Gitlab CI: Docker Build and Push
Hello. How are you? Long time no see... Yes, there's a lot of dust at this blog, and I will try to remove a little bit with this blog post. BTW Happy New Year!
For a long time I use Gitlab as the main git repository. And I was lucky enough to work in companies that uses Gitlab for their projects too. Mostly because of the CI/CD that Gitlab provides for us to use.
So since I know a bit or two about DevOps, I have became quite an expert on building the .gitlab-ci.yml
.
Most of projects these days end up as a Docker Image. When using Gitlab you can use Docker in Docker or Kaniko to build and push your image. I have done both of them, and I will share with you the how to.
Docker in Docker(Dind)
Using the Dind method is quite straight forward, you use the concept of service
of Gitlab to give you the hability to run the docker
command. After the build, I need to push the image, and with these examples I am going to push to the Elastic Container Registry of AWS.
Example of the Dind job.
With the snippet above, I have a hidden job that installs aws-cli to get the credentials to push to ECR, I build and tag the image and finally push it to ECR. Why am I using a hidden job? Because it allows me to reuse that code when defining the jobs that will execute that script. The code is "customized" using the environment vars defined in the job that implement this hidden job. More on Dind check the docs.
Kaniko
I've came uppon Kaniko after searching to use an docker image of aws-cli to authenticate to the ECR and avoid the pip install awscli
.
Kaniko is a tool that builds a docker image without the need of the docker daemon. And from Gitlab docs solves some secutiry issues of the Dind method:
kaniko solves two problems with using the Docker-in-Docker build method:
Docker-in-Docker requires privileged mode to function, which is a significant security concern.
Docker-in-Docker generally incurs a performance penalty and can be quite slow.
The same apply for the idea of the hidden job and environment vars. More on Kaniko, check the docs.
And now what?
Let's try it!
For a pet project I have built the docker image using Dind and using Kaniko. Here's the Dockerfile:
The image generated by the Dind method has a size of 440MB. And using Kaniko method has a size of 152MB. I'm not fully aware of what makes the difference so big, but I bet that is something to do with not using the docker daemon on Kaniko.
For both jobs I need to have the AWS Credentials available so the job can push the image to ECR. The ECR docs shows you the available methods for the authentication. With the Dind I have used the awscli to get the token, and Kaniko uses the amazon-ecr-credential-helper by default. That made my life a lot easier.
I was not able to use Kaniko locally in my pc, because it requires to have a repository to push defined on the command line. I could setup a local registry, to try it, but I was too lazy for it.
Examples
To use the shown templates and understand how to build jobs with them, check my Gitlab Repository. Feel free to reach me out if you have any questions at https://t.me/lays147.