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
- Conclusion
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.
VPS Hosting Course
Learn everything you need to know about servers and hosting your own applications!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:
export CR_PAT=<PAT>
- Sign in to the container registry:
echo $CR_PAT | docker login registry.gitlab.com -u <username> --password-stdin
- Build and upload the container image:
export IMAGE=registry.gitlab.com/
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.
Need help or want to share feedback? Join my discord community!
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:
services:
frontend:
container_name: frontend
image: registry.gitlab.com/<username>/<project-name>:latest
ports:
- 80:80
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.
If this guide is helpful to you and you like what I do, please support me with a coffee!
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 serverSSH_HOST
: IP of your serverWORK_DIR
: path to the directory containing thedocker-compose.yml
filePAT
: 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.
stages:
- publish
- deploy
variables:
REGISTRY: registry.gitlab.com
IMAGE_NAME: $GITLAB_USER_LOGIN/$CI_PROJECT_NAME
publish:
image: docker
stage: publish
services:
- docker:dind
before_script:
- echo $PAT | docker login $REGISTRY -u $GITLAB_USER_LOGIN --password-stdin
script:
- docker build . --tag $REGISTRY/$IMAGE_NAME
- docker push $REGISTRY/$IMAGE_NAME
deploy:
image: ubuntu:latest
stage: deploy
only:
- main
before_script:
- 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
script:
- ssh $SSH_USER@$SSH_HOST "cd $WORK_DIR && docker compose pull && docker compose up -d && exit"
after_script:
- rm -rf ~/.ssh
This job basically logs into the server, pulls the new version of the image, and then rebuilds the containers.
Conclusion
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.
[convertkit form=2303042]