※ DockerでRailsの環境構築をする方法に関して新しい記事を書いたので、下記を参照ください。 (2021/1/21更新)
Dockerに興味があり、作成したポートフォリオに組み込もうと思い、様々な記事を見ながら導入を試みましたが、かなり苦戦を強いられました。
無事導入することができましたので、今回は既存のRailsアプリにDockerを導入する方法を書いていきたいと思います。
環境
- Mac OS
- Ruby2.5.7
- Rails5.2.4
- mysql5.7
- nginx1.15.8
事前準備
- OS上に Docker と docker-compose をインストールしてください。
以下のコマンドを実行して、それぞれ表示されればインストールできています。
$ docker -v
Docker version 19.03.8, build afacb8b
$ docker-compose -v
docker-compose version 1.25.5, build 8a1c60f6
ファイル構成
ローカルのファイル構成は最終的に以下の通りになります。
myapp
|-- app
|-- bin
|-- config
|-- containers
|-- nginx
|-- Dockerfile
|-- nginx.conf
|-- db
|-- lib
|-- log
|-- public
|-- storage
|-- test
|-- tmp
|-- vendor
|-- config.ru
|-- docker-compose.yml
|-- Dockerfile
|-- Gemfile
|-- Gemfile.lock
|-- package.json
|-- Rakefile
|-- README.md
RubyのDockerfileを作成
myappはご自身のアプリケーション名に変えてください。
FROM ruby:2.5.7
RUN apt-get update -qq && \
apt-get install -y build-essential \
libpq-dev \
nodejs \
vim
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN gem install bundler
RUN bundle install
ADD . /myapp
RUN mkdir -p tmp/sockets
RUN mkdir -p tmp/pids
- From に記述している ruby:2.5.7 はご自身のGemfileに書いてあるrubyのバージョンに合わせてください。
- RUN gem install bundler を記述しないと、bundle install が実行できず、以下のようなエラーが表示され、rubyのコンテナが起動できません。
ERROR: Service 'app' failed to build: The command '/bin/sh -c bundle install' returned a non-zero code: 20
NginxのDockerfileを作成
FROM nginx:1.15.8
RUN rm -f /etc/nginx/conf.d/*
ADD nginx.conf /etc/nginx/conf.d/myapp.conf
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
nginx.confを作成
upstream myapp {
server unix:///myapp/tmp/sockets/puma.sock;
}
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root /myapp/public;
client_max_body_size 100m;
error_page 404 /404.html;
error_page 505 502 503 504 /500.html;
try_files $uri/index.html $uri @myapp;
keepalive_timeout 5;
location @myapp {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://myapp;
}
}
docker-compose.ymlの作成
version: '3'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: user
MYSQL_PASSWORD: 1234
MYSQL_DATABASE: myapp_db
volumes:
- mysql-data:/var/lib/mysql
ports:
- "4306:3306"
app:
build: .
command: bundle exec puma -C config/puma.rb
volumes:
- .:/myapp
- public-data:/myapp/public
- tmp-data:/myapp/tmp
- log-data:/myapp/log
web:
build:
context: containers/nginx
volumes:
- public-data:/myapp/public
- tmp-data:/myapp/tmp
ports:
- 80:80
volumes:
mysql-data:
public-data:
tmp-data:
log-data:
database.ymlを編集
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch('MYSQL_USER') { 'root' } %>
password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %>
host: db
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
production:
<<: *default
database: <%= ENV['DB_DATABASE'] %>
adapter: mysql2
encoding: utf8mb4
charset: utf8mb4
collation: utf8mb4_general_ci
host: <%= ENV['DB_HOST'] %>
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
puma.rbを編集
puma.rbの最下部に以下の記述を追加
app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"
stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true
Gemfileの編集
Gemfileに以下の記述を追加します。
gem 'mysql2'
コンテナの起動
あとはコンテナを起動するだけです。
アプリケーションのあるディレクトリに移動し以下のコマンドを実行します。
$ docker-compose up -d
しばらく経つと、最後に以下のように表示され、コンテナの起動が完了します。
Creating myapp_db_1 ... done
Creating myapp_app_1 ... done
Creating myapp_web_1 ... done
次のコマンドを実行し、コンテナが起動できているか確認します。
以下のように表示されれば、コンテナの起動は成功しています。
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------
myapp_app_1 bundle exec puma -C config ... Up
myapp_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:4306->3306/tcp, 33060/tcp
myapp_web_1 /bin/sh -c /usr/sbin/nginx ... Up 0.0.0.0:80->80/tcp
データベースの作成、マイグレーションファイルの読み込み
最後に以下のコマンドでデータベースの作成とマイグレーションファイルの読み込みをします。
$ docker-compose exec app rails db:create db:migrate
localhost:80にアクセスして、正しくに表示されればOKです。
コンテナの停止、削除
以下のコマンドでコンテナの停止、削除ができます。
$ docker-compose down
再び起動したい場合は先ほどと同様、 "dokcer-compose up -d" でOKです。
以下のコマンドでvolumeも一緒に削除できます。(Mysqlのデータも全て消えるので注意!!)
$ docker-compose down -v
Docker導入後の開発
Docker導入後の開発(rails g コマンド や budle install)を行うには Railsのコンテナの中に入る必要があります。
コンテナが起動された状態で、以下のコマンドを実行し、コンテナの中に入ります。
$ docker-compose exec app bash
ターミナル画面の左側の コンピューター名やユーザー名 が表示されている部分が以下のような感じに変わればコンテナに入ることができています。
root@f839434ad777:/myapp#
コンテナに入り、以下のコマンドで、Docker導入前の rails s -b 0.0.0.0 で見れていたログを表示することができます。
$ tail -f log/development.log
以下のコマンドでコンテナから出ることができます。
$ exit