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