Last active
March 30, 2024 05:21
-
-
Save florentchauveau/2dc4da0299d42258606fc3b0e148fc07 to your computer and use it in GitHub Desktop.
GitLab CI yaml file for building docker images
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a GitLab CI configuration to build the project as a docker image | |
# The file is generic enough to be dropped in a project containing a working Dockerfile | |
# Author: Florent CHAUVEAU <[email protected]> | |
# Mentioned here: https://blog.callr.tech/building-docker-images-with-gitlab-ci-best-practices/ | |
# do not use "latest" here, if you want this to work in the future | |
image: docker:20 | |
stages: | |
- build | |
- push | |
variables: | |
# fill those if you have a proxy in your environment | |
http_proxy: "" | |
https_proxy: "" | |
no_proxy: "" | |
# Use this if your GitLab runner does not use socket binding | |
# services: | |
# - docker:dind | |
before_script: | |
# docker login asks for the password to be passed through stdin for security | |
# we use $CI_REGISTRY_PASSWORD here which is a special variable provided by GitLab | |
# https://docs.gitlab.com/ce/ci/variables/predefined_variables.html | |
- echo -n $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY | |
Build: | |
stage: build | |
script: | |
# fetches the latest image (not failing if image is not found) | |
- docker pull $CI_REGISTRY_IMAGE:latest || true | |
# builds the project, passing proxy variables, using OCI labels | |
# notice the cache-from, which is going to use the image we just pulled locally | |
# the built image is tagged locally with the commit SHA, and then pushed to | |
# the GitLab registry | |
- > | |
docker build | |
--pull | |
--build-arg http_proxy=$http_proxy | |
--build-arg https_proxy=$https_proxy | |
--build-arg no_proxy=$no_proxy | |
--cache-from $CI_REGISTRY_IMAGE:latest | |
--label "org.opencontainers.image.title=$CI_PROJECT_TITLE" | |
--label "org.opencontainers.image.url=$CI_PROJECT_URL" | |
--label "org.opencontainers.image.created=$CI_JOB_STARTED_AT" | |
--label "org.opencontainers.image.revision=$CI_COMMIT_SHA" | |
--label "org.opencontainers.image.version=$CI_COMMIT_REF_NAME" | |
--tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA | |
. | |
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA | |
# Here, the goal is to tag the "master" branch as "latest" | |
Push latest: | |
variables: | |
# We are just playing with Docker here. | |
# We do not need GitLab to clone the source code. | |
GIT_STRATEGY: none | |
stage: push | |
only: | |
# Only "master" should be tagged "latest" | |
- master | |
script: | |
# Because we have no guarantee that this job will be picked up by the same runner | |
# that built the image in the previous step, we pull it again locally | |
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA | |
# Then we tag it "latest" | |
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:latest | |
# Annnd we push it. | |
- docker push $CI_REGISTRY_IMAGE:latest | |
# Finally, the goal here is to Docker tag any Git tag | |
# GitLab will start a new pipeline everytime a Git tag is created, which is pretty awesome | |
Push tag: | |
variables: | |
# Again, we do not need the source code here. Just playing with Docker. | |
GIT_STRATEGY: none | |
stage: push | |
only: | |
# We want this job to be run on tags only. | |
- tags | |
script: | |
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA | |
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME | |
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME |
Thanks. Sorry, I should have commented again. I made it work on my side as well.
Thanks for your reply
I am wondering whether the Push latest
job should also run on tags, i.e. have
only:
# Only "main" should be tagged "latest"
- main
- tags
Otherwise the last tagged image (on main/master) has a different manifest digest (at least) than the "latest" image.
I guess that adding tags
to only
on the Push latest
job bears the risk that you may end up with a "latest" image that is not from main/master, if one git-tags a commit from another branch.
Why are we building the same image again when adding a new tag?
We already have built pushed image, we also have the line with getting this image docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This happens when one of the variable is not defined. I have updated the gist, try with
$CI_REGISTRY_USER
and$CI_REGISTRY_PASSWORD
.