Back to Blog
Lesson 45 of the CI/CD: Continuous Integration from Scratch course
DevOpsAugust 20, 20264 min read

Pulling Images in Production: Automating Your Deployment Server

Learn how to configure your deployment server to pull images from a registry, ensuring your production environment always runs the latest container version.

DevOpsDockerCI/CDDeploymentContainers
Close-up of blue ethernet cables hanging in a data center, highlighting technology connections.

Previously in this course, we covered Container Registry Integration: Pushing Images in CI/CD, where we automated the delivery of our artifacts to a central repository. Now that your images are safely stored in the cloud, this lesson focuses on the "pull" side of the equation: configuring your production server to fetch those images and update your running services.

The Deployment Lifecycle

When you push a new image to a registry, your production server doesn't magically know about it. Most production setups rely on a "pull-based" model where the server periodically checks for, or is triggered to download, the latest version of your application.

To achieve this, your deployment server needs three things:

  1. Authentication: Credentials to log into your private registry.
  2. The Pull Command: A instruction to download the specific image tag.
  3. The Service Update: A way to signal the container runtime (like Docker) to replace the old container with the new one.

Configuring the Deployment Server

Assuming you have a remote server running Docker, you shouldn't rely on manual docker pull commands. Instead, we use an automated script or a configuration management tool.

If you are using a standard Linux VPS, your deployment script (which we started building in Production Deployment: Automating Secure CD Pipelines) should look something like this:

Bash
#!/bin/bash
# deploy.sh - executed on the production server
set -e

# 1. Login to the registry (using environment variables)
echo $REGISTRY_PASSWORD | docker login $REGISTRY_URL -u $REGISTRY_USER --password-stdin

# 2. Pull the latest image
docker pull $REGISTRY_URL/$IMAGE_NAME:latest

# 3. Stop and remove the old container
docker stop my-app || true
docker rm my-app || true

# 4. Run the new container
docker run -d --name my-app -p 80:80 $REGISTRY_URL/$IMAGE_NAME:latest

Why "Latest" is a Trap

While the script above uses :latest, in a professional production environment, you should always tag your images with a unique identifier, such as the Git commit SHA. Using :latest can lead to unpredictable behavior where your server pulls a different version than the one you tested, or worse, fails to update because the tag name hasn't changed.

Better Practice: Modify your CI pipeline to push with the commit SHA (e.g., myapp:a1b2c3d) and pass that specific tag to your deployment script. This makes your deployments deterministic and significantly easier to roll back if something goes wrong.

Hands-on Exercise: Update Your Deployment Script

  1. SSH into your staging or production server.
  2. Create a deploy.sh script using the template above, but replace :latest with a specific version tag.
  3. Run the script manually to ensure your server can authenticate with your registry and pull the image successfully.
  4. If you have completed Manual Approval Gates: Controlling Production Deployments, add this execution step to your workflow as a final "Deploy" job.

Common Pitfalls

  • Stale Credentials: Docker login sessions expire. Ensure your CI/CD runner or your server has a mechanism to refresh the config.json file or re-authenticate before every pull.
  • Downtime during Pull: The docker stop followed by docker run pattern introduces a few seconds of downtime. For zero-downtime requirements, you would typically use a load balancer or a container orchestrator like Docker Swarm or Kubernetes.
  • Disk Bloat: Running docker pull repeatedly without cleaning up old images will eventually fill your server's disk. Add docker image prune -f to your maintenance routine.

FAQ

Q: Do I need to log in every time I pull? A: If the registry is private, yes, your server needs a valid session. If you are using a public registry, you don't need authentication, but you risk exposing your source code.

Q: Can I pull images without stopping the container? A: Docker needs to replace the running process to update the application. You can pull the image while the container is running, but you must recreate the container to apply the changes.

Recap

We have moved from manually building code to fully automated deployments. By configuring your server to pull from a registry, you close the loop of the software delivery lifecycle. Always prefer specific version tags over :latest, and ensure your server handles authentication securely.

Up next: We will tackle the complexities of persistent data by learning about Database Migrations in CI.

Similar Posts