DockerでRailsAPI + React(PostgreSQL)環境を作る!
はじめに
usconsort.com
今回はこの記事を参考に、自分なりに改造しながら作って行きました。
Dockerを勉強しているとわからない単語やプロパティがたくさん出てきますが、横着せずに全部理解しながら進めましょう。
- 1. ファイル構成
- 2. docker-compose.ymlの作成
- 3. apiのDockerfileの作成
- 4. entrypoint.shの作成
- 5. frontのDockerfile作成
- 6. 環境をbuild
1. ファイル構成
今回は以下のようなファイル構成にします。
- api ↓
Dockerfile
entrypoint.sh
Gemfile
Gemfile.lock
- front↓
Dockerfile
- docker-compose.yml
(なんかうまいことファイル構成を表現する方法って無いんですかね、、、)
2. docker-compose.ymlの作成
以下のようなプログラムを書きます。
version: '3.9' services: db: #データベースイメージを定義 image: postgres # postgresのイメージを使用 volumes: - ./docker/db/data:/var/lib/postgresql/data # データのマウント場所を指定 environment: POSTGRES_PASSWORD: password # passwordを設定 api: build: context: ./api/ # ./api/ の下のDockerfileを読み込み。 dockerfile: Dockerfile command: sh -c "rm -f /api/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" # コンテナ立ち上げのたびに実行するコマンドを定義 volumes: - ./api:/api - ./api/vendor/bundle:/api/vendor/bundle ports: - '3000:3000' depends_on: - db # 実行順を指定 front: build: context: ./front/ dockerfile: Dockerfile volumes: - ./front:/usr/src/app command: sh -c "cd reactapp && yarn start" ports: - '8000:3000' volumes: postgresql_db: driver: local
特に変わったことは書いていないので説明は省略させて頂きます。
3. apiのDockerfileの作成
api側のDockerfileを作って行きます。
今回は以下のようなコマンドを書きました。
# syntax=docker/dockerfile:1 FROM ruby:2.5 RUN apt-get update -qq && apt-get install -y nodejs postgresql-client RUN mkdir /api WORKDIR /api # コマンドの実行ディレクトリを移動。 COPY Gemfile /api/Gemfile COPY Gemfile.lock /api/Gemfile.lock RUN bundle install # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 # Configure the main process to run when running the image CMD ["rails", "server", "-b", "0.0.0.0"]
WORKDIRで指定した/apiというのはdockerのイメージ内のパスで、指定できるパスはdocker-compose.ymlで定義した
volumes: - ./api:/api - ./api/vendor/bundle:/api/vendor/bundle
ここから確認できます。
その他Dockerfile内のパスは全てイメージのパスを指しており、ローカルコンピューターのパスをしても動かない。
4. entrypoint.shの作成
entrypoint.shを作成して以下のように記述します。
#!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /api/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@"
主にやっていることとしては、不要なファイルを削除するということと、コマンドライン上でエラーが起きたときにすぐ実行を中止すること。それとentrypointの処理が終わってからコマンドラインの入力を受け付けること。(多分)
https://stackoverflow.com/questions/39082768/what-does-set-e-and-exec-do-for-docker-entrypoint-scripts
5. frontのDockerfile作成
frontのDockefileに以下のように記述。
FROM node:17.5-alpine WORKDIR /usr/src/app
6. 環境をbuild
まずはrails側の環境をを以下のコマンドで構築。
docker-compose run api rails new . --api --database=postgresql
次に、React環境を作成。
docker-compose run --rm front sh -c "npm install -g create-react-app && create-react-app reactapp"
ここで一旦build。
docker-compose build
Railsとデータベースを繋げるためにapiのconfig/database.ymlを編集。
default: &default adapter: postgresql encoding: unicode host: db username: postgres password: password # docker-compose.ymlで設定したパスワード # For details on connection pooling, see Rails configuration guide # http://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
こんな感じ。
一旦コンテナを立ち上げ。
docker-compose up
最後にRails側のデータベースを作成。
docker-compose exec api bash rails db:create
出来たっぽい。
データベースとRailsがつながらなかったり、volumeの概念の理解に苦しんだり、ここまで来るのに色々ありましたが完成したんでとりあえず上出来だと思います。次はこれをVPSで実行できるか試してみようと思います。