The meta pictures
Home

GitLab CI: Deploy Docker Image to a Server

Brie 21 Jun, 2019
facebook facebook facebook facebook facebook facebook facebook

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.

GitLab CI: Deploy Docker Image to a Server

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, and SERVER_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.