Jack Moore

Email: jack(at)jmoore53.com
Project Updates

Configure Gitlab CI/CD

03 Sep 2019 » gitlab, devops, production

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

GitLab’s Predefined Variables

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.

Pushing and Pulling from Docker

© Jack Moore