GitLab CI: Deploy Docker Image to a Server
Brie 21 Jun, 2019






Automating your software deployment process can save time and reduce errors. With GitLab CI/CD, you can build, test, and deploy Docker images to a remote server using a well-defined pipeline. In this guide, we’ll outline the essential steps and best practices for deploying Docker images from GitLab to your server, ensuring a smooth and consistent release workflow.

1. Prerequisites
Before configuring GitLab CI/CD to deploy Docker images, confirm that you have the following ready:
- GitLab Repository: A repository hosted on GitLab with CI/CD enabled.
- Dockerfile: A valid Dockerfile describing how to build your application’s Docker image.
- Runner with Docker Installed: A GitLab Runner capable of building and pushing Docker images.
- Target Server Access: SSH credentials or another secure method to deploy images to your server.
2. Setting Up the .gitlab-ci.yml File
Your CI/CD pipeline is governed by a .gitlab-ci.yml
file at the root of
your repository. Here’s a basic example:
stages:
- build
- deploy
variables:
DOCKER_IMAGE: "registry.gitlab.com/<group>/<project>/myapp"
build_docker_image:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker login -u "${CI_REGISTRY_USER}" -p "${CI_REGISTRY_PASSWORD}" ${CI_REGISTRY}
- docker build -t "${DOCKER_IMAGE}:${CI_COMMIT_SHA}" .
- docker push "${DOCKER_IMAGE}:${CI_COMMIT_SHA}"
deploy_to_server:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache sshpass
script:
- sshpass -p "${SSH_PASSWORD}" ssh -o StrictHostKeyChecking=no "${SSH_USER}@${SERVER_IP}" "docker pull ${DOCKER_IMAGE}:${CI_COMMIT_SHA} && docker run -d --name myapp --rm -p 80:80 ${DOCKER_IMAGE}:${CI_COMMIT_SHA}"
only:
- main
Key points to note:
- stages: Separate the build and deploy phases for clarity.
- docker:dind service: Allows the build job to run Docker-in-Docker (dind).
- docker login command: Authenticates to the GitLab Container Registry.
- sshpass: This is used for non-interactive SSH deployments; consider more secure alternatives like SSH keys for production.
- only: main: Ensures deployment occurs only from the
main
branch. Adjust this to match your workflow.
3. Building and Tagging Your Docker Image
In the example above, the build job:
- Logs into the GitLab Registry: Ensures your runner can push images to the private registry.
- Builds the Docker image: Utilizes your
Dockerfile
to create an image tagged with${CI_COMMIT_SHA}
. - Pushes the image: Stores the newly built image in the GitLab Container Registry, making it available for the deployment stage.
4. Deploying to the Target Server
Once the build is successful, the deploy_to_server
job initiates:
- SSH to Your Server: Uses
sshpass
and credentials stored in GitLab’s CI/CD Variables. - Pulls the Latest Image: Fetches the Docker image tagged with
${CI_COMMIT_SHA}
. - Runs the Container: Spins up a container on the specified port, effectively deploying your application.
If you prefer a zero-downtime approach, consider using Docker Compose or a reverse proxy configuration.
5. Managing CI/CD Variables
To securely store sensitive information (e.g., SSH password, SERVER_IP
), use
GitLab CI/CD Variables:
- Navigate to Settings > CI/CD > Variables in your GitLab project.
- Add new variables like
SSH_USER
,SSH_PASSWORD
, andSERVER_IP
. - Check “Protect” or “Masked” options if desired, ensuring they remain hidden in build logs.
6. Improving Security and Workflow
While the above example demonstrates a straightforward approach, there are ways to enhance your pipeline:
- SSH Keys Instead of Passwords: For better security, configure a key-based authentication system on your runner and target server.
- Use Docker Swarm or Kubernetes: Employ container orchestration for higher scalability and zero-downtime deployments.
- Staging Environments: Test your image in a staging environment before promoting it to production.
- Automated Tests: Incorporate unit, integration, or end-to-end tests in your CI pipeline for reliability.
7. Conclusion
Using GitLab CI/CD to deploy Docker images enables a more automated, consistent release
process. By designing a clear pipeline in your .gitlab-ci.yml
file, you can
seamlessly build images, upload them to the GitLab Container Registry, and spin up containers
on your target server. As you refine your workflow, consider adding security measures,
better orchestration tools, and thorough testing stages to make your deployments both
robust and efficient.