本番コンテナの(ECS/Fargate)運用で、一番大変なのはコンテナの設計とデプロイ方法です。ここをしっかり決めておかないと開発環境から全てやり直しになります。この2週間はだいぶハマりまくったのでだいぶ知見が増えました。今回はRailsでCircleCIのデプロイよりも前のDockerfileでやることをブログします。
■デプロイする前にDockerfileでやることって?
まずCircleCIを使わずにECRへpushする場合はローカルで docker build
してからpushする流れが一般的です。実際のフローは以下。
- Dockerfileでの各パッケージをインストール
- Dockerfileでソースを
COPY
- Dockerfileで
bundle install
- Dockerfileで
assets:precompile
- コンテナ内に.envの配置
- ECRにpush
このソースコピーとbundle installらを自分はCircleCIでデプロイしようと頑張っていましたが、独自のユーザーで権限やらなんやらで死にそうになり、rootユーザーで管理することにしました。まずはDockerfileにできることを組み込めれば、CircleCIでやることはDockerfileのbuild
.envの設置
ECRにpush
ECSのリビジョンを変更
となります。ここらへんはCircleCIのOrbsを使って実装できるので、かなりシンプルな作りとなります。それでは以下Stg用のDockerfileを見てみましょう。
■Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
FROM ruby:2.5.7 ENV LANG C.UTF-8 ENV ENTRYKIT_VERSION 0.4.0 ENV QMAKE=/usr/lib/qt5/bin/qmake ENV APP_ROOT /var/www/app RUN apt-get update -y && \ apt-get upgrade -y && \ apt-get install -y --no-install-recommends \ bash \ build-essential \ git \ libcurl4-openssl-dev \ libghc-yaml-dev \ libqt5webkit5-dev \ libxml2-dev \ libxslt-dev \ libyaml-dev \ linux-headers-amd64 \ default-mysql-client \ nginx \ nodejs \ openssl \ ruby-dev \ ruby-json \ tzdata \ vim \ supervisor \ zlib1g-dev && \ apt-get clean -y && \ rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* RUN wget https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \ && tar -xvzf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \ && rm entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \ && mv entrykit /bin/entrykit \ && chmod +x /bin/entrykit \ && entrykit --symlink # copy app RUN mkdir -p $APP_ROOT WORKDIR $APP_ROOT COPY . $APP_ROOT RUN cp config/mail.yml.exampleconfig/mail.yml RUN cp docker/stg/app/.env.example $APP_ROOT/.env # build nokogiri COPY docker/stg/app/gemrc/.gemrc /etc/gemrc/ RUN chmod +r /etc/gemrc RUN bundle config --global build.nokogiri --use-system-libraries # bundle install RUN bundle install --path vendor/bundle RUN bundle exec rake assets:stgcompile RAILS_ENV=stg # nginx RUN groupadd nginx RUN useradd -g nginx nginx ADD docker/stg/app/nginx/nginx.conf /etc/nginx/nginx.conf ADD docker/stg/app/nginx/adachin.conf /etc/nginx/conf.d/adachin.conf # setting superviser COPY docker/stg/app/supervisor/app.conf /etc/supervisor/conf.d/app.conf # link logs RUN ln -sf /dev/stdout /var/log/nginx/access.log RUN ln -sf /dev/stderr /var/log/nginx/error.log # Service to run CMD [ "/usr/bin/supervisord" ] |
上記のようにDockerfileでソースのコピー、 bundle install
と precompile
を指定しています。nginxとunicornは下記の supervisor
で立ち上がります。あとはローカルで docker build
すればあとは.envを入れて、ECRにpushしてリビジョンを変更するだけで終わります。実際にbuildテストとして以下のようにローカルでデバッグ確認をすれば良いですね。
1 |
$ docker build -f docker/stg/adachin-app/Dockerfile -t xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/adachin-app:latest . |
- supervisor/app.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[supervisord] nodaemon=true [program:app] command=bundle exec unicorn_rails -c config/pre_unicorn.rb -E stg autostart=true autorestart=true stopsignal=TERM user=root directory=/var/www/app/ stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 [program:nginx] command=/usr/sbin/nginx -g "daemon off;" autostart=true autorestart=true stopsignal=TERM user=root stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 |
上記のようにDockerはプロセスがフォアグラウンドで動いてないと、コンテナが終了するためデーモンをオフにしてフォアグラウンドで実行できるようにしています。
■まとめ
Dockerfileでなるべく完結して、CircleCIではシンプルな構成に持っていくということを学べました。来週はOrbsでbuild、.envの追記、ECSでのリビジョン変更をブログします。
(下記書きましたのでぜひ!)
[CircleCI][AWS][Rails]OrbsのCommandsをつかってECR/ECS/Fargateにデプロイする
0件のコメント