BigW Consortium Gitlab

using_docker_images.md 9.11 KB
Newer Older
1 2
# Using Docker Images

3
GitLab CI in conjunction with [GitLab Runner](../runners/README.md) can use
4
[Docker Engine](https://www.docker.com/) to test and build any application.
5

6 7
Docker is an open-source project that allows you to use predefined images to
run applications in independent "containers" that are run within a single Linux
8
instance. [Docker Hub][hub] has a rich database of pre-built images that can be
9
used to test and build your applications.
10

11
Docker, when used with GitLab CI, runs each build in a separate and isolated
12 13
container using the predefined image that is set up in
[`.gitlab-ci.yml`](../yaml/README.md).
14 15 16 17

This makes it easier to have a simple and reproducible build environment that
can also run on your workstation. The added benefit is that you can test all
the commands that we will explore later from your shell, rather than having to
18
test them on a dedicated CI server.
19

20
## Register docker runner
21 22 23

To use GitLab Runner with docker you need to register a new runner to use the
`docker` executor:
24 25

```bash
26
gitlab-ci-multi-runner register \
27
  --url "https://gitlab.com/" \
28 29 30 31 32 33 34 35
  --registration-token "PROJECT_REGISTRATION_TOKEN" \
  --description "docker-ruby-2.1" \
  --executor "docker" \
  --docker-image ruby:2.1 \
  --docker-postgres latest \
  --docker-mysql latest
```

36 37 38 39
The registered runner will use the `ruby:2.1` docker image and will run two
services, `postgres:latest` and `mysql:latest`, both of which will be
accessible during the build process.

40
## What is image
41 42 43 44 45 46 47 48 49

The `image` keyword is the name of the docker image that is present in the
local Docker Engine (list all images with `docker images`) or any image that
can be found at [Docker Hub][hub]. For more information about images and Docker
Hub please read the [Docker Fundamentals][] documentation.

In short, with `image` we refer to the docker image, which will be used to
create a container on which your build will run.

50
## What is service
51

52
The `services` keyword defines just another docker image that is run during
53 54
your build and is linked to the docker image that the `image` keyword defines.
This allows you to access the service image during build time.
55

56 57 58 59
The service image can run any application, but the most common use case is to
run a database container, eg. `mysql`. It's easier and faster to use an
existing image and run it as an additional container than install `mysql` every
time the project is built.
60

61 62
You can see some widely used services examples in the relevant documentation of
[CI services examples](../services/README.md).
63

64 65 66
### How is service linked to the build

To better understand how the container linking works, read
67
[Linking containers together][linking-containers].
68 69 70 71 72 73 74 75

To summarize, if you add `mysql` as service to your application, the image will
then be used to create a container that is linked to the build container.

The service container for MySQL will be accessible under the hostname `mysql`.
So, in order to access your database service you have to connect to the host
named `mysql` instead of a socket or `localhost`.

76
## Overwrite image and services
77

78
See [How to use other images as services](#how-to-use-other-images-as-services).
79

80
## How to use other images as services
81 82 83 84

You are not limited to have only database services. You can add as many
services you need to `.gitlab-ci.yml` or manually modify `config.toml`.
Any image found at [Docker Hub][hub] can be used as a service.
85

86
## Define image and services from `.gitlab-ci.yml`
87 88 89 90 91

You can simply define an image that will be used for all jobs and a list of
services that you want to use during build time.

```yaml
92
image: ruby:2.2
93

94 95
services:
  - postgres:9.3
96

97
before_script:
98
  - bundle install
99

100 101 102 103 104
test:
  script:
  - bundle exec rake spec
```

105 106 107 108
It is also possible to define different images and services per job:

```yaml
before_script:
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
  - bundle install

test:2.1:
  image: ruby:2.1
  services:
  - postgres:9.3
  script:
  - bundle exec rake spec

test:2.2:
  image: ruby:2.2
  services:
  - postgres:9.4
  script:
  - bundle exec rake spec
```

126
## Define image and services in `config.toml`
127 128 129

Look for the `[runners.docker]` section:

130 131 132 133 134 135
```
[runners.docker]
  image = "ruby:2.1"
  services = ["mysql:latest", "postgres:latest"]
```

136 137
The image and services defined this way will be added to all builds run by
that runner.
138

139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
## Define an image from a private Docker registry

Starting with GitLab Runner 0.6.0, you are able to define images located to
private registries that could also require authentication.

All you have to do is be explicit on the image definition in `.gitlab-ci.yml`.

```yaml
image: my.registry.tld:5000/namepace/image:tag
```

In the example above, GitLab Runner will look at `my.registry.tld:5000` for the
image `namespace/image:tag`.

If the repository is private you need to authenticate your GitLab Runner in the
registry. Learn how to do that on
[GitLab Runner's documentation][runner-priv-reg].

157
## Accessing the services
158

159 160 161 162 163 164 165
Let's say that you need a Wordpress instance to test some API integration with
your application.

You can then use for example the [tutum/wordpress][] image in your
`.gitlab-ci.yml`:

```yaml
166 167
services:
- tutum/wordpress:latest
168 169
```

170
When the build is run, `tutum/wordpress` will be started and you will have
171
access to it from your build container under the hostname `tutum__wordpress`.
172 173 174

The alias hostname for the service is made from the image name following these
rules:
175

176
1. Everything after `:` is stripped
177
2. Slash (`/`) is replaced with double underscores (`__`)
178

179
## Configuring services
180

181 182
Many services accept environment variables which allow you to easily change
database names or set account names depending on the environment.
183

184 185
GitLab Runner 0.5.0 and up passes all YAML-defined variables to the created
service containers.
186

187 188
For all possible configuration variables check the documentation of each image
provided in their corresponding Docker hub page.
189

190 191
*Note: All variables will be passed to all services containers. It's not
designed to distinguish which variable should go where.*
192

193
### PostgreSQL service example
194

195 196
See the specific documentation for
[using PostgreSQL as a service](../services/postgres.md).
197

198
### MySQL service example
199

200 201
See the specific documentation for
[using MySQL as a service](../services/mysql.md).
202

203
## How Docker integration works
204 205 206 207

Below is a high level overview of the steps performed by docker during build
time.

208
1. Create any service container: `mysql`, `postgresql`, `mongodb`, `redis`.
209 210
1. Create cache container to store all volumes as defined in `config.toml` and
   `Dockerfile` of build image (`ruby:2.1` as in above example).
211 212 213 214 215 216 217 218
1. Create build container and link any service container to build container.
1. Start build container and send build script to the container.
1. Run build script.
1. Checkout code in: `/builds/group-name/project-name/`.
1. Run any step defined in `.gitlab-ci.yml`.
1. Check exit status of build script.
1. Remove build container and all created service containers.

219
## How to debug a build locally
220 221 222 223 224 225

*Note: The following commands are run without root privileges. You should be
able to run docker with your regular user account.*

First start with creating a file named `build script`:

226
```bash
227
cat <<EOF > build_script
228 229
git clone https://gitlab.com/gitlab-org/gitlab-ci-multi-runner.git /builds/gitlab-org/gitlab-ci-multi-runner
cd /builds/gitlab-org/gitlab-ci-multi-runner
230
make
231 232 233
EOF
```

234 235 236 237 238 239 240
Here we use as an example the GitLab Runner repository which contains a
Makefile, so running `make` will execute the commands defined in the Makefile.
Your mileage may vary, so instead of `make` you could run the command which
is specific to your project.

Then create some service containers:

241
```
242 243
docker run -d --name service-mysql mysql:latest
docker run -d --name service-postgres postgres:latest
244 245
```

246 247 248 249 250 251 252
This will create two service containers, named `service-mysql` and
`service-postgres` which use the latest MySQL and PostgreSQL images
respectively. They will both run in the background (`-d`).

Finally, create a build container by executing the `build_script` file we
created earlier:

253
```
254
docker run --name build -i --link=service-mysql:mysql --link=service-postgres:postgres ruby:2.1 /bin/bash < build_script
255 256
```

257 258 259 260 261 262 263 264
The above command will create a container named `build` that is spawned from
the `ruby:2.1` image and has two services linked to it. The `build_script` is
piped using STDIN to the bash interpreter which in turn executes the
`build_script` in the `build` container.

When you finish testing and no longer need the containers, you can remove them
with:

265 266 267
```
docker rm -f -v build service-mysql service-postgres
```
268 269 270 271 272

This will forcefully (`-f`) remove the `build` container, the two service
containers as well as all volumes (`-v`) that were created with the container
creation.

273
[Docker Fundamentals]: https://docs.docker.com/engine/understanding-docker/
274 275
[hub]: https://hub.docker.com/
[linking-containers]: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/
276 277 278
[tutum/wordpress]: https://hub.docker.com/r/tutum/wordpress/
[postgres-hub]: https://hub.docker.com/r/_/postgres/
[mysql-hub]: https://hub.docker.com/r/_/mysql/
279
[runner-priv-reg]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md#using-a-private-docker-registry