数時間苦闘したのでメモ。
.gitlab-ci.yml
build:
stage: build
image: docker:stable
services:
- docker:dind
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG || true
- docker build --cache-from $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG app
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
test:
stage: test
image: tmaier/docker-compose:19.03
services:
- docker:dind
script:
- docker version
- docker-compose version
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- sed -i "s|build:|# build:|" docker-compose.yml
- sed -i "s|context:|# context:|" docker-compose.yml
- sed -i "s|app_image|$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG|" docker-compose.yml
- docker-compose -p $CI_COMMIT_SHA config
- docker-compose -p $CI_COMMIT_SHA pull
- docker-compose -p $CI_COMMIT_SHA run test
after_script:
- docker-compose -p $CI_COMMIT_SHA down -v
- docker-compose -p $CI_COMMIT_SHA rm -f
- build ジョブは標準的な手順のまま。1
- test では
- image: docker/compose もあったが、 variables を設定してもサーバーとうまく接続できなかったので、 tmaier/docker-compose を使うようにした2。このイメージで直接テストを行うのは難があるので、テストスクリプトを実行して終了するサービス test を追加している。
- sed: ローカルでは build context で作っているのでそれをコメントアウトしている。イメージは build ジョブで作ったものを使用するようにしている。
- $CI_COMMIT_SHA: 複数のジョブまたはパイプラインが同時に実行される可能性がある場合は
-p project_name
で一意にしないとおそらく破綻する。 - after_script: コンテナとボリュームとネットワークの後始末。
docker-compose.yml
そのまま。
ローカルで test イメージを起動したくないときは docker-compose up -d app
などする。
version: "3.0"
services:
redis:
image: redis:5.0
volumes:
- redis_data:/data
app:
build:
context: app
image: app_image
depends_on:
- redis
ports:
- "80:80"
command: "/app/main.py"
test:
image: app_image
depends_on:
- app
volumes:
- ./:/work:ro
command: "/work/test.sh"
volumes:
redis_data:
CI Runner の config.toml
関係する部分を抜粋。
[[runners]]
name = "xxx"
url = "xxx"
token = "xxx"
executor = "docker"
[runners.custom_build_dir]
[runners.docker]
tls_verify = false
image = "ubuntu:18.04"
privileged = true
volumes = ["/certs/client", "/cache"]
検証環境
CI のログから。
$ docker version
Client: Docker Engine - Community
Version: 19.03.5
API version: 1.40
Go version: go1.12.12
Git commit: 633a0ea838
Built: Wed Nov 13 07:22:05 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.6
API version: 1.40 (minimum version 1.12)
Go version: go1.12.16
Git commit: 369ce74a3c
Built: Thu Feb 13 01:32:22 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.2.12
GitCommit: 35bd7a5f69c13e1563af8a93431411cd9ecf5021
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683
$ docker-compose version
docker-compose version 1.25.1, build a82fef0
docker-py version: 4.1.0
CPython version: 2.7.16
OpenSSL version: OpenSSL 1.1.1d 10 Sep 2019