Deploying a new build to production

Updated Jun 29, 2026 · 1 min read

How a merged change becomes a live deployment — from the CI image build to rolling the running Swarm service onto the new image.

CI builds and pushes the image

When a change is merged, the CI pipeline automatically builds a fresh Docker image and pushes it to the GitHub Container Registry as:

ghcr.io/lewis159/youtube-transcriber:latest

No manual build step is required — by the time the merge completes, the new "latest" image is available in the registry.

Roll the running service onto the new image

To make the running service pick up the new image, run the following on the Swarm manager (or trigger it via Portainer):

docker service update --image ghcr.io/lewis159/youtube-transcriber:latest --force yt-transcriber_app

The --force flag ensures Swarm re-pulls and re-deploys even though the image tag ("latest") has not changed. Swarm then performs a rolling update of the service tasks.

Why there is no downtime

The app runs as two replicas (app-ha-1 and app-ha-2) behind the nginx load balancer. During the rolling update, Swarm replaces one replica at a time: the first replica is updated and must come back healthy before the second is touched. At every moment at least one replica is serving traffic via nginx, so users experience no downtime.

Verify the deployment

After the rollout completes, hard-refresh your browser (Ctrl+Shift+R / Cmd+Shift+R) to bypass any cached assets and pull the new bundle. Then confirm the deploy succeeded by checking the changelog or version indicator in the app — it should show the version you just shipped. If anything looks wrong, roll back by updating the service to the previous image tag.

Was this helpful?