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.27orlouislam/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 type | Pulled from |
|---|---|
nginx:1.27 | Docker Hub (docker.io/library/nginx) |
myorg/web:2.0 | Docker Hub |
ghcr.io/acme/api:1.4.2 | GitHub Container Registry |
registry.example.com:5000/team/app:3.1 | Your 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:packagesscope; 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=infoYou 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):
- Under Container registry ("Pull private images from a registry during deploys"), press Add.
- Registry host: the host as it appears in your image reference, such as
ghcr.io,registry.example.com:5000, ordocker.iofor Docker Hub.https://and trailing slashes are removed, and every Docker Hub spelling is stored asdocker.io. - 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
versionortag_name, or deploy a fixed version only.
- GitHub Releases: follow the latest published release of a GitHub repository (
- 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.2Redeploy 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/amd64orlinux/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.
Related
Deploy a folder or archive
Put an app online straight from a folder on your computer or a .zip or tar archive (.tar, .tar.gz, .tar.bz2, .tar.xz, .tar.zst), with no Git repository. The browser upload, the archive upload, and the one-command CLI way, with size limits and what gets skipped.
Paste a Dockerfile or Compose file
Deploy without a repository by writing a Dockerfile or pasting a docker-compose.yml in the panel. Covers what the build can see, ports, environment variables and .env files, and what to do after the first deploy.