How To Deploy A Docker Image To A Server Using GitLab CI CD
Do you want to learn how to deploy your docker image to your server automatically and, in the same run, update your container? In this guide, we will do exactly that! We will store the image inside GitLab’s Container Registry and then create a Pipeline using GitLab CI CD to deploy it onto the server whenever we push a change!
- Store docker image in GitLab’s Container Registry
- Running the container on your server
- Automate the deployment of your application using GitLab CI CD
You do need a Docker image for this guide. If you do not have an image yet, check out my last post on creating one here.
Store docker image in GitLab’s Container Registry
We will use the GitLab Container Registry to store our Docker image, which allows us to access it from anywhere, especially our server. To store an image in the GLCR, we first need to create a GitLab Personal Access Token (PAT). For more details on the scopes you need and other information, you can check out the GitLab documentation here. If you want to get started quickly, you can use this link, which includes all the required scopes: https://gitlab.com/-/profile/
After you click the link, you need to specify the duration and save the PAT value somewhere secure. We will need it in the next steps.
Now, open your terminal and follow these steps from the directory containing the Dockerfile:
- Store your PAT inside an environment variable:
- Sign in to the container registry:
echo $CR_PAT | docker login registry.gitlab.com -u <username> --password-stdin
- Build and upload the container image:
programonaut/ docker-image-gitlab:latest && docker build . -t $IMAGE && docker push $IMAGE
By following these steps, your Docker image will be built and uploaded to the GLCR, and you will be able to access it from your server using the specified image tag. You need to run steps 1 and 2 on your server as well.
Running the container on your server
The next step is to create a
docker-compose.yml file on our server (inside of
/home/<username>/<project>), which is a template for our Docker container. This way, we can easily move it to another machine or rebuild the containers. Inside the file, we specify the name of the service, the image, and the ports to use:
After creating the
docker-compose.yml file, we can build the container by running
docker compose up -d. This command will start the container in detached mode, meaning it runs in the background. To check if your container can be built. If everything works correctly, you can access it under
http://<server-ip>. To learn how to connect it with a domain, check this post here.
Automate the deployment of our application using GitLab CI CD
Automating the deployment of our application significantly reduces manual work and speeds up the deployment process. Before creating the variables and the GitLab Pipeline, we need to set up a new SSH key. To do so, log in to your server as the user you want to run the pipeline as and follow these steps:
- Check that user has access to the directory containing the repository and is able to run Docker
- Create an SSH key:
ssh-keygen -t rsa -b 4096
- Copy the content of the key file in base64 encoded (this is needed to store it in the GitLab variables in the next step):
cat <path/to/private/key> | base64 -w0
- Add the public key to the authorized_keys file:
cat <path/to/public/key> >> ~/.ssh/authorized_keys
After creating the SSH key, we need to create the following variables in the repository by going to Settings > Secrets and Variables > Actions:
SSH_PRIVATE_KEY: the content of the private key file [MASK]
SSH_USER: user to access the server
SSH_HOST: IP of your server
WORK_DIR: path to the directory containing the
PAT: the personal access token to log in to the registry [MASK]
Once the secrets are set up, we can create the following action inside the file
.gitlab-ci.yml. The action first builds the image and pushes it to the registry inside the publish job. It then pulls it onto the server and updates the container in the deploy job.
- echo $PAT | docker login $REGISTRY -u $GITLAB_USER_LOGIN --password-stdin
- docker build . --tag $REGISTRY/$IMAGE_NAME
- docker push $REGISTRY/$IMAGE_NAME
- apt-get -yq update
- apt-get -yqq install ssh
- install -m 600 -D /dev/null ~/.ssh/id_rsa
- echo "$SSH_PRIVATE_KEY" | base64 -d > ~/.ssh/id_rsa
- ssh-keyscan -H $SSH_HOST > ~/.ssh/known_hosts
- ssh $SSH_USER@$SSH_HOST "cd $WORK_DIR && docker compose pull && docker compose up -d && exit"
- rm -rf ~/.ssh
This job basically logs into the server, pulls the new version of the image, and then rebuilds the containers.
In this guide, you learned how to create a GitLab CI CD to deploy a docker image to your server automatically! The pipeline first builds the Docker image, pushes it to GitLab’s Container Registry, pulls the new version onto the server, and updates the container!
If you have any questions feel free to comment, join my discord, or email me.