新しくRailsのアプリケーションを作って書いた。データベースはPostgeSQLを使う想定。 GitHub - ikaruga777/taskleaf実際にdockernizeしたものはこちら。(現場Rails本のサンプルアプリケーションを使った)
Quickstart: Compose and Rails | Docker Documentation ココらへんを参考にした。
Dockerfileを作る
FROM ruby:2.6.3 RUN apt-get update -qq \ && apt-get install -y postgresql-client \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* ENV LANG=C.UTF-8 \ TZ=Asia/Tokyo \ APP_HOME=/usr/src/app WORKDIR $APP_HOME COPY Gemfile* $APP_HOME/ RUN bundle install COPY . $APP_HOME/
RUN命令でDockerfileのImageに対してコマンドを実行する。
RUN apt-get update -qq \ && apt-get install -y postgresql-client \ && apt-get clean
apt-get updateの-qqオプションはエラー以外を出力しないもの。- postgresqlもDocker Imageで用意するけど、Railsアプリ自体に接続するためのクライアントが入っていないので、
apt-get install -y postgresql-clientでインストール - 最後に apt-get cleanで一時ファイルなどを削除する
ENV命令は環境変数を設定できる。
今回は文字コード、タイムゾーン、アプリケーションのルートディレクトリを設定した。
WORKDIR命令はアプリケーションの作業ディレクトリを設定できる。設定したディレクトリが存在しない場合は自動で作成される。
Dockerfile リファレンス — Docker-docs-ja 17.06.Beta ドキュメント
COPY命令はローカルファイルをコンテナファイルにコピーする。 ローカルのカレントディレクトリのGemfile*をコピーしてbundle installを実行後、残りのディレクトリをごそっとコピーするようにした。Quick guildeでは /myappとかルートディレクトリからディレクトリを生やしていたので、とりあえずusr/src/で作業するようにした。
これでカレントディレクトリのRailsアプリケーションを実行するためのコンテナの作成はOK
docker-compose.ymlを作る
Railsのプロセスが動くコンテナはできたので、docker-composeでその他のコンテナを集めて、実行環境を作っていく。
version: '3'
services:
db:
image: postgres:11.2
environment:
POSTGRES_PASSWORD: postgres
ports:
- '5432:5432'
volumes:
- postgres-data:/var/lib/postgresql/data
app: &app_base
build: .
command: /bin/sh -c "rm -f ./tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
ports:
- '3000:3000'
volumes:
- .:/usr/src/app
environment:
RAILS_ENV: development
depends_on:
- db
spring:
<<: *app_base
command: bin/spring server
ports: []
volumes:
postgres-data:
postgresと上で作成した、Appコンテナ、springサーバーを起動するためのサービスを定義する。
db Service
PostgreSQLのコンテナpostgres:11.2 は POSTGRES_PASSWORD環境変数でデータベースパスワードを設定できる。そのまま、5432番ポートでつながるようにマッピング。
postgres-dataというボリュームをファイルの下の volumes:で定義しているので、postgresのデータをそのままボリュームに指定する。/var/lib/postgresql/dataがデータを保存するディレクトリだということはDocker Hubのページから確認できる。
app Service
docker-compose buildコマンドでDockerfileの内容でbuildされる。
起動時には bundle exec railsの前に rm -f ./tmp/pids/server.pidを実行している。これはdocker-compose killを実行したときにファイルが残って、次回起動時にエラーになっちゃうから。
spring Service
docker-compose upしたあとにappコンテナ内でRailsのコマンドを効率的よく実行したいので、springをdocker-compose execコマンドで呼べるようにしている。
高速に開発できる Docker + Rails開発環境のテンプレートを作った - Qiita ここ眺めて、<<がdocker-compose.ymlの記法に見当たらないと思ってさまよっていたんだけど、YAMLの記法だった。&fooでハッシュに名前をつけれて、<<: *fooでその内容をそのまま展開できる。これで同じコンテナで違うcommandを持つserviceが作成できる。
database.ymlの設定を変える
config/database.ymlの内容をdockerのpostgresで使えるように設定する。
- hostにはdocker-compose.ymlに記載したサービスdbを指定する
- user、passwordには postgresを設定する。
- userはpostgresコンテナのデフォルト、passwordはdocker-compose.ymlで指定した環境変数POSTGRES_PASSWORDを設定する。
ここまで書けば、
docker-compose builddocker-compose up
でRailsのアプリケーションがDockerコンテナで実行できる。
改善
読み返すと甘いところもあって
/vendor/bundleをvolumeに外出しできそう- nodeをインストールするのがだるくて、
mini-racerをインストールしてたりするけどどっちがいいのか迷ってる - そもそもAPPコンテナの容量が1.2Gとかあるので、削減できそう
などなど改善できそうなので、やっていこうと思う。