For the Love of God please put some CI/CD into your project.
A gentle intro to GitLab’s CI/CD
Building Docker images with GitLab CI/CD
Using Other Resources
Automatically build and push Docker images using GitLab CI
DigitalOcean guide to building images with GitLab
gitlab-ci.yml File
Checkout this gitlab-ci.yml
file based off this blog post from callr:
image: docker:stable
services:
- docker:dind
stages:
- build
- push
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $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, and vcs vars for LABEL
# 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 VCS_REF=$CI_COMMIT_SHA
--build-arg VCS_URL=$CI_PROJECT_URL
--cache-from $CI_REGISTRY_IMAGE:latest
--tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
-f docker.production.Dockerfile
.
- 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
This example pipeline is pretty self explanitory with the correct knowledge of GitLab’s CI/CD yaml notation and a basic understanding of pipelines.
This pipeline will only run push an image out to dockerhub on a push to master and on any tags. The master branch push to Dockerhub works and correctly tags the image, but I have yet to test the tagging push to Dockerhub.
This pipeline is similiar to the AWS pipelinse except that the AWS pipelines were more bash driven and involved more hooks from AWS. Both are relatively easy to create once the basics are known.
Gitlab’s Environment Variables
These have been a little wonky for me to say the least. I have struggled to understand them from the beginning. This is a problem, because now I am going to straight up abstract them… Set these and force gitlab to push to it’s own registry:
CI_REGISTRY=https://index.docker.io/v1/
CI_REGISTRY_IMAGE=registry.gitlab.com/compositionalenterprises/homstatic
CI_REGISTRY_PASSWORD=P4$$WORD_H3RE
CI_REGISTRY_USER=jmoore53
Setting these variables fixes the problems I am currently having and pushes the image up to Gitlab’s docker registry. I have decided I will pull the image down using a bash script and then push up only tagged images to docker’s registry. You may call it a few extra steps, but take a look at the commit log and then ask if you think its worth it to keep hacking on.
I will give it a few months, gain a few more xp points and then return to the problem. For now here is 1.0.0
Dockerhub Setup
Getting gitlab configured with dockerhub is relatively simple, but you need to push the initial image up to dockerhub first. If the image is not pushed up then the cicd pipeline is going to throw an error due to not being able to pull an image.
Although this makes the process not fully automated from the start, taking one step for a repo initialization is part of the initialization process. There’s no sense in automating this piece. I’d rather spend my time on more critical pieces of the project.