Docker
Prerequisites
Run environment
|
CI/CD scenarios for Docker
Automated Docker builds: All image dependencies already exist and all you need is to build and publish a Docker image to Space Packages.
Creating dependencies before the build: An Automation job must create image dependencies before building and publishing the image.
Publishing an image to an external repository, for example, Docker Hub.
Ways to run Docker builds
Automation provides two different ways for building and publishing Docker images depending on a run environment:
- job.host.dockerBuildPush
job.host.dockerBuildPush
lets you run Docker builds on a self-hosted or Space Cloud worker. Technically, this is a DSL wrapper for thejob.host.shellScript
block that runs thedocker build
anddocker push
commands.Pros over
job.kaniko
:It's possible to build Windows Docker images (if the host machine runs on Windows).
It's easier and faster to build image dependencies – As you can pre-install all necessary tools to the host machine, the same
host
step can be used not only to build and publish an image but also to build artifacts required for this image.In case of
job.kaniko
, you must build image artifacts in a separate step and provide them tojob.kaniko
via the file share.Some things might work differently with Kaniko compared to classic Docker.
- job.kaniko
job.kaniko
lets you run Docker builds in a container with the pre-installed Kaniko tool. Technically, this is ajob.container
step that runs in a container based on a special image. The main reason of usingjob.kaniko
overhost.dockerBuildPush
is when using of the latter is not possible. For example, if your company uses Space On-Premises and doesn't allow using self-hosted workers.
Build and publish a Docker image to Space Packages
The job below first builds and then publishes an image defined in ./docker/config/Dockerfile
. Note that Automation jobs don't require authentication in a Space Packages registry, given that the registry belongs to the same project.
Create an image dependency, build, and publish a Docker image to Space Packages
The job below implies that a Gradle build generates artifacts in the ./build
directory. The job then builds a Docker image that includes the artifacts, for example, the artifacts can be added using the ADD
directive in Dockerfile
(not shown). The Dockerfile
is located in the project root.
In case of job.kaniko
the job must contain two steps: The first step (job.container
) builds artifacts and puts them to the file share, the second step (job.kaniko
) takes the files from the file share and builds the image.
Publish a Docker image to a remote registry (Docker Hub)
The example below shows publishing an image to Docker Hub. However, the instructions would be identical for any external registry requiring authentication.
To publish to a registry that requires authentication, your script must first log in to this repository. You can do this either by running docker login
in the script itself or create a connection to the registry and use it in the dockerRegistryConnections
block (recommended).
In Docker Hub, create an access token with the Write permission. Save the created token to a safe location.
Create a connection to Docker Hub:
Open the desired project.
On the project sidebar menu, choose Settings, then Docker Registry Connections.
Click New connection and specify connection settings:
Key: a unique connection name that you will use to reference this connection in jobs, e.g.,
docker_hub
orsome_registry
Docker registry server: a URL of the remote Docker registry. For Docker Hub, it's
index.docker.io
Username and Password: the username and the password (token) created previously.
Edit the project's
.space.kts
:job("Publish to Docker Hub") { host("Build artifacts and a Docker image") { // Before running the scripts, the host machine will log in to // the registries specified in connections. dockerRegistryConnections { // specify connection key +"docker_hub" // multiple connections are supported // +"one_more_connection" } dockerBuildPush { labels["vendor"] = "mycompany" tags { +"myrepo/hello-from-space:1.0.${"$"}JB_SPACE_EXECUTION_NUMBER" } } } }
Note that as a job.kaniko
runs in a container that is isolated from the host machine, it's not possible to use dockerRegistryConnections
for logging in to Docker Hub. Instead, you must provide Docker Hub credentials in the config.json
file.
In Docker Hub, create an access token with the Write permission. Save the created token to a safe location.
In Space, create two secrets:
dockerhub_user
: your Docker Hub username.dockerhub_token
: the Docker Hub token you've created in step 1.
Edit the project's
.space.kts
:job("Publish to Docker Hub") { kaniko("Docker build and push") { // assign project secrets to environment variables env["HUB_USER"] = Secrets("dockerhub_user") env["HUB_TOKEN"] = Secrets("dockerhub_token") // put auth data to Docker config beforeBuildScript { content = """ B64_AUTH=${'$'}(echo -n ${'$'}HUB_USER:${'$'}HUB_TOKEN | base64 -w 0) echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"${'$'}B64_AUTH\"}}}" > ${'$'}DOCKER_CONFIG/config.json """ } build { labels["vendor"] = "mycompany" } //in push, specify repo_name/image_name push("myrepo/hello-from-space") { tags{ +"1.0.\$JB_SPACE_EXECUTION_NUMBER" } } } }