Recently I started to use Docker for my side projects. In the deployment process there are two tasks: One is to build the docker image and push it to my private container registry, another is to pull the docker image from the registry and create a container from it.

For private registry I am using Google Cloud Container Registry (GCR). I also have my own jenkins service, so I want to do these two tasks from jenkins automatically. After some investigation I finally made everything work. Here is how.

Environment

Here is a list of software and OS I am using:

Ubuntu 18.04

Jenkins ver. 2.121.3

Docker 17.12.1-ce, installed with apt install docker.io

Basics

To access GCR from jenkins, we need to install the following plugins.

docker-build-step: This plugin allows to add various Docker commands as a build step. Latest version 2.0.

Google OAuth Credentials: Provide Google credentials. Latest version 0.6.

Google Container Registry Auth: This plugin retrieves Google credentials from Google OAuth Credentials plugin, and provides authentication for docker-build-step plugin. Latest version 0.3.

The workflow is a little bit cumbersome but still understandable:

Create a service account which has full access to GCR in Google Cloud. In jenkins, create a credential for this service account with Google OAuth Credentials plugin. Create a pull/push build step with docker-build-step plugin, and set the registry url to GCR. Google Container Registry Auth plugin will provide the credential created in Step 2 to docker when the build step is executed.

Please keep reading for the details.

Step 1: Create a service account

I will assume you have already created the Container Registry in Google Cloud. If you haven’t done so, don’t worry, just login to your Google Cloud Console and choose “Container Registry” from the side bar and follow the instructions. You’ll finish the setup in minutes. Let’s assume the registry URL is https://gcr.io/myregistry , in which myregistry is the project name in Google Cloud.

We need to create a service account so that jenkins can access GCR. Open “IAM & admin” from the sidebar then “Service account”. Click “+ CREATE SERVICE ACCOUNT” button and enter your account name.

Here “Service account name” is a descriptive name for human reading so it can be anything. We don’t need to add any roles. Don’t forget to check “Furnish a new private key” and choose “JSON” format.

Before clicking Save, please take a note of the “Service account ID” generated, which is in this case, my-jenkins-gcr-account@myregistry.iam.gserviceaccount.com . We need this later.

Click Save button, a JSON file containing the private key will be downloaded. Keep this file in a safe place, we need this file in the next step.

Switch to “Storage” from sidebar. You should be able to see a bucket for the GCR, probably named artifacts.myregistry.appspot.com . Open this bucket and switch to “Permissions” tab.

Click “Add members”. Enter the service account ID we just created, and choose “Storage Admin” in “Roles”. Click Add.

Setup Jenkins Credentials

Go back to your jenkins service, and make sure login with an admin account. Choose “Credentials” from the sidebar, then choose “Global credentials” (you can choose other domains as well), and click “Add Credentials”.

Select “Google Service Account from private key” for the “Kind” field, and enter your project name ( myregistry in this example). Then upload the JSON private key we just downloaded in previous step.

Setup Docker

If your docker already works with Jenkins, you can skip this step. Also note that since I have only one jenkins server which acts as both master and slave, I decided to install Docker manually from command line. If you want to configure Docker for jenkins cluster, “Manage Jenkins” → “Global Tool Configuration” → “Docker installations” may help.

I installed docker from the jenkins server command line:

$ sudo apt install docker.io

By default, Docker only exposes API on unix socket which Jenkins cannot access. We need to expose a TCP port for jenkins. Type the following command:

$ sudo systemctl edit docker

And type the following content to override Docker configuration:

[Service]

ExecStart=

ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375

Restart docker so that docker exposes API on 127.0.0.1:2375 :

$ sudo systemctl restart docker.service

Then go back to jenkins, choose “Manage Jenkins” → “Configure System”. In “Docker Builder” section, fill the “Docker URL” with tcp://127.0.0.1:2375 and click “Test Connection” to make sure it works.

Setup Jenkins Job to Push Image

Now it is time to create the jenkins job. Create a freestyle jenkins job and fill other settings with your needs (such as git repository, parameters, etc.). In the build steps, you can add Docker commands to build and push / pull docker images.

For push / pull command, Fill the parameters like this:

Name of the image to push/pull: image name, e.g. myapp

Tag: image tag, jenkins variables can be used, e.g. build-$BUILD_NUMBER

Registry: the registry name on GCR without https , e.g. gcr.io/myregistry

, e.g. Docker registry URL: GCR url, use https://gcr.io

Registry credentials: Choose the credentials we created in “Setup Jenkins Credentials” section

Here is an example with a build step and a push step:

That’s all of it! Now you can try to build this jenkins job and it will automatically push the image to GCR.