Publishing Google Cloud Container Registry Images from Gitlab CI

Grant Forrest
3 min readMay 22, 2018

--

Since I had some trouble getting this to work, I thought I’d write up a post about it to see if I can help anyone else.

At the present time (May 21, 2018), this is the best I’ve come up with to publish Docker images from a Gitlab CI runner to a private Google Cloud Container Registry.

Create a Service Account

IAM Configuration in the Google Cloud Console

Open IAM. In the sidebar, you’ll see Service Accounts. Create one, with the “Editor” permission set for your project (you may want to be more fine-grained with permissions, but I’m not confident in recommending anything more granular). Be sure to check “Furnish a new key”. You can name it something like “Gitlab CI”.

A service account with Editor role and a new key

Save the key locally when prompted after creation. Be very careful with this key, as it is a literal key to your cloud account (and anyone who gets it can, at minimum, mine some cryptocurrency which you’ll have to pay for… if not worse).

Use a Docker image in Gitlab Runner with Docker-in-Docker

Since you want to use Docker to build your images on the runner, you’ll need to run a Docker image on that runner which has Docker installed. Here’s the first few lines of our .gitlab-ci.yml file:

image: docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay

That sets us up with an environment in which we can run the docker command and build our image. The overlay bit is just a performance improvement, as far as I can gather.

Add the JSON Service Key Secret

Next, we add a Gitlab secret environment variable with the contents of our Service Account’s authentication key which we downloaded previously.

In your Gitlab repo, hover the settings icon in the sidebar and select CI/CD. Expand the ‘Secret variables’ section and add the contents of your key to a variable which you may name yourself (I called mine GCLOUD_SERVICE_KEY):

Gitlab secrets

Now this variable is available in our Gitlab CI environment.

Install GCloud SDK and Log In

In your Gitlab CI config file, add a before_script section which updates and installs some dependencies, then logs into your private registry. Note that I am using the https://us.gcr.io domain for my registry. Don’t log into the wrong registry; the login will succeed, but you will get an authorization error when pushing.

(Also note that I’m not sure every step here is necessary, I copied most of this from a great gist here)

before_script:
# Install CA certs, openssl to https downloads, python for gcloud sdk
- apk add --update make ca-certificates openssl python
- update-ca-certificates
# Write our GCP service account private key into a file
- echo $GCLOUD_SERVICE_KEY > ${HOME}/gcloud-service-key.json
# Download and install Google Cloud SDK
- wget https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz
- tar zxvf google-cloud-sdk.tar.gz && ./google-cloud-sdk/install.sh --usage-reporting=false --path-update=true
- google-cloud-sdk/bin/gcloud --quiet components update
- google-cloud-sdk/bin/gcloud auth activate-service-account --key-file ${HOME}/gcloud-service-key.json
- docker login -u _json_key --password-stdin https://us.gcr.io < ${HOME}/gcloud-service-key.json

Great, if that succeeded, you should now have access to the Google Cloud Registry. Just to round things out, here’s the rest of my .gitlab-ci.yml file where I build and push my image:

stages:
- publish
publish:
stage: publish
script:
- docker build -t $IMAGE_NAME .
- docker tag $IMAGE_NAME "us.gcr.io/$GCLOUD_PROJECT_ID/$IMAGE_NAME"
- docker push "us.gcr.io/$GCLOUD_PROJECT_ID/$IMAGE_NAME:latest"
only:
- master

… which just builds the image, tags it as Google Cloud expects, then pushes it off. Again, be sure you’re pushing to the correct registry domain and that you’ve defined any variables shown here or substituted hardcoded values as you see fit.

--

--

Grant Forrest

Writes frontend code, short fiction, theological musings.