環境
・Docker 20.10.22
・Rails6.1
・Mysql5.7
はじめに
Railsチュートリアルを完走したので、練習のためにアプリをDockerに配置してみようと思いました。
ファイルの作成
必要になるファイルは、以下の5つ
- Dockerfile
- docker-compose.yml
- Gemfile
- Gemfile.lock
- entrypoint.sh
Dockerfile
docker-compose.yml
docker-entrypoint.sh
ファイルを作成する。
$ touch {Dockerfile,docker-compose.yml,Gemfile,Gemfile.lock,entrypoint.sh}
Dockerfile
Dockerfile(イメージを作成する時に使用するファイル)
FROM ruby:3.1.1
RUN apt-get update -qq \
&& apt-get install -y nodejs npm \
&& npm install --global yarn \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
COPY ./docker-entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
CMD
基本的な使い方
CMD [“実行ファイル”, “パラメータ1”, “パラメタ2”…]
CMD ["rails", "server", "-b", "0.0.0.0"]
-
exec
は処理を実行するコマンドであり、"$@"
は全ての引数という意味。
つまりexec rails server -b 0.0.0.0
という処理が実行される。 -
exec rails server -b 0.0.0.0
はrails server
をコンテナ内のすべてのIPに紐づけている。
-b
railsのプロセスをどのIPアドレスにバインドするか。
0.0.0.0
を指定することで、コンテナ内のサーバーにアクセスできるようになる。
参考
EXPOSE
コンテナが接続用にリッスンするポートを指定する。
基本的にはローカル環境なら3000を指定
docker-entrypoint.sh
初回起動時のみに処理したい内容を記述するヘルパースクリプト。
ENTRYPOINT
で読み込ませることができる。
ENTRYPOINT のベストな使い方は、イメージにおけるメインコマンドの設定です。これによりイメージを指定したコマンドを通して実行します(そして、 CMD がデフォルトのフラグとして使われます)。
#!/bin/bash
#エラー発生時、スクリプトを修了する
set -e
# 初期に作成されるPIDを削除する
# 削除しないと次回起動時にエラーが出る
rm -f /rails-vue/tmp/pids/server.pid
# DockerfileのCMDにセットしたすべての引数を実行する
exec "$@"
docker-compose.yml
version: "3"
services:
web:
container_name: sample_app_local
build: .
# -cで、渡されたコマンドを実行
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
# データの永続化(ホスト側のカレントディレクトリにマウントする)
volumes:
- .:/myapp
# ポートの指定(外部からのアクセス時のポート:Dockerコンテナからアクセス時のポート)
ports:
- "3000:3000"
depends_on:
- db
db:
image: mysql:5.7
#データが消えないように、ボリュームを作成。
volumes:
- mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: docker
ports:
- 3306:3306
volumes:
mysql-data:
db:
のenvironment
のMYSQL_ROOT_PASSWORD:
は必須です。
config/database.yml
のpasswordと一致させます。
volumesの動き
個人的にvolumeの動きが曖昧だったので整理します。
mysql-dataという名前でコンテナ内のvolumesに新規作成。DBのデータはここに保存されていく
volumes:
mysql-data:
上記のボリュームに保存されたデータを、コンテナ内アプリの/var/lib/mysql
にコピー
db:
volumes:
- mysql-data:/var/lib/mysql
config/database.yml
主に、passwordの設定やhostの設定を行います。
default: &default
adapter: mysql2
encoding: utf8
charset: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
password: docker #docker-compose.ymlのMYSQL_ROOT_PASSWORDと一致させる
socket: /tmp/mysql.sock
host: db #追記
サービス構築、立ち上げ
ビルド
$ docker-compose build
立ち上げ
$ docker-compose up -d
-d デタッチモード
yarn install
私の環境ではwebサーバーを立ち上げる際に下記のようなエラーが出ました。
========================================
Your Yarn packages are out of date!
Please run `yarn install --check-files` to update.
========================================
To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).
yarn check v1.22.19
info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.
そのためwebサーバーでyarn installを実行します
$ docker-compose run web yarn install
DB作成、マイグレート
$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate
参考サイト
DockerでRails環境を構築してみた
DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】
rails s -b 0.0.0.0 のオプション-bの意味
[Rails][docker]Please run yarn install --check-files
を解決する