github.com/ssube/gitlab-ci-multi-runner@v1.2.1-0.20160607142738-b8d1285632e6/docs/executors/docker.md (about) 1 # The Docker executor 2 3 GitLab Runner can use Docker to run builds on user provided images. This is 4 possible with the use of **Docker** executor. 5 6 The **Docker** executor when used with GitLab CI, connects to [Docker Engine] 7 and runs each build in a separate and isolated container using the predefined 8 image that is [set up in `.gitlab-ci.yml`][yaml] and in accordance in 9 [`config.toml`][toml]. 10 11 That way you can have a simple and reproducible build environment that can also 12 run on your workstation. The added benefit is that you can test all the 13 commands that we will explore later from your shell, rather than having to test 14 them on a dedicated CI server. 15 16 --- 17 18 <!-- START doctoc generated TOC please keep comment here to allow auto update --> 19 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> 20 **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 21 22 - [Workflow](#workflow) 23 - [The `image` keyword](#the-image-keyword) 24 - [The `services` keyword](#the-services-keyword) 25 - [How is service linked to the build](#how-is-service-linked-to-the-build) 26 - [Define image and services from `.gitlab-ci.yml`](#define-image-and-services-from-gitlab-ci-yml) 27 - [Define image and services in `config.toml`](#define-image-and-services-in-config-toml) 28 - [Define an image from a private Docker registry](#define-an-image-from-a-private-docker-registry) 29 - [Accessing the services](#accessing-the-services) 30 - [Configuring services](#configuring-services) 31 - [PostgreSQL service example](#postgresql-service-example) 32 - [MySQL service example](#mysql-service-example) 33 - [The services health check](#the-services-health-check) 34 - [The builds and cache storage](#the-builds-and-cache-storage) 35 - [The persistent storage](#the-persistent-storage) 36 - [The privileged mode](#the-privileged-mode) 37 - [Use docker-in-docker with privileged mode](#use-docker-in-docker-with-privileged-mode) 38 - [The ENTRYPOINT](#the-entrypoint) 39 - [Docker vs Docker-SSH](#docker-vs-docker-ssh) 40 41 <!-- END doctoc generated TOC please keep comment here to allow auto update --> 42 43 ## Workflow 44 45 The Docker executor divides the build into multiple steps: 46 47 1. **Prepare**: Create and start the services. 48 1. **Pre-build**: Clone, restore cache and download artifacts from previous 49 stages. This is run on a special Docker Image. 50 1. **Build**: User build. This is run on the user-provided docker image. 51 1. **Post-build**: Create cache, upload artifacts to GitLab. This is run on 52 a special Docker Image. 53 54 The special Docker Image is based on [Alpine Linux] and contains all the tools 55 required to run the prepare step the build: the Git binary and the Runner 56 binary for supporting caching and artifacts. You can find the definition of 57 this special image [in the official Runner repository][special-build]. 58 59 ## The `image` keyword 60 61 The `image` keyword is the name of the Docker image that is present in the 62 local Docker Engine (list all images with `docker images`) or any image that 63 can be found at [Docker Hub][hub]. For more information about images and Docker 64 Hub please read the [Docker Fundamentals][] documentation. 65 66 In short, with `image` we refer to the docker image, which will be used to 67 create a container on which your build will run. 68 69 If you don't specify the namespace, Docker implies `library` which includes all 70 [official images](https://hub.docker.com/u/library/). That's why you'll see 71 many times the `library` part omitted in `.gitlab-ci.myl` and `config.toml`. 72 For example you can define an image like `image: ruby:2.1`, which is a shortcut 73 for `image: library/ruby:2.1`. 74 75 Then, for each Docker image there are tags, denoting the version of the image. 76 These are defined with a colon (`:`) after the image name. For example, for 77 Ruby you can see the supported tags at <https://hub.docker.com/_/ruby/>. If you 78 don't specify a tag (like `image: ruby`), `latest` is implied. 79 80 ## The `services` keyword 81 82 The `services` keyword defines just another Docker image that is run during 83 your build and is linked to the Docker image that the `image` keyword defines. 84 This allows you to access the service image during build time. 85 86 The service image can run any application, but the most common use case is to 87 run a database container, eg. `mysql`. It's easier and faster to use an 88 existing image and run it as an additional container than install `mysql` every 89 time the project is built. 90 91 You can see some widely used services examples in the relevant documentation of 92 [CI services examples](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/ci/services/README.md). 93 94 ### How is service linked to the build 95 96 To better understand how the container linking works, read 97 [Linking containers together](https://docs.docker.com/userguide/dockerlinks/). 98 99 To summarize, if you add `mysql` as service to your application, this image 100 will then be used to create a container that is linked to the build container. 101 According to the [workflow](#workflow) this is the first step that is performed 102 before running the actual builds. 103 104 The service container for MySQL will be accessible under the hostname `mysql`. 105 So, in order to access your database service you have to connect to the host 106 named `mysql` instead of a socket or `localhost`. 107 108 ## Define image and services from `.gitlab-ci.yml` 109 110 You can simply define an image that will be used for all jobs and a list of 111 services that you want to use during build time. 112 113 ```yaml 114 image: ruby:2.2 115 116 services: 117 - postgres:9.3 118 119 before_script: 120 - bundle install 121 122 test: 123 script: 124 - bundle exec rake spec 125 ``` 126 127 It is also possible to define different images and services per job: 128 129 ```yaml 130 before_script: 131 - bundle install 132 133 test:2.1: 134 image: ruby:2.1 135 services: 136 - postgres:9.3 137 script: 138 - bundle exec rake spec 139 140 test:2.2: 141 image: ruby:2.2 142 services: 143 - postgres:9.4 144 script: 145 - bundle exec rake spec 146 ``` 147 148 ## Define image and services in `config.toml` 149 150 Look for the `[runners.docker]` section: 151 152 ``` 153 [runners.docker] 154 image = "ruby:2.1" 155 services = ["mysql:latest", "postgres:latest"] 156 ``` 157 158 The image and services defined this way will be added to all builds run by 159 that Runner, so even if you don't define an `image` inside `.gitlab-ci.yml`, 160 the one defined in `config.toml` will be used. 161 162 ## Define an image from a private Docker registry 163 164 Starting with GitLab Runner 0.6.0, you are able to define images located to 165 private registries that could also require authentication. 166 167 All you have to do is be explicit on the image definition in `.gitlab-ci.yml`. 168 169 ```yaml 170 image: my.registry.tld:5000/namepace/image:tag 171 ``` 172 173 In the example above, GitLab Runner will look at `my.registry.tld:5000` for the 174 image `namespace/image:tag`. 175 176 If the repository is private you need to authenticate your GitLab Runner in the 177 registry. Read more on [using a private Docker registry][runner-priv-reg]. 178 179 ## Accessing the services 180 181 Let's say that you need a Wordpress instance to test some API integration with 182 your application. 183 184 You can then use for example the [tutum/wordpress][] as a service image in your 185 `.gitlab-ci.yml`: 186 187 ```yaml 188 services: 189 - tutum/wordpress:latest 190 ``` 191 192 When the build is run, `tutum/wordpress` will be started first and you will have 193 access to it from your build container under the hostname `tutum__wordpress` 194 or `tutum-wordpress`. 195 196 The GitLab Runner creates two alias hostnames for the service that you can use 197 alternatively. The aliases are taken from the image name following these rules: 198 199 1. Everything after `:` is stripped 200 2. For the first alias, the slash (`/`) is replaced with double underscores (`__`) 201 2. For the second alias, the slash (`/`) is replaced with a single dash (`-`) 202 203 ## Configuring services 204 205 Many services accept environment variables which allow you to easily change 206 database names or set account names depending on the environment. 207 208 GitLab Runner 0.5.0 and up passes all YAML-defined variables to the created 209 service containers. 210 211 For all possible configuration variables check the documentation of each image 212 provided in their corresponding Docker hub page. 213 214 > **Note**: 215 > 216 All variables will be passed to all services containers. It's not designed to 217 distinguish which variable should go where. 218 > 219 Secure variables are only passed to the build container. 220 221 ### PostgreSQL service example 222 223 See the specific documentation for 224 [using PostgreSQL as a service](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/ci/services/postgres.md). 225 226 ### MySQL service example 227 228 See the specific documentation for 229 [using MySQL as a service](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/ci/services/mysql.md). 230 231 ### The services health check 232 233 After the service is started, GitLab Runner waits some time for the service to 234 be responsive. Currently, the Docker executor tries to open a TCP connection to 235 the first exposed service in the service container. 236 237 You can see how it is implemented [in this Dockerfile][service-file]. 238 239 ## The builds and cache storage 240 241 The Docker executor by default stores all builds in 242 `/builds/<namespace>/<project-name>` and all caches in `/cache` (inside the 243 container). 244 245 You can overwrite the `/builds` and `/cache` directories by defining the 246 `builds_dir` and `cache_dir` options under the `[[runners]]` section in 247 `config.toml`. This will modify where the data are stored inside the container. 248 249 If you modify the `/cache` storage path, you also need to make sure to mark this 250 directory as persistent by defining it in `volumes = ["/my/cache/"]` under the 251 `[runners.docker]` section in `config.toml`. 252 253 Read the next section of persistent storage for more information. 254 255 ## The persistent storage 256 257 The Docker executor can provide a persistent storage when running the containers. 258 All directories defined under `volumes =` will be persistent between builds. 259 260 The `volumes` directive supports 2 types of storage: 261 262 1. `<path>` - **the dynamic storage**. The `<path>` is persistent between subsequent 263 runs of the same concurrent job for that project. The data is attached to a 264 custom cache container: `runner-<short-token>-project-<id>-concurrent-<job-id>-cache-<unique-id>`. 265 2. `<host-path>:<path>[:<mode>]` - **the host-bound storage**. The `<path>` is 266 bind to `<host-path>` on the host system. The optional `<mode>` can specify 267 that this storage is read-only or read-write (default). 268 269 ## The privileged mode 270 271 The Docker executor supports a number of options that allows to fine tune the 272 build container. One of these options is the [`privileged` mode][privileged]. 273 274 ### Use docker-in-docker with privileged mode 275 276 The configured `privileged` flag is passed to the build container and all 277 services, thus allowing to easily use the docker-in-docker approach. 278 279 First, configure your Runner (config.toml) to run in `privileged` mode: 280 281 ```toml 282 [[runners]] 283 executor = "docker" 284 [runners.docker] 285 privileged = true 286 ``` 287 288 Then, make your build script (`.gitlab-ci.yml`) to use Docker-in-Docker 289 container: 290 291 ```bash 292 image: docker:git 293 services: 294 - docker:dind 295 296 build: 297 script: 298 - docker build -t my-image . 299 - docker push my-image 300 ``` 301 302 ## The ENTRYPOINT 303 304 The Docker executor doesn't overwrite the [`ENTRYPOINT` of a Docker image][entry]. 305 306 That means that if your image defines the `ENTRYPOINT` and doesn't allow to run 307 scripts with `CMD`, the image will not work with the Docker executor. 308 309 With the use of `ENTRYPOINT` it is possible to create special Docker image that 310 would run the build script in a custom environment, or in secure mode. 311 312 You may think of creating a Docker image that uses an `ENTRYPOINT` that doesn't 313 execute the build script, but does execute a predefined set of commands, for 314 example to build the docker image from your directory. In that case, you can 315 run the build container in [privileged mode](#the-privileged-mode), and make 316 the build environment of the Runner secure. 317 318 Consider the following example: 319 320 1. Create a new Dockerfile: 321 322 ```bash 323 FROM docker:dind 324 ADD / /entrypoint.sh 325 ENTRYPOINT ["/bin/sh", "/entrypoint.sh"] 326 ``` 327 328 2. Create a bash script (`entrypoint.sh`) that will be used as the `ENTRYPOINT`: 329 330 ```bash 331 #!/bin/sh 332 333 dind docker daemon 334 --host=unix:///var/run/docker.sock \ 335 --host=tcp://0.0.0.0:2375 \ 336 --storage-driver=vf & 337 338 docker build -t "$BUILD_IMAGE" . 339 docker push "$BUILD_IMAGE" 340 ``` 341 342 3. Push the image to the Docker registry. 343 344 4. Run Docker executor in `privileged` mode. In `config.toml` define: 345 346 ```toml 347 [[runners]] 348 executor = "docker" 349 [runners.docker] 350 privileged = true 351 ``` 352 353 5. In your project use the following `.gitlab-ci.yml`: 354 355 ```yaml 356 variables: 357 BUILD_IMAGE: my.image 358 build: 359 image: my/docker-build:image 360 script: 361 - Dummy Script 362 ``` 363 364 This is just one of the examples. With this approach the possibilities are 365 limitless. 366 367 ## Docker vs Docker-SSH 368 369 >**Note**: 370 The docker-ssh executor is deprecated and no new features will be added to it 371 372 We provide a support for a special type of Docker executor, namely Docker-SSH. 373 Docker-SSH uses the same logic as the Docker executor, but instead of executing 374 the script directly, it uses an SSH client to connect to the build container. 375 376 Docker-ssh then connects to the SSH server that is running inside the container 377 using its internal IP. 378 379 [Docker Fundamentals]: https://docs.docker.com/engine/understanding-docker/ 380 [docker engine]: https://www.docker.com/products/docker-engine 381 [hub]: https://hub.docker.com/ 382 [linking-containers]: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/ 383 [tutum/wordpress]: https://registry.hub.docker.com/u/tutum/wordpress/ 384 [postgres-hub]: https://registry.hub.docker.com/u/library/postgres/ 385 [mysql-hub]: https://registry.hub.docker.com/u/library/mysql/ 386 [runner-priv-reg]: ../configuration/advanced-configuration.md#using-a-private-docker-registry 387 [yaml]: http://doc.gitlab.com/ce/ci/yaml/README.html 388 [toml]: ../commands/README.md#configuration-file 389 [alpine linux]: https://alpinelinux.org/ 390 [special-build]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/tree/master/dockerfiles/build 391 [service-file]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/tree/master/dockerfiles/service 392 [privileged]: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities 393 [entry]: https://docs.docker.com/engine/reference/run/#entrypoint-default-command-to-execute-at-runtime