業務で開発者一人(+仕様検討一人)のプロジェクトをやってます。
開発を始めるにあたって、コードの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
でアクセスできるようにしたかった
- hostsに
- サーバーPCにはGitLab以外にも機能を搭載しているため、ポート22,80は使わないようにした
- external_urlでポートまで指定すると起動ポートまで変わるみたいなので
100080:10080
で指定
GitLab設定編集
・・・
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
にアクセス
⇒GitLabに接続できればOK!
(最初はrootユーザーのパスワード設定画面が出る)
以下の画面が出る場合は、まだ起動中の場合が多いので、少し待つ
-
docker ps
でgitlabコンテナの起動状況を確認できます-
(health: starting)
となっていたら起動中 -
(healty)
となっていたら起動完了 -
(unhealthy)
となっていたら起動失敗- この場合はログを見て対応する
-
GitLab-CIについて
開発が一人だけで本番環境へのデプロイもまだまだ先だということで、ずっとGitLab単体で作業してました。
あれやこれやとやってる内に本番環境に反映するタイミングが来てしまったんですが、最初のデプロイは手作業でやってしまいました。。。
先のことを考えるとまずいなと思い、GitLab-CIの設定をすることに
↓ちなみに、ローカル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コンテナイメージのバージョンが前回構築時と異なる場合、動かなくなる可能性があります。。。
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項目を展開する
- 展開した中にURLとトークンがあるため、コピーする
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だと登録できませんでした。。。
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
ふむ、なんかしらのネットワークエラーが起こってるっぽい。。。
ネットワークわからん
とりあえず、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"
登録出来た!
パイプラインを実行してみた
Host is unreachable
。。。
ちなみにこの時のhttp://gitlab-ci-token:xxxx@~:10080
の~部分に表示されたURLは172.16.238.20
ではなく、192.168.33.20
の方だった
クローン元の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
を追加して登録しなおしてみる。
↓パイプラインの実行結果
⇒クローン元のホストは変わったが、Operation timed out
。。。
一応、Host is unreachable
は解消されたのかな?
大きな勘違いに気づいた
ふとした瞬間にdocker ps -a
でコンテナ一覧を確認した。
すると、runner-xxxxx
のようなコンテナの残骸が大量にあった。。。
まさか。。。
再度パイプラインを動かし、動作中にdocker ps
してみると、案の定runner-xxxというコンテナが動いていた。
ということは。。。
パイプライン動作中にデフォルトネットワークを確認してみる。
docker network inspect bridge
※ネットワーク指定なしだと、bridge
に属するっぽい
いたーーーーーーーーーーーーーーーーーー
要はCI用のコンテナがgitlab_net内にいないために、gitlabコンテナが参照できない状態となっていたってことらしい。
GitLab-CIでdockerを指定した場合、gitlab-runnerコンテナ内でCI用コンテナが動くもん(Docker-in-Docker)だと思ってましたが、実際はgitlab
やgitlab-runner
と同じ階層で起動するようです。
gitlab-runnerコンテナ内からホスト側へのネットワークが通じてないのかな~?みたいな調査をしてましたが、見当違いだったみたいです
ついに解決!!!
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で開発しているのですが、公式ページだと情報がなかったので、こちらのページも参考にさせてもらいました。
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」から行います。
HerokuのCI用APIキーの取得方法
- Herokuにログインし、
Account settings
を選択
- Accountタブの下の方に
API Key
があります
いざHerokuへ
これで準備はできました!!
いざ、デプロイ!!!
キターーーー
最後に
長い道のりでしたが、無事にHerokuへのデプロイまでできるようになりました
インフラとかネットワーク、Dockerあたりの知識は必要だな~と痛いほどに実感しました。。。
参考
GitLab Docs
Docker Compose で GitLab + GitLab Runner の環境を整える
Heroku Tips(4) Gitlabで自動デプロイ
Gitlab CI/CD Testing Nodejs App