LoginSignup
10
4

More than 5 years have passed since last update.

gitlab-ciを使ってdocker build&pushを自動化したい

Last updated at Posted at 2018-10-06

なぜやるの?

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に最初から定義されている

ありがとうございました

10
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4