なぜやるの?
dockerを使って開発を行っている.そこでgitlabにソースをpushするだけでGitLab Container Registryにimageを作ってほしい
どうやるの?
- .gitlab-ci.yamlにステージを追加する
- docker imageを指定する
- docker loginをする
- docker buildをする
- docker pushする
全体のyaml
stages:
- docker-login
- docker-build
docker-login:
image: docker:stable
services:
- docker:dind
stage: docker-login
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
branch-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t registry.gitlab.com/empenguin/momoka-slacker/alpine-php:branch ./service/.
- docker push registry.gitlab.com/empenguin/momoka-slacker/alpine-php:branch
master-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t registry.gitlab.com/empenguin/momoka-slacker/alpine-php:latest ./service/.
- docker push registry.gitlab.com/empenguin/momoka-slacker/alpine-php:latest
only:
- master
.gitlab-ciにステージを追加する
stages:
- docker-login
- docker-build
今回はdocker-loginステージとdocker-buildステージを追加する
docker-loginはdocker loginできるかどうかテストするために今回用意したもの
なので実際に使うときはdocker-loginはいらない
docker imageを指定する
docker-login:
image: docker:stable
services:
- docker:dind
stage: docker-login
imageをdocker:stableにしているほかのタグが使いたいならdockerのdocker hubを見るとほかの物もあることが分かる
ちなみにdocker-loginはログインできるかどうかの確認用なので
branch-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
こちらでも同じことをやっている
docker loginをする
branch-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
docker loginしている ,CI_REGISTRY_USER,$CI_REGISTRY_PASSWORD
それぞれあらかじめ変数として追加しておいたものgitlab.comのアカウントを追加しておくといい
ここを参考にするといいと思う
docker buildをする
branch-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t registry.gitlab.com/empenguin/momoka-slacker/alpine-php:branch ./service/.
ここではbuildをやっているdocker buildするときはpushする先と同じでなければエラーになってしまうためpush先と同じ名前でbuildしておく
タグはbranchにしている・・・まぁdocker hubにbuildしたことがある人なら大丈夫だろう
docker pushする
branch-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t registry.gitlab.com/empenguin/momoka-slacker/alpine-php:branch ./service/.
- docker push registry.gitlab.com/empenguin/momoka-slacker/alpine-php:branch
同じようにbranchタグを追加してpushする試してはないけどタグなしでもpushできるはず
ちなみに
master-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t registry.gitlab.com/empenguin/momoka-slacker/alpine-php:latest ./service/.
- docker push registry.gitlab.com/empenguin/momoka-slacker/alpine-php:latest
only:
- master
onlyを付け加えることでそのブランチにプッシュ or マージされたときだけjobを実行することができる
この場合の例だとmasteブランチにマージされたときだけmaste-buildの内容が実行されてタグがlatestで追加される
k8sを使っている我々としてはmasterにマージされたものはコンテナとして動くことは保証されているので
k8sのアップデートをすることで常に新しいcontainerが立つ
まとめ
onlyタグをつけることでjobを分けることができるのは大きいと感じている
なぜなら新たに開発を行うときも,本番で動かしたいときも常にlatestタグを引っ張ってくればいいからだ
逆に開発を行っているときはbranchタグをつけるようになっているため誰かと近いところを開発しているときはbranchタグが上書きされてしまうときがある.これは改善するべきタスクだと考えている.今考えている改善案として
gitlabの最初から使うことができる変数CI_COMMIT_SHA
を使う方法を考えているこれはcommitのハッシュが入っているはず.これを使って一意にタグを決めてあげることで解決できるのではないかと考えている
また解消できたときに記事を上げようと思う
ありがとうございました
追記
便利なやり方を教えていただいたため追記します
何を教えていただいたか
docker loginに$CI_JOB_TOKENを使う方法を教えていただいた
現状の何が問題か
docker loginするときに変数CI_REGISTRY_PASSWORDを定義しているが
これは管理者権限を持ったアカウントのパスワードを渡している.
もしアカウントのパスワードを変更したときには変数CI_REGISTRY_PASSWORDの変数を手動で変更しなければならない
どう解決するか
docker login時にユーザをgitlab-ci-token
,パスワードを$CI_JOB_TOKEN
に設定することでプロジェクトのユーザとしてログインすることができる
全体はこうなった
stages:
- docker-login
- docker-build
docker-login:
image: docker:stable
services:
- docker:dind
stage: docker-login
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
branch-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker build -t registry.gitlab.com/empenguin/momoka-slacker/alpine-php:branch ./service/.
- docker push registry.gitlab.com/empenguin/momoka-slacker/alpine-php:branch
master-build:
image: docker:stable
services:
- docker:dind
stage: docker-build
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker build -t registry.gitlab.com/empenguin/momoka-slacker/alpine-php:latest ./service/.
- docker push registry.gitlab.com/empenguin/momoka-slacker/alpine-php:latest
only:
- master
全体ではこうなる
どこが変わったかというと
docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
gitlab.comの記事では
You have to use the special gitlab-ci-token user created for you in order to push to the Registry connected to your project.
gitlab.comより
なるほどgitlab-ci-tokenを使ってプロジェクトのレジストリにプッシュしないと行けない,推奨してるということだろう(間違ってたらごめんなさい)
そして,そのgitlab-ci-tokenのパスワードは$CI_JOB_TOKENに最初から定義されている
ありがとうございました