summaryrefslogtreecommitdiff
path: root/doc/ci/docker/using_docker_build.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ci/docker/using_docker_build.md')
-rw-r--r--doc/ci/docker/using_docker_build.md358
1 files changed, 280 insertions, 78 deletions
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index ebbfde09c67..8e5ce2fb359 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -1,7 +1,7 @@
---
stage: Verify
group: Continuous Integration
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: concepts, howto
---
@@ -37,7 +37,7 @@ during jobs, each with their own tradeoffs.
An alternative to using `docker build` is to [use kaniko](using_kaniko.md).
This avoids having to execute a runner in privileged mode.
-TIP: **Tip:**
+NOTE:
To see how Docker and GitLab Runner are configured for shared runners on
GitLab.com, see [GitLab.com shared
runners](../../user/gitlab_com/index.md#shared-runners).
@@ -103,7 +103,7 @@ image in privileged mode.
CI builds, follow the `docker-compose`
[installation instructions](https://docs.docker.com/compose/install/).
-DANGER: **Warning:**
+WARNING:
By enabling `--docker-privileged`, you are effectively disabling all of
the security mechanisms of containers and exposing your host to privilege
escalation which can lead to container breakout. For more information, check
@@ -152,9 +152,9 @@ Docker-in-Docker service and
[GitLab.com shared runners](../../user/gitlab_com/index.md#shared-runners)
support this.
-GitLab Runner 11.11 or later is required, but it is not supported if GitLab
-Runner is installed using the [Helm chart](https://docs.gitlab.com/runner/install/kubernetes.html).
-See the [related issue](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/83) for details.
+##### Docker
+
+> Introduced in GitLab Runner 11.11.
1. Install [GitLab Runner](https://docs.gitlab.com/runner/install/).
1. Register GitLab Runner from the command line to use `docker` and `privileged`
@@ -217,6 +217,62 @@ See the [related issue](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/iss
# The 'docker' hostname is the alias of the service container as described at
# https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services.
#
+ # Specify to Docker where to create the certificates, Docker will
+ # create them automatically on boot, and will create
+ # `/certs/client` that will be shared between the service and job
+ # container, thanks to volume mount from config.toml
+ DOCKER_TLS_CERTDIR: "/certs"
+
+ services:
+ - docker:19.03.12-dind
+
+ before_script:
+ - docker info
+
+ build:
+ stage: build
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+ ```
+
+##### Kubernetes
+
+> [Introduced](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/106) in GitLab Runner Helm Chart 0.23.0.
+
+1. Using the
+ [Helm chart](https://docs.gitlab.com/runner/install/kubernetes.html), update the
+ [`values.yml` file](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/blob/00c1a2098f303dffb910714752e9a981e119f5b5/values.yaml#L133-137)
+ to specify a volume mount.
+
+ ```yaml
+ runners:
+ config: |
+ [[runners]]
+ [runners.kubernetes]
+ image = "ubuntu:20.04"
+ privileged = true
+ [[runners.kubernetes.volumes.empty_dir]]
+ name = "docker-certs"
+ mount_path = "/certs/client"
+ medium = "Memory"
+ ```
+
+1. You can now use `docker` in the build script (note the inclusion of the
+ `docker:19.03.13-dind` service):
+
+ ```yaml
+ image: docker:19.03.13
+
+ variables:
+ # When using dind service, we need to instruct docker to talk with
+ # the daemon started inside of the service. The daemon is available
+ # with a network connection instead of the default
+ # /var/run/docker.sock socket.
+ DOCKER_HOST: tcp://docker:2376
+ #
+ # The 'docker' hostname is the alias of the service container as described at
+ # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services.
# If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
# the variable must be set to tcp://localhost:2376 because of how the
# Kubernetes executor connects services to the job container
@@ -227,9 +283,14 @@ See the [related issue](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/iss
# `/certs/client` that will be shared between the service and job
# container, thanks to volume mount from config.toml
DOCKER_TLS_CERTDIR: "/certs"
+ # These are usually specified by the entrypoint, however the
+ # Kubernetes executor doesn't run entrypoints
+ # https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4125
+ DOCKER_TLS_VERIFY: 1
+ DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
services:
- - docker:19.03.12-dind
+ - docker:19.03.13-dind
before_script:
- docker info
@@ -302,6 +363,90 @@ build:
- docker run my-docker-image /script/to/run/tests
```
+#### Use Docker socket binding
+
+The third approach is to bind-mount `/var/run/docker.sock` into the
+container so that Docker is available in the context of that image.
+
+NOTE:
+If you bind the Docker socket and you are
+[using GitLab Runner 11.11 or later](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/1261),
+you can no longer use `docker:19.03.12-dind` as a service. Volume bindings
+are done to the services as well, making these incompatible.
+
+To make Docker available in the context of the image:
+
+1. Install [GitLab Runner](https://docs.gitlab.com/runner/install/).
+1. From the command line, register a runner with the `docker` executor and share `/var/run/docker.sock`:
+
+ ```shell
+ sudo gitlab-runner register -n \
+ --url https://gitlab.com/ \
+ --registration-token REGISTRATION_TOKEN \
+ --executor docker \
+ --description "My Docker Runner" \
+ --docker-image "docker:19.03.12" \
+ --docker-volumes /var/run/docker.sock:/var/run/docker.sock
+ ```
+
+ This command registers a new runner to use the special
+ `docker:19.03.12` image, which is provided by Docker. **The command uses
+ the Docker daemon of the runner itself. Any containers spawned by Docker
+ commands are siblings of the runner rather than children of the runner.**
+ This may have complications and limitations that are unsuitable for your workflow.
+
+ Your `config.toml` file should not have an entry like this:
+
+ ```toml
+ [[runners]]
+ url = "https://gitlab.com/"
+ token = REGISTRATION_TOKEN
+ executor = "docker"
+ [runners.docker]
+ tls_verify = false
+ image = "docker:19.03.12"
+ privileged = false
+ disable_cache = false
+ volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
+ [runners.cache]
+ Insecure = false
+ ```
+
+1. Use `docker` in the build script. You don't need to
+ include the `docker:19.03.12-dind` service, like you do when you're using
+ the Docker-in-Docker executor:
+
+ ```yaml
+ image: docker:19.03.12
+
+ before_script:
+ - docker info
+
+ build:
+ stage: build
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+ ```
+
+This method avoids using Docker in privileged mode. However,
+the implications of this method are:
+
+- By sharing the Docker daemon, you are effectively disabling all
+ the security mechanisms of containers and exposing your host to privilege
+ escalation, which can lead to container breakout. For example, if a project
+ ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner
+ containers.
+- Concurrent jobs may not work; if your tests
+ create containers with specific names, they may conflict with each other.
+- Sharing files and directories from the source repository into containers may not
+ work as expected. Volume mounting is done in the context of the host
+ machine, not the build container. For example:
+
+ ```shell
+ docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
+ ```
+
#### Enable registry mirror for `docker:dind` service
When the Docker daemon starts inside of the service container, it uses
@@ -381,7 +526,7 @@ content:
Update the `config.toml` file to mount the file to
`/etc/docker/daemon.json`. This would mount the file for **every**
-container that is created by GitLab Runner. The configuration will be
+container that is created by GitLab Runner. The configuration is
picked up by the `dind` service.
```toml
@@ -422,7 +567,7 @@ of this file. You can do this with a command like:
kubectl create configmap docker-daemon --namespace gitlab-runner --from-file /tmp/daemon.json
```
-NOTE: **Note:**
+NOTE:
Make sure to use the namespace that GitLab Runner Kubernetes executor uses
to create job pods in.
@@ -444,89 +589,146 @@ The configuration is picked up by the `dind` service.
sub_path = "daemon.json"
```
-#### Use Docker socket binding
+## Authenticating with registry in Docker-in-Docker
-The third approach is to bind-mount `/var/run/docker.sock` into the
-container so that Docker is available in the context of that image.
+When you use Docker-in-Docker, the [normal authentication
+methods](using_docker_images.html#define-an-image-from-a-private-container-registry)
+won't work because a fresh Docker daemon is started with the service.
-NOTE: **Note:**
-If you bind the Docker socket [when using GitLab Runner 11.11 or
-newer](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/1261),
-you can no longer use `docker:19.03.12-dind` as a service because volume bindings
-are done to the services as well, making these incompatible.
+### Option 1: Run `docker login`
-In order to do that, follow the steps:
+In [`before_script`](../yaml/README.md#before_script) run `docker
+login`:
-1. Install [GitLab Runner](https://docs.gitlab.com/runner/install/).
-1. Register GitLab Runner from the command line to use `docker` and share `/var/run/docker.sock`:
+```yaml
+image: docker:19.03.13
- ```shell
- sudo gitlab-runner register -n \
- --url https://gitlab.com/ \
- --registration-token REGISTRATION_TOKEN \
- --executor docker \
- --description "My Docker Runner" \
- --docker-image "docker:19.03.12" \
- --docker-volumes /var/run/docker.sock:/var/run/docker.sock
- ```
+variables:
+ DOCKER_TLS_CERTDIR: "/certs"
- The above command registers a new runner to use the special
- `docker:19.03.12` image which is provided by Docker. **Notice that it's using
- the Docker daemon of the runner itself, and any containers spawned by Docker
- commands are siblings of the runner rather than children of the runner.**
- This may have complications and limitations that are unsuitable for your workflow.
+services:
+ - docker:19.03.13-dind
- The above command creates a `config.toml` entry similar to this:
+build:
+ stage: build
+ before_script:
+ - echo "$DOCKER_REGISTRY_PASS" | docker login $DOCKER_REGISTRY --username $DOCKER_REGISTRY_USER --password-stdin
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+```
- ```toml
- [[runners]]
- url = "https://gitlab.com/"
- token = REGISTRATION_TOKEN
- executor = "docker"
- [runners.docker]
- tls_verify = false
- image = "docker:19.03.12"
- privileged = false
- disable_cache = false
- volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
- [runners.cache]
- Insecure = false
- ```
+To log in to Docker Hub, leave `$DOCKER_REGISTRY`
+empty or remove it.
-1. You can now use `docker` in the build script (note that you don't need to
- include the `docker:19.03.12-dind` service as when using the Docker in Docker
- executor):
+### Option 2: Mount `~/.docker/config.json` on each job
- ```yaml
- image: docker:19.03.12
+If you are an administrator for GitLab Runner, you can mount a file
+with the authentication configuration to `~/.docker/config.json`.
+Then every job that the runner picks up will be authenticated already. If you
+are using the official `docker:19.03.13` image, the home directory is
+under `/root`.
- before_script:
- - docker info
+If you mount the configuration file, any `docker` command
+that modifies the `~/.docker/config.json` (for example, `docker login`)
+fails, because the file is mounted as read-only. Do not change it from
+read-only, because other problems will occur.
- build:
- stage: build
- script:
- - docker build -t my-docker-image .
- - docker run my-docker-image /script/to/run/tests
- ```
+Here is an example of `/opt/.docker/config.json` that follows the
+[`DOCKER_AUTH_CONFIG`](using_docker_images.md#determining-your-docker_auth_config-data)
+documentation:
-While the above method avoids using Docker in privileged mode, you should be
-aware of the following implications:
+```json
+{
+ "auths": {
+ "https://index.docker.io/v1/": {
+ "auth": "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ="
+ }
+ }
+}
+```
-- By sharing the Docker daemon, you are effectively disabling all
- the security mechanisms of containers and exposing your host to privilege
- escalation which can lead to container breakout. For example, if a project
- ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner
- containers.
-- Concurrent jobs may not work; if your tests
- create containers with specific names, they may conflict with each other.
-- Sharing files and directories from the source repository into containers may not
- work as expected since volume mounting is done in the context of the host
- machine, not the build container. For example:
+#### Docker
- ```shell
- docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
- ```
+Update the [volume
+mounts](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#volumes-in-the-runnersdocker-section)
+to include the file.
+
+```toml
+[[runners]]
+ ...
+ executor = "docker"
+ [runners.docker]
+ ...
+ privileged = true
+ volumes = ["/opt/.docker/config.json:/root/.docker/config.json:ro"]
+```
+
+#### Kubernetes
+
+Create a [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) with the content
+of this file. You can do this with a command like:
+
+```shell
+kubectl create configmap docker-client-config --namespace gitlab-runner --from-file /opt/.docker/config.json
+```
+
+Update the [volume
+mounts](https://docs.gitlab.com/runner/executors/kubernetes.html#using-volumes)
+to include the file.
+
+```toml
+[[runners]]
+ ...
+ executor = "kubernetes"
+ [runners.kubernetes]
+ image = "alpine:3.12"
+ privileged = true
+ [[runners.kubernetes.volumes.config_map]]
+ name = "docker-client-config"
+ mount_path = "/root/.docker/config.json"
+ # If you are running GitLab Runner 13.5
+ # or lower you can remove this
+ sub_path = "config.json"
+```
+
+### Option 3: Use `DOCKER_AUTH_CONFIG`
+
+If you already have
+[`DOCKER_AUTH_CONFIG`](using_docker_images.md#determining-your-docker_auth_config-data)
+defined, you can use the variable and save it in
+`~/.docker/config.json`.
+
+There are multiple ways to define this. For example:
+
+- Inside
+ [`pre_build_script`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section)
+ inside of the runner configuration file.
+- Inside [`before_script`](../yaml/README.md#before_script).
+- Inside of [`script`](../yaml/README.md#script).
+
+Below is an example of
+[`before_script`](../yaml/README.md#before_script). The same commands
+apply for any solution you implement.
+
+```yaml
+image: docker:19.03.13
+
+variables:
+ DOCKER_TLS_CERTDIR: "/certs"
+
+services:
+ - docker:19.03.13-dind
+
+build:
+ stage: build
+ before_script:
+ - mkdir -p $HOME/.docker
+ - echo $DOCKER_AUTH_CONFIG > $HOME/.docker/config.json
+ script:
+ - docker build -t my-docker-image .
+ - docker run my-docker-image /script/to/run/tests
+```
## Making Docker-in-Docker builds faster with Docker layer caching
@@ -586,7 +788,7 @@ The steps in the `script` section for the `build` stage can be summed up to:
## Use the OverlayFS driver
-NOTE: **Note:**
+NOTE:
The shared runners on GitLab.com use the `overlay2` driver by default.
By default, when using `docker:dind`, Docker uses the `vfs` storage driver which