はじめに
以前「無料!かつ最短?で Ruby on Rails on Docker on AWS のアプリを公開するぞ。 - Qiita」でRuby on Rails on DockerのアプリをAWSで公開する手順を記事にまとめさせていただきました。
何回かアプリの更新を行なっているうちに気づいたことがあります。t2.microさん、bundle installに耐えられてない...
Gemfileに手を加えてない時はいいのですが、そうでない時は決まってEC2のCPU使用率がCloudWatch上100%になってしまい...最悪SSHがフリーズしてしまいインスタンス再起動なんてことも...
これではいけないということで、GitLab Container Registry(GitLabレジストリ)を活用させていただきbuildはEC2以外の場所で実行し、EC2はcontainer upを行うのみにしたいと思います。
インフラ構成は基本的に以前の記事と同じです。
事前準備
docker-compose.ymlはこんなイメージです。
version: '3'
services:
web:
container_name: myapp_web_prod
build: .
environment:
RAILS_ENV: production
command: bundle exec puma -C config/puma.rb
volumes:
- .:/myapp
- ./public:/myapp/public
- ./tmp:/myapp/tmp
- ./log:/myapp/log
ports:
- 3000:3000
nginx:
container_name: myapp_nginx_prod
build: containers/nginx
volumes:
- ./public:/myapp/public
- ./tmp:/myapp/tmp
ports:
- 80:80
depends_on:
- web
docker-compose buildすると、myapp_web、myapp_nginxのimageが作成されることと、docker-compose upするとmyapp_web_prod、myapp_nginx_prodのcontainerが起動することがわかればよしです。
今までの手順
- localhostからGitLabレポジトリにアプリのソースコードをpush
- EC2でGitLabリポジトリからアプリのソースコードをpull
- EC2で
docker-compose buildしてdocker imageを作成 #ここでとまる。 - EC2で
docker-compose upしてdocker imageからdocker containerを起動
改善版の手順
- localhostからGitLabレポジトリにアプリのソースコードをpush
- localhostで
docker-compose buildしてdocker imageを作成 - localhostからGitLabレジストリにdocker imageをpush
- EC2でGitLabリポジトリからアプリのソースコードをpull
- EC2でGitLabレジストリからdocker imageをpull
- EC2で
docker-compose upしてdocker imageからdocker containerを起動
それでは早速改善版の手順を進めていきましょう!
1. localhostからGitLabレポジトリにアプリのソースコードをpush
説明は端折ります。
$ git push origin master
2. localhostでdocker-compose buildしてdocker imageを作成
ここも説明端折ります。
$ docker-compose build
$ docker images #"myapp_web"と"myapp_nginx"のimageが作成されていることを確認
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp_web latest xxxxxxxx xxxxxxx xxxxx
myapp_nginx latest xxxxxxxx xxxxxxx xxxxx
3. localhostからGitLabレジストリにdocker imageをpush
# Gitlabのレジストリにログインする。UsernameとPasswordを聞かれるので入力する。この手順は初めの1回だけです。
$ docker login registry.gitlab.com
# pushするimageのrepositoryをGitLabに向ける
$ docker tag myapp_web registry.gitlab.com/mygroup/myapp/myapp_web
$ docker tag myapp_nginx registry.gitlab.com/mygroup/myapp/myapp_nginx
# docker imagesを確認すると以下のようになる
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp_web latest xxxxxxxx xxxxxxx xxxxx
myapp_nginx latest xxxxxxxx xxxxxxx xxxxx
registry.gitlab.com/mygroup/myapp/myapp_web latest xxxxxxxx xxxxxxx xxxxx
registry.gitlab.com/mygroup/myapp/myapp_nginx latest xxxxxxxx xxxxxxx xxxxx
# GitLabにimage pushする
$ docker push registry.gitlab.com/mygroup/myapp/myapp_web
$ docker push registry.gitlab.com/mygroup/myapp/myapp_nginx
GitLabへのpushは<registry URL>/<namespace>/<project>/<image>とするとのこと。
詳しくは「GitLab Container Registry | GitLab」を参考に。
4. EC2でGitLabリポジトリからアプリのソースコードをpull
こちらも端折ります。EC2にSSHしている前提で。
[myuser@xxx.xxx.xxx.xxx myapp]$ git pull origin master
5. EC2でGitLabレジストリからdocker imageをpull
GitLabのレジストリを指定してpullするだけです。
[myuser@xxx.xxx.xxx.xxx ~]$ docker pull registry.gitlab.com/mygroup/myapp/myapp_web
[myuser@xxx.xxx.xxx.xxx ~]$ docker pull registry.gitlab.com/mygroup/myapp/myapp_nginx
[myuser@xxx.xxx.xxx.xxx ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.gitlab.com/mygroup/myapp/myapp_web latest xxxxxxxx xxxxxxx xxxxx
registry.gitlab.com/mygroup/myapp/myapp_nginx latest xxxxxxxx xxxxxxx xxxxx
6. EC2でdocker-compose upしてdocker imageからdocker containerを起動
docker-compose upではmyapp_webとmyapp_nginxのimageからコンテナを起動することになっていますが、レポジトリがregistry.gitlab.com/mygroup/myapp/myapp_xxxxxになってしまっているのでこのままでは起動できません。localhostでGitLabにpushする前にやったようにレポジトリの名前をdocker tagコマンドで変更していきます。
[myuser@xxx.xxx.xxx.xxx ~]$ docker tag registry.gitlab.com/mygroup/myapp/myapp_web myapp_web
[myuser@xxx.xxx.xxx.xxx ~]$ docker tag registry.gitlab.com/mygroup/myapp/myapp_nginx myapp_nginx
[myuser@xxx.xxx.xxx.xxx ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.gitlab.com/mygroup/myapp/myapp_web latest xxxxxxxx xxxxxxx xxxxx
registry.gitlab.com/mygroup/myapp/myapp_nginx latest xxxxxxxx xxxxxxx xxxxx
myapp_web latest xxxxxxxx xxxxxxx xxxxx
myapp_nginx latest xxxxxxxx xxxxxxx xxxxx
ここまできたらGitLabからpullしてきたレポジトリ名の方のimageはいらないので管理しやすくするために消してしまってもいいです。
[myuser@xxx.xxx.xxx.xxx ~]$ docker rmi registry.gitlab.com/mygroup/myapp/myapp_web
[myuser@xxx.xxx.xxx.xxx ~]$ docker rmi registry.gitlab.com/mygroup/myapp/myapp_nginx
[myuser@xxx.xxx.xxx.xxx ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp_web latest xxxxxxxx xxxxxxx xxxxx
myapp_nginx latest xxxxxxxx xxxxxxx xxxxx
ここまでできたらコンテナを起動するのみです。
ソースコードの改修次第ではdb:migrateやassets:precompileが必要かもしれませんが、それらもdocker-compose run webコマンドを使って実行することができます。
[myuser@xxx.xxx.xxx.xxx ~]$ docker-compose run web rails db:migrate
[myuser@xxx.xxx.xxx.xxx ~]$ docker-compose run web rails assets:clobber
[myuser@xxx.xxx.xxx.xxx ~]$ docker-compose run web rails assets:precompile
# ここまでは必要であれば。
[myuser@xxx.xxx.xxx.xxx ~]$ docker-compose up -d
これでEC2上でのbuildを回避することができました!
終わりに
これを毎回毎回やるのは面倒ですので、とりあえずシェルスクリプトを組んでみてます。
GitLabではCI/CDツールも提供してくれているので、次はここに記載した手順をCI/CDに組み込めないか検討してみようと思います!