Guides

Deploy a Docker image

Run a prebuilt container image from Docker Hub, GitHub Container Registry or any private registry. Nothing is cloned or built. Covers registry credentials, ports, environment variables and tracking new versions.

When your app is already published as a container image (by your CI, or by the project that makes it), Synq can run that image directly. There is no repository to clone and no build step: Synq pulls the image on your server, starts it, and routes traffic to it like any other project.

Use this for:

  • an image your CI pushes to a registry, such as ghcr.io/acme/api:1.4.2;
  • an off-the-shelf image, such as nginx:1.27 or louislam/uptime-kuma:1;
  • anything in a private registry, with a registry login Synq stores for you.

A whole stack of images?

For several containers that work together (an app plus its database), paste a Compose file instead: see Paste a Dockerfile or Compose file. For a ready-made stack, look at the one-click apps first.

Deploy an image

Open the Docker image tab

Click New Project in the sidebar, then the Docker image tab. The card is titled Deploy a Docker image ("Run a prebuilt image from Docker Hub or any registry. Nothing is cloned or built."). You can also open /library#image directly.

Enter the image

Type the image reference into Image:

You typePulled from
nginx:1.27Docker Hub (docker.io/library/nginx)
myorg/web:2.0Docker Hub
ghcr.io/acme/api:1.4.2GitHub Container Registry
registry.example.com:5000/team/app:3.1Your own registry on port 5000

The tag is optional and defaults to latest. A digest (image@sha256:...) is not accepted here: use a tag. Project name fills in from the image name; change it if you like. Project names must be unique: an existing project with the same name is not overwritten.

Set the container port

Container port is the port the app listens on inside the container (default 80). Check the image's documentation: nginx listens on 80, many Node images on 3000, many Go and Java images on 8080. Synq routes your domain to this port.

Pick the server

Server chooses which of your servers runs the image. It starts on the first server in the list.

Add a registry login (private images only)

Turn on Private registry and fill in:

  • Username: your registry user (for GitHub Container Registry, your GitHub username).
  • Password or access token: prefer a read-only token over an account password. For GitHub Container Registry, a token with the read:packages scope; for Docker Hub, a personal access token with read access.

Synq saves this as an organization registry credential for that registry host ("Saved as a registry credential for ghcr.io and used for every pull from it"). If a credential for that host already exists, the form says "Using the saved credential for ghcr.io" and asks for nothing.

Saving a new registry login needs organization admin rights; for other members the whole form fails with "Could not create the project". If you are not an admin, ask one to add the login under Settings → Credentials first; the form then uses it.

Add environment variables (optional)

Environment variables takes one KEY=value per line, as in a .env file:

DATABASE_URL=postgres://app:secret@db.internal:5432/app
LOG_LEVEL=info

You can change them later on the project's Environment tab.

Press Create and deploy

Synq creates the project, saves the variables and starts the first deploy. You land on the build screen, which shows the pull and start. When it is live, add a domain on the project's Domains & Routes tab (see Custom domains).

If the project was created but the first deploy could not start, you see "The project was created, but the first deploy could not start" and land on the project, where you can fix the problem and press Deploy.

Registry credentials

Registry logins are shared by the whole organization and used for every pull from that registry host: image projects, Compose services and one-click apps alike. Manage them in Settings → Credentials (organization admins only):

  1. Under Container registry ("Pull private images from a registry during deploys"), press Add.
  2. Registry host: the host as it appears in your image reference, such as ghcr.io, registry.example.com:5000, or docker.io for Docker Hub. https:// and trailing slashes are removed, and every Docker Hub spelling is stored as docker.io.
  3. Username and Password or access token, then save. Synq checks the credential with the registry before saving it. A saved login that later stops working is marked Needs attention; after fixing it, use Re-check with the provider.

Credentials are stored encrypted and never shown again. To rotate one, edit it and type the new secret; to stop using it, delete it (anything pulling from that registry privately stops working).

Track new versions

An image project remembers which version it runs. Open the project, then Source & Triggers → Source. The Tracked container image card shows the Image template, the Version source, the Current version, and the Latest version (or Target version when a version is pinned), with Update available when you are behind.

The Release tracking form below it decides where new versions come from:

  • Image template: the image with a placeholder for the version, such as ghcr.io/acme/api:{tag}. {tag} keeps the publisher's exact tag (v2.4.1); {version} uses the normalized version (2.4.1).
  • Version provider:
    • GitHub Releases: follow the latest published release of a GitHub repository (owner/repository).
    • Version URL or pin: read an HTTPS Version URL that returns the version as text, or JSON with version or tag_name, or deploy a fixed version only.
  • Pinned version: a fixed version to deploy, such as v2.4.1. It overrides the discovered latest version; leave it blank to track updates.

Press Save source. Changes apply to every environment of the project. A project created from the Docker image tab starts as a pinned version (the tag you typed).

When a newer version is found, the project's Deployments tab shows New version available with a Deploy new version button.

The same settings from the terminal:

# Follow GitHub Releases of acme/api, deploying ghcr.io/acme/api:<release tag>
synq project release-image <project-id> --image-template "ghcr.io/acme/api:{tag}" --github-repo acme/api

# Or deploy one fixed version
synq project release-image <project-id> --image-template "ghcr.io/acme/api:{tag}" --pin v1.4.2

Redeploy when CI pushes a new image

If your CI pushes a new image to the same tag (for example :main or :latest), create a deploy hook and call it at the end of the pipeline. A deploy started by a deploy hook pulls registry images again instead of reusing the copy already on the server, so it picks up the new push. For anything you may need to roll back, prefer versioned tags: rollback can then restore the exact image a release ran.

Switch between an image and a repository

  • An image project's Source card has Link Git repository to switch it to a Git source. Nothing changes until you actually link a repository.
  • A Git project that could run a published image instead offers Use prebuilt image on its Source card. Saving replaces the Git source for every environment; existing deployments and rollback history stay available.

Limits

  • One image per project. For several containers, use a Compose file.
  • The image must run on your server's CPU architecture (for example linux/amd64 or linux/arm64).
  • Image projects have no build, so the Builder setting does not apply to them.
  • The container's own start command (CMD/ENTRYPOINT) starts the app.

On this page