LoginSignup
9
12

More than 3 years have passed since last update.

GitLab-CIでHerokuにデプロイするまでの奮闘記

Last updated at Posted at 2019-06-05

業務で開発者一人(+仕様検討一人)のプロジェクトをやってます。
開発を始めるにあたって、コードのGit管理は当たり前として、今後規模が大きくなった時のことも考えるとホスティングサービスは必須かなということでGitLabを導入することにしました。

※ほんとはGitHubでクラウド管理したいところですが、社内規定的にクラウドに業務情報を置けないのでオンプレ構築できるGitLabを採用しました

微妙にハマったところもあるので、備忘録がてら記事にしておこうかと思います。
※IPアドレスとかプロジェクト名なんかは、ところどころフェイク入れたりモザイク入れたりしてます。

構成

環境 説明
ローカルPC 開発環境(Windowsマシン)
サーバー用ノートPC 使わなくなったノートPCにCentOS7をインストールしたもの(予算がね。。)
※以降サーバーPC
Heroku ステージング環境/本番環境

初めてのGitLab構築

以下のページを参考に、サーバーPC上にDockerでインストールをします
参考:https://docs.gitlab.com/omnibus/docker/

dockerコマンドでGitLabコンテナ作成

sudo docker run --detach \
    --hostname 192.168.33.20 \
    --publish 10080:10080 --publish 10022:22 \
    --name gitlab \
    --restart always \
    --volume /srv/gitlab/config:/etc/gitlab:z \
    --volume /srv/gitlab/logs:/var/log/gitlab:z \
    --volume /srv/gitlab/data:/var/opt/gitlab:z \
    gitlab/gitlab-ce:latest

【公式からの変更点】

  • hostnameはサーバーPCのIPアドレスを指定
    • hostsに192.168.33.20 gitlab.example.com追加してとかメンバーに周知するのがめんどくさい
    • http://192.168.33.20:10080でアクセスできるようにしたかった
  • サーバーPCにはGitLab以外にも機能を搭載しているため、ポート22,80は使わないようにした
  • external_urlでポートまで指定すると起動ポートまで変わるみたいなので100080:10080で指定

GitLab設定編集

/srv/gitlab/config/gitlab.rb
・・・
external_url "http://192.168.33.20:10080/"
・・・
gitlab_rails['gitlab_shell_ssh_port'] = 10022
・・・
  • 編集完了後、docker exec gitlab gitlab-ctl reconfigureで設定を反映させる
    • docker restart gitlabでコンテナ再起動でも良いかも?

アクセスしてみる

external_urlで指定したURLにローカルPCのブラウザでhttp://192.168.33.20:10080にアクセス
image.png
⇒GitLabに接続できればOK!
 (最初はrootユーザーのパスワード設定画面が出る)

以下の画面が出る場合は、まだ起動中の場合が多いので、少し待つ
image.png

  • docker psでgitlabコンテナの起動状況を確認できます
    • (health: starting)となっていたら起動中
    • (healty)となっていたら起動完了
    • (unhealthy)となっていたら起動失敗
      • この場合はログを見て対応する

GitLab-CIについて

開発が一人だけで本番環境へのデプロイもまだまだ先だということで、ずっとGitLab単体で作業してました。
あれやこれやとやってる内に本番環境に反映するタイミングが来てしまったんですが、最初のデプロイは手作業でやってしまいました。。。

先のことを考えるとまずいなと思い、GitLab-CIの設定をすることに:sweat_smile:

↓ちなみに、ローカルPCからHerokuにデプロイする場合(heroku cliでログインしたりは別途必要です)

git pull
git push heroku master

【懸念】

  • pullし忘れて古いコードが本番に反映される可能性がある
  • ローカルの修正が本番にデプロイされる可能性がある
  • ...

docker-composeで再構築

GitLab-CIを使うにあたって、GitLab-Runnerのコンテナを新しく立てる必要が出てきた。

dockerコマンドでも構築できるが、構成を確認しづらいと思ったので、docker-composeで構築しなおすことにした。
(docker-compose.ymlはテキストだからGit管理できるし、見れば構成がわかるし、コマンドもdocker-compose upだけなので、簡単)

docker-composeでの構築にあたって、こちらのページを参考にさせていただきました。

データのバックアップ

何かあったら怖いので、バックアップを取っておきます

docker exec gitlab gitlab-rake gitlab:backup:create

⇒デフォルトでは/srv/gitlab/data/backups下に作られます

※もし、再構築ついでにGitLabを最新版にしたいなら、先に現在のGitLabを最新版にバージョンアップしてからバックアップを取って下さい。

構築済みGitLabバージョンを調べておく

gitlabコンテナイメージのバージョンが前回構築時と異なる場合、動かなくなる可能性があります。。。

バージョンは「?⇒Help」から確認できます。
image.png

docker-compose.yml

docker-compose.yml
version: '3'
services:
    gitlab:
        image: gitlab/gitlab-ce:11.8.10-ce.0
        restart: always
        container_name: gitlab
        volumes:
            - /srv/gitlab/config:/etc/gitlab:z
            - /srv/gitlab/logs:/var/log/gitlab:z
            - /srv/gitlab/data:/var/opt/gitlab:z
        environment:
            GITLAB_OMNIBUS_CONFIG: |
                external_url 'http://192.168.33.20:10080/'
                gitlab_rails['gitlab_shell_ssh_port'] = 10022
        ports:
            - "10080:10080"
            - "10022:22"
        networks:
            gitlab_net:
                ipv4_address: 172.16.238.2
    gitlab-runner:
        image: gitlab/gitlab-runner:v11.8.0
        restart: always
        container_name: gitlab-runner
        volumes:
            - /srv/gitlab-runner/config:/etc/gitlab-runner:z
            - /var/run/docker.sock:/var/run/docker.sock
        depends_on:
            - gitlab
        extra_hosts:
            - "192.168.33.20:172.16.238.2"
        networks:
            gitlab_net:
                ipv4_address: 172.16.238.3

networks:
    gitlab_net:
        ipam:
            config:
            - subnet: 172.16.238.0/24
  • 参考にさせていただいたページのymlをほぼ流用してます
  • 変更点
    • hostnameを削除(あるとうまくいかなかったので。。。)
    • コンテナ名を変更
    • GITLAB_OMNIBUS_CONFIGの内容を変更
    • volumeは前回構築時に指定したディレクリに変更
    • イメージのバージョンを前回構築時のバージョンと同じものを指定
      • 最初latestにしてたらバージョンの違いのせいでプロジェクトが見れなくなりました。。。
    • 一番下のvolumesを削除

GitLab-Runnerの登録

RunnerのURLおよびトークンの調べ方

Runnerの登録前に登録用のURLとトークンを調べておきます。

  • プロジェクトの「Settings⇒CI/CD」からRunner項目を展開する

image.png

  • 展開した中にURLとトークンがあるため、コピーする

image.png

Runnerの登録を行う

これも参考にさせていただいたページ通りに実行

docker-compose exec gitlab-runner gitlab-runner register \
    --non-interactive 
    --name gitlab-runner 
    --url http://192.168.33.20:10080/ 
    --registration-token "{YOUR-TOKEN} "
    --executor docker 
    --env "GODEBUG=netdns=cgo" 
    --docker-image debian:stretch-slim 
    --tag-list test `
    --docker-extra-hosts "192.168.33.20:172.16.238.2"

エラーが出た。。。

ローカルのVM上で試したときはすんなりと登録出来たのに、サーバーPCだと登録できませんでした。。。
image.png

ERROR: Registering runner... failed       runner=XXXXX status=couldn't execute POST against http://~/api/v4/runners: Post http://~/api/v4runners: dial tcp ~: get sockopt: no route to host
PANIC: Failed to register_this runner. Perhaps you are having network problems

ふむ、なんかしらのネットワークエラーが起こってるっぽい。。。
ネットワークわからん:sob:

とりあえず、gitlab-runnerコンテナ内から192.168.33.20が見えてないってことだと思う
gitlab-runnerコンテナ内でcurl http://192.168.33.20:10080がno routeになったし。

とりあえず、強引に登録してみる

urlのホスト名をgitlabコンテナで指定したIPアドレスに変更してみました

docker-compose exec gitlab-runner gitlab-runner register \
    --non-interactive 
    --name gitlab-runner 
    --url http://172.16.238.2:10080/ 
    --registration-token "{YOUR-TOKEN} "
    --executor docker 
    --env "GODEBUG=netdns=cgo" 
    --docker-image debian:stretch-slim 
    --tag-list test `
    --docker-extra-hosts "192.168.33.20:172.16.238.2"

登録出来た!:laughing:

パイプラインを実行してみた

image.png

Host is unreachable。。。
ちなみにこの時のhttp://gitlab-ci-token:xxxx@~:10080の~部分に表示されたURLは172.16.238.20ではなく、192.168.33.20の方だった:rolling_eyes:

クローン元のURLはRunner登録時の--urlで指定するURLとは別らしい。

原因調査

色々調べてる中で以下の記事を発見
https://gitlab.com/gitlab-org/gitlab-runner/issues/1036

  • external_urlを指定するんだよ!
  • extra_hostsに追加してみた?
  • linksにgitlabを指定すれば良いんだよ!

みたいなのが、色々と書いてあって、最後までず~っと読んでると、clone_urlを指定すれば良いんだよ!という回答が!!

clone_urlを指定してみる

公式ドキュメントに書いてありました
https://docs.gitlab.com/runner/configuration/advanced-configuration.html#how-clone_url-works

一旦、作成したrunnerを削除し、登録コマンドに--clone-url 172.16.238.2を追加して登録しなおしてみる。

↓パイプラインの実行結果
image.png
⇒クローン元のホストは変わったが、Operation timed out。。。

一応、Host is unreachableは解消されたのかな?

大きな勘違いに気づいた

ふとした瞬間にdocker ps -aでコンテナ一覧を確認した。
すると、runner-xxxxxのようなコンテナの残骸が大量にあった。。。

まさか。。。
再度パイプラインを動かし、動作中にdocker psしてみると、案の定runner-xxxというコンテナが動いていた。

ということは。。。
パイプライン動作中にデフォルトネットワークを確認してみる。
docker network inspect bridge
※ネットワーク指定なしだと、bridgeに属するっぽい

image.png

いたーーーーーーーーーーーーーーーーーー
要はCI用のコンテナがgitlab_net内にいないために、gitlabコンテナが参照できない状態となっていたってことらしい。

GitLab-CIでdockerを指定した場合、gitlab-runnerコンテナ内でCI用コンテナが動くもん(Docker-in-Docker)だと思ってましたが、実際はgitlabgitlab-runnerと同じ階層で起動するようです。

gitlab-runnerコンテナ内からホスト側へのネットワークが通じてないのかな~?みたいな調査をしてましたが、見当違いだったみたいです:sob:

ついに解決!!!

network_mode

ネットワークの設定とかできる項目ないかな~と公式ページを探していたら、以下の一覧にnetwork_modeなる項目が!!!

最終的なRunner登録コマンド

こんな感じに仕上がりました。

docker-compose exec gitlab-runner gitlab-runner register \
    --non-interactive \
    --name gitlab-runner \
    --url "http://gitlab:10080/" \
    --clone-url "http://gitlab:10080" \
    --registration-token "YOUR_TOKEN" \
    --executor docker \
    --env "GODEBUG=netdns=cgo" \
    --docker-image "debian:stretch-slim" \
    --tag-list test \
    --docker-network-mode "gitlab_gitlab_net" \
    --docker-pull-policy "if-not-present"
  • docker-network-modeでnetworkを指定
    • docker network lsで実際のネットワーク名を確認(gitlab_gitlab_netでした)
  • urlのホストはgitlabコンテナ名を指定

これで、Runnerの登録ができて、サンプルのパイプラインも動作するようになりました!!

(追記 2019/11/1)
 ・clone-urlがないとダメっぽいので追記しました
 ・毎度イメージをプルしないようにpull-policyを追加しました

Herokuへのデプロイ

Herokuへのデプロイ方法は以下のページを参考にする。
https://docs.gitlab.com/ee/ci/examples/README.html

.gitlab-ci.yml作成

今回Node.jsで開発しているのですが、公式ページだと情報がなかったので、こちらのページも参考にさせてもらいました。

gitlab-ci.yml
image: node:9-alpine

stages:
  - deploy

deploy-staging:
  image: ruby:latest
  stage: deploy
  tags:
    - test
  script:
  - gem install dpl
  - dpl --provider=heroku --app=$HEROKU_APP_STAGING --api-key=$HEROKU_CI_API_KEY
  only:
  - staging

deploy-production:
  image: ruby:latest
  stage: deploy
  tags:
    - test
  script:
  - gem install dpl
  - dpl --provider=heroku --app=$HEROKU_APP --api-key=$HEROKU_CI_API_KEY
  only:
  - master

とりあえず、ステージングと本番のデプロイをするだけです

GitLabに変数を登録

変数名 内容
HEROKU_APP_STAGING Heroku上のプロジェクト名(ステージング)
HEROKU_APP Heroku上のプロジェクト名(本番)
HEROKU_CI_API_KEY Herokuから取得したAPIキー

GitLabへの登録は対象プロジェクトの「設定⇒CI/CD⇒Environment variables」から行います。
image.png

HerokuのCI用APIキーの取得方法

  • Herokuにログインし、Account settingsを選択

image.png

  • Accountタブの下の方にAPI Keyがあります

image.png

image.png

いざHerokuへ

これで準備はできました!!
いざ、デプロイ!!!

image.png
(中略)
image.png

キターーーー:joy:

最後に

長い道のりでしたが、無事にHerokuへのデプロイまでできるようになりました:grin:
インフラとかネットワーク、Dockerあたりの知識は必要だな~と痛いほどに実感しました。。。

参考

GitLab Docs
Docker Compose で GitLab + GitLab Runner の環境を整える
Heroku Tips(4) Gitlabで自動デプロイ
Gitlab CI/CD Testing Nodejs App

9
12
0

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
9
12