Nginx+Rails6.0+MySQL8.0+Adminer:docker-compose で rails new
Docker の仕組みの解説や rails new
や webpacker の詳しい話はしません。
TL;DR
- このへんの記事と大体同じです
- とりあえずのdocker-compose upから入って、Web serverの基礎設計を学びながらDockerを学ぶ① | Naokit_dev | zenn
- Docker ComposeでRuby2.7+Rails6.0+MySQL8.0の環境を用意してrails newする | Qiita
- Dockerを使ってRails6環境の構築をしてみる | Qiita
- Rails newからproductionモードで動くようになるまで | Qiita
- 丁寧にNginx + MySql + Rails6 (Using Webpacker) on Dockerな開発環境を構築します。 | Qiita
- Adminer
- 今回のリポジトリはこちら
今回の構成
- Nginx
- Railsサーバへのリバースプロキシ
- 静的コンテンツ(JavaScript/CSS/画像ファイルなど)の配信
- フロントエンドの環境整備は今回はやりません
- Rails(Puma)
- アプリケーションサーバ
- Webpacker はいったんそのままで
- simpacker を使う構築は別記事でまた上げる予定です
- MySQL
- データベース
- PostgreSQL でないのは本番環境で Amazon RDS for MySQL を利用する予定のため
- というか私が PostgreSQL あまり得意ではないから💦
- Heroku の無料枠にデプロイする予定もない
- Adminer
- 簡易MySQLGUIクライアント
- phpMyAdmin よりも機能が少なくて扱いやすい
- MySQL Workbench あれば別に使わなくても良いけどあったらあったで便利
- 使ってみてね
ローカル ruby で作業はしない
コンテナ立ち上げずにローカルruby使って "bundle install" とかすると楽なんですが
コンテナ立ち上げてる意味が(私は)ないと思ったのでそれはやらないことにします
なるべく Dockerfile を書きたくない
- ダルい
- 特殊なことをやってないないなら docker-compose から設定できるもので基本十分なはず
でも Rails サーバは Dockerfile を書く
Rails の公式imageは現在はなく、
標準 Ruby image を優先するとしてサポートされなくなっていますので、
Docker docks にあるように Dockerfile を書きます。ぴえん。
ruby のバージョンは2.6にしました。
ruby2.7は3.0previewへの移行対応が色々入っており、worning出るgemがそこそこあるみたい。
- rails | Docker Hub
- "This image is officially deprecated in favor of the standard ruby image"
- メンテコストがあるのはわかるけど世界中(?)で同じような Dockerfile 書いてるんだから用意してくれよォ〜
- じゃあ君がやれば? はい……すいませんやりません……
- https://hub.docker.com/_/rails
- ruby | Docker Hub
- Quickstart: Compose and Rails | Docker docs
手順
- rails new する用の Dockerfile を作成
- Dockerfile で使う forDocker/rails/entrypoint.sh を作成
- mysql 用の設定ファイルを作成
- Rails と MySQL のみの docker-compose.yml を作成
-
docker-compose run
してrails new
とか実施 - root ではないユーザを mysql に作成
- いったんコンテナ類を落とす
- nginx 用の設定ファイルを作成
- docker-compose.yml に Nginx, Adminer を追加
- 起動!
最終的に作成する設定ファイル類は以下です。それ以外は rails new
コマンドなどで生成されます。
- Dockerfile
- docker-compose.yml
- forDocker/mysql/conf.d/mysql.cnf
- forDocker/nginx/default.conf
- forDocker/rails/entrypoint.sh
最低限の状態で rails new をする
rails 用の Dockerfile を作成(あとで改変します)
FROM ruby:2.6
RUN set -x && curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN set -x && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list
RUN set -x && apt-get update -qq && apt-get install -yq nodejs yarn vim default-mysql-client
RUN mkdir /app
WORKDIR /app
# ※ここのコメントはあとで外す
# COPY Gemfile /app/Gemfile
# COPY Gemfile.lock /app/Gemfile.lock
# RUN bundle install
COPY . /app
# Add a script to be executed every time the container starts.
COPY ./forDocker/rails/entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
- Rails6.0以上はwebpackerが必要なので最新のyarnが入るように Dockerfile を書く必要があります
- Ruby:2.6 のdockerコンテナでrails6.0を入れようとしたらyarnがコケた | 北山淳也 | zenn
また、Dockerfile で指定している entrypoint.sh も作成しておきます。
forDocker/rails/entrypoint.sh
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
- Quickstart: Compose and Rails | Docker docs
mysql 用の設定ファイルを作成
forDocker/mysql/conf.d/mysql.cnf
[mysqld]
default_authentication_plugin = mysql_native_password
skip-host-cache
skip-name-resolve
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init-connect = SET NAMES utf8mb4
skip-character-set-client-handshake
[client]
default-character-set = utf8mb4
[mysqldump]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
mysql8.0 移行から認証形式が chacing_sha2_password
になっているので
mysql_native_password(パスワード認証)に変更してやるのを忘れないように
- RailsでMySQL8.0を使うときは認証形式に注意する | キャリアは日々のアウトプットの組み合わせ
- Docker で MySQL 8.0.4 を使う | Qiita
docker-compose.yml
version: '3.7'
services:
app:
container_name: app
build: .
tty: true
stdin_open: true
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
db:
image: mysql:8.0
container_name: db
restart: always
volumes:
- ./forDocker/mysql/conf.d:/etc/mysql/conf.d
- dbvol:/var/lib/mysql
ports:
- "3306:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 1
TZ: "Asia/Tokyo"
volumes:
dbvol:
- mysql | Docker Hub
この状態で docker-compose run --rm app bash
して db
に接続できてるか、
バージョンは 8.0 かを確認してみます。
Dockerfile を読んでもらうとわかるのですが、
apt-get install vim default-mysql-client
してるので
コンテナ内で vim
と mysql
コマンドが使えます。
docker-compose run --rm app bash
# bashログインできてもちょっと待つ(MySQLが立ち上がってくるのを待つ)
mysql -u root -h db -e 'select version();'
Enter password:
+-----------+
| version() |
+-----------+
| 8.0.22 |
+-----------+
mysql -u ユーザ名 -h ホスト -e "select 文とか"
- MYSQL_ALLOW_EMPTY_PASSWORD=1 してるので root にパスワードはないです
- (あまりよくはないが開発環境なので……)
- mysql コマンドオプション | Qiita
OK ですね。じゃあいったんbashを抜けます。
exit
docker-compose down
再度 --service-ports
つきで docker-compose run
して
app
の bash にログインします。
docker-compose run --rm --service-ports app bash
# Gemfile 作成
bundle init
# Rails を入れる
bundle add rails --version "~> 6.0"
# rails new
rails new . -d mysql --skip-test --force
# 依存ライブラリのインストール
bundle
yarn
rails webpacker:install
- rails6.0から webpacker が必要になったので yarn と webpacker が入っていないと起動しないです
- Rails6 開発時につまづきそうな webpacker, yarn 関係のエラーと解決方法 | Qiita
- Rails6 Webpackerでエラーが出た | Qiita
config/database.yml の編集
vim config/database.yml
config/database.yml
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
url: mysql2://root:@db:3306
# username: root
# password:
# host: localhost
config/database.yml の編集を行ったら、データベースの準備をしてrailsを起動してみます。
rails db:create
rails db:migrate
rails s -b "0.0.0.0"
いつものアレが表示されました
Ctrl-c でいったん停止します。
root 以外のユーザーを作成する
Adminer はパスワードなしユーザーでのログインに対応していないので
パスワードなしroot以外のユーザーを作成します。
上記までの作業で app コンテナに入ってるのでそのまま作業を続けましょう。
# mysql client に接続
mysql -u root -h db
# id user pass user のユーザーを作成
MySQL [(none)]> CREATE user 'user'@'%' IDENTIFIED BY 'user';
Query OK, 0 rows affected (0.054 sec)
# 権限を確認。作っただけなので USAGE でありなんの権限もない
MySQL [(none)]> SHOW GRANTS for 'user'@'%';
+----------------------------------+
| Grants for user@% |
+----------------------------------+
| GRANT USAGE ON *.* TO `user`@`%` |
+----------------------------------+
1 row in set (0.001 sec)
# user にフル権限を追加
MySQL [(none)]> GRANT ALL ON *.* TO 'user'@'%';
Query OK, 0 rows affected (0.025 sec)
# mysql client を抜ける
MySQL [(none)]> exit
Bye
- 【MySQL】Mysql2::Error::ConnectionError: Access denied for user ~への対処法【環境構築】 | Qiita
- ユーザーを作成する(CREATE USER文) | MySQLの使い方 | DBOnline
ではいったんコンテナから抜けて全てのコンテナを落とします
exit
docker-compose down
rails new 後の Dockerfile
bundle init
したことにより Gemfile などが生成されたので
rails(app) コンテナの Dockerfile のコメントを外します。
Dockerfile
FROM ruby:2.6
RUN set -x && curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN set -x && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list
RUN set -x && apt-get update -qq && apt-get install -yq nodejs yarn vim default-mysql-client
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
# Add a script to be executed every time the container starts.
COPY ./forDocker/rails/entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
設定ファイルの作成
mysql の設定ファイル forDocker/mysql/conf.d/mysql.cnf はもういじりません。
今度は Nginx も立ち上げるので設定ファイルを用意します。
forDocker/nginx/default.conf
upstream puma {
server app:3000;
}
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root /app/public;
location @puma {
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://puma;
}
location / {
try_files $uri @puma;
}
location ~ ^/(assets|packs)/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location = /favicon.ico {
access_log off;
log_not_found off;
}
location = /robots.txt {
access_log off;
log_not_found off;
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /500.html {
}
}
Nginx の設定ファイルはちょっと苦戦したんですがこちらにまとめました。
- docker-compose+Nginx+Rails6 で静的コンテンツをNginxから配信する | 北山淳也 | zenn
docker-compose.yml を完成させる
では docker-compose.yml に Nginx や Adminer を追加しましょう。
Rails 以外は Dockerfile なしでイケます。
docker-compose.yml
version: '3.7'
services:
web:
image: nginx:1.18
container_name: web
ports:
- "8080:80"
volumes:
- ./forDocker/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./public:/app/public
depends_on:
- app
app:
container_name: app
build: .
tty: true
stdin_open: true
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
db:
image: mysql:8.0
container_name: db
restart: always
volumes:
- ./forDocker/mysql/conf.d:/etc/mysql/conf.d
- dbvol:/var/lib/mysql
ports:
- "3306:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 1
TZ: "Asia/Tokyo"
adminer:
image: adminer:latest
container_name: adminer
ports:
- "9000:8080"
depends_on:
- db
volumes:
dbvol:
- ngninx | Docker Hub
- Adminer
- adminer | Docker Hub
config/webpacker.yml の編集
私はこれをやらないと app コンテナが起動しませんでした。
check_yarn_integrity: false # ここを true から false に変更する
- yarnが原因でdocker-compose up ができない ( Your Yarn packages are out of date!) | Qiita
実行
docker-compose up -d
Nginxがリバースプロキシしてくれるので今度からは
localhost:8080
へアクセスして動作確認します。見れたはずです。OKですね。
いつものアレが表示されましたはずです
Adminer を使ってみる
localhost:9000
で Adminer が待ち受けています。
先ほど作成した user アカウントでログインしてみます。
ログインするとこんな感じです。
左上の「DB」を選択(SELECTするならとりあえず app_development ですかね)し、
「SQLコマンド」をクリックします。
こんな感じでちょっとSELECT文打つぐらいなら便利に使えると思います。
コンテナを停止
docker-compose down
今回の手順が全て終わったリポジトリはこちらです。
その他の参考リンク
- とりあえずのdocker-compose upから入って、Web serverの基礎設計を学びながらDockerを学ぶ① | Naokit_dev | zenn
- Docker ComposeでRuby2.7+Rails6.0+MySQL8.0の環境を用意してrails newする | Qiita
- Dockerを使ってRails6環境の構築をしてみる | Qiita
- Rails newからproductionモードで動くようになるまで | Qiita
- 丁寧にNginx + MySql + Rails6 (Using Webpacker) on Dockerな開発環境を構築します。 | Qiita
Discussion