はじめに
今回はタイトル通りの開発環境を構築したので備忘録的にまとめる為に記事にしました。
既存のrailsプロジェクトにこの開発環境を導入する記事になります。新しいrailsプロジェクトの場合は少し手順が変わりますが同じように環境を構築できると思います。
参考させていただいた記事等
世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
こちらの記事を参考にAWSにアプリをデプロイしていたのでunicoronの設定を同じものにしています。
nginxの設定ファイルはこちらを参考にさせていただきました。
Nginx設定のまとめ
nginxについてまとめ(設定編)
構成
コンテナはrailsアプリ用、Mysql用、nginx用の3つを作成します。
rails+Mysqlの環境についてはこちらの記事で紹介してます。
Dockerを使用して既存のRailsプロジェクト開発環境構築してみた
ファイル構成はこのようになります。
.(既存railsプロジェクト)
├── Dockerfile
├── docker-compose.yml
├── Gemfile
├── Gemfile.lock
├── config
| └──datebase.yml
| └──unicorn.conf.rb
└── nginx
├──Dockerfile
└──nginx.conf
1.Dockerfile(rails)
#既存のプロジェクトのrubyのバージョンを指定FROM ruby:2.6.3
dockerizeパッケージダウンロード用環境変数
ENV DOCKERIZE_VERSION v0.6.1#パッケージの取得RUN apt-get update &&\
apt-get install-y--no-install-recommends\
nodejs \
mariadb-client \
build-essential \
wget \
&& wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&&tar-C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&&rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& apt-get clean \
&&rm-rf /var/lib/apt/lists/*WORKDIR /myprojectCOPY Gemfile /myproject/GemfileCOPY Gemfile.lock /myproject/Gemfile.lockRUN gem install bundler
RUN bundle installCOPY . /myproject
dbが立ち上がる前にunicornコマンドを行わないようにdockerizeをdocker-composeで使用するのでここでダウンロードしています。こちらの記事も参照いただければと思います。
dockerizeでコンテナが立ち上がる順番を制御してみた
2.dockerfileと設定ファイル(nginx用)
FROM nginx:stable#デフォルトのnginxファイルを削除して作成したものコンテナないにコピーRUN rm-f /etc/nginx/conf.d/*COPY nginx.conf /etc/nginx/conf.d/myapp.conf#-c以降の設定ファイルを指定して起動 daemon offでフォアグラウンドで起動CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
upstreamunicorn {
#ユニコーンソケットの設定
serverunix:/myproject/tmp/sockets/.unicorn.sockfail_timeout=0;
}
server {
#IPとポートの指定
listen80default;
#サーバーネームの指定
server_namelocalhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
#ドキュメントルートの指定
root /myproject/public;
client_max_body_size100m;
error_page404 /404.html;
error_page505502503504 /500.html;
try_files $uri/index.html $uri @unicorn;
keepalive_timeout5;
location @unicorn {
proxy_set_headerX-Real-IP $remote_addr;
proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_headerHost $http_host;
proxy_passhttp://unicorn;
}
}
Gemファイルにunicorn追加
gem'unicorn'
3.各種設定(database.yml,unicorn.conf.rb)
default:&defaultadapter:mysql2encoding:utf8pool:5username:rootpassword:passworddevelopment:<<:*defaulthost:dbdatabase:docker_development
$worker=2$timeout=30$app_dir="/myproject"#自分のアプリケーションまでのpath$listen=File.expand_path'tmp/sockets/.unicorn.sock',$app_dir$pid=File.expand_path'tmp/pids/unicorn.pid',$app_dir$std_log=File.expand_path'log/unicorn.log',$app_dir# set configworker_processes$workerworking_directory$app_dirstderr_path$std_logstdout_path$std_logtimeout$timeoutlisten$listenpid$pid# loading boosterpreload_apptrue# before starting processesbefore_forkdo|server,worker|defined?(ActiveRecord::Base)andActiveRecord::Base.connection.disconnect!old_pid="#{server.config[:pid]}.oldbin"ifold_pid!=server.pidbeginProcess.kill"QUIT",File.read(old_pid).to_irescueErrno::ENOENT,Errno::ESRCHendendend# after finishing processesafter_forkdo|server,worker|defined?(ActiveRecord::Base)andActiveRecord::Base.establish_connectionend
3.docker-compose.yml
version:'3'services:web:build:context:.dockerfile:Dockerfilecommand:dockerize -wait tcp://db:3306 -timeout 20s bundle exec unicorn -p 3000 -c /myproject/config/unicorn.conf.rbtty:true#pry-byebugを使えるようにするstdin_open:truedepends_on:-dbports:-"3000:3000"volumes:-.:/myproject:cached#ソケット通信用ファイルをnginxコンテナと共有-tmp-data:/myproject/tmp/sockets#画像データとかをnginxと共有-public-data:/myproject/publicdb:image:mysql:5.7command:mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ciports:-'3306:3306'environment:MYSQL_DATABASE:docker_developmentMYSQL_ROOT_PASSWORD:passwordMYSQL_USER:rootMYSQL_PASSWORD:password#dbのデータを永続化しておくvolumes:-mysql-data:/var/lib/mysqlnginx:build:context:./nginxdockerfile:Dockerfileports:-80:80restart:always#明示的にstopさせるまでリスタートする。(失敗するたび遅延あり)volumes:-tmp-data:/myproject/tmp/sockets-public-data:/myproject/publicdepends_on:-webvolumes:public-data:tmp-data:mysql-data:
名前つきvolumeを作成してdbのデータの永続化と、nginxとunicornのソケット通信用ファイルを共有化しています。
次のコマンドを実行してコンテナを立ち上げてください。以上で環境の構築は終わりです。
#imageの作成
docker-compose build
#コンテナの立上げ
dokcer-compose up -d
docker-compose exec web bundle exec rails db:migrate
終わりに
今回の環境を作成する上で困った点はdbが立ち上がる前にunicornコマンドを実行しようとして、コネクションエラーがよく起きたことです。dockerizeを利用することによって解決することができました。
また、データ永続化にするときに/myproject/tmp/で最初に指定していたせいで、tmp/pidsも永続化されてコンテナのbuildやupを何度か繰り返しているとうまくサービスが終了しなかった時とかに、pidファイルが残ってエラーを起こしてました。volumeを削除して立ち上げなおすことが何度かありました。
以前書いたこちらの記事も組み合わせればRSpecのテスト用の環境も追加できます。
Docker+Rails+HeadlessChromeでRSpecのSystem Testしてみた
次回はRSpecテスト用に2個目のdocker-compose.ymlを用意して、CircleCIで自動テストをする環境構築について記事にしたいと思います。
ここまでお読みいただきありがとうございました。