最終的なフォルダ構成
myapp/
|--docker-compose.yml
|--apache/
|--html/
|--rails/
|--app/
|--bin/
|--config/
|--db/
|--lib/
|--log/
|--public/
|--storage/
|--test/
|--tmp/
|--vendor/
|--config.ru
|--Dockerfile
|--entrypoint.sh
|--Gemfile
|--Gemfile.lock
|--Rakefile
|--README.md
|--.env
|--.gitignore
|--.git
.git
Gitの初期化を行う
git init
.gitignore
- Gitの管理下に置きたくないファイルやディレクトリを管理するためのファイル
/.env
.env
- 環境変数を管理するために使われるファイル
# commons
WORKDIR=app
CONTAINER_PORT=3000
RAILS_PORT=3000
APACHE_PORT=8080
# db
# POSTGRES_PASSWORD=password
docker-compose.yml
まずプロジェクトフォルダを作成し、そこにrailisフォルダ、apacheフォルダとdockercompose.ymlファイルを作成する。
version: '3.8'
services:
apache:
image: httpd:alpine
container_name: apache
volumes:
- ./apache/html:/usr/local/apache2/htdocs
# httpdイメージでは80番ポートを公開している
ports:
- "$APACHE_PORT:80"
depends_on:
- rails
# railイメージを構築、railsコンテナを構築、起動
rails:
# railsフォルダの中にあるDockerfileをビルド
build:
context: ./rails
# Dockerイメージをビルドする際にDockerfileに渡す値を指定
args:
WORKDIR: $WORKDIR
container_name: rails
environment:
# rack-corsで使用する
ACCESS_CONTROL_ALLOW_ORIGIN: "localhost:$APACHE_PORT"
# サーバの起動フラッグを削除(起動されていると勘違いしてしまわないように)
# ポートを$CONTAINER_PORTとしてサーバ起動(Dockerfile内でも起動しているが)
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p $CONTAINER_PORT -b '0.0.0.0'"
# コンテナ中のappフォルダをローカルのappフォルダに結びつける(コンテナを起動する際にホストマシン上のデータがコンテナにマウントされる)
volumes:
- ./rails:/$WORKDIR
# コンテナのポートとホストのポートを対応付ける
ports:
- "$RAILS_PORT:$CONTAINER_PORT"
# attachに必要,ターミナルの入出力がコンテナのbashとつながる?,attachしないとブラウザは一生読み込み中に
stdin_open: true
# これがないとattachしてもすぐ切れてしまう?
tty: true
CORSの設定
- CORSとは、異なるオリジン感の通信を許可する仕組み
- Gemのインストール
- railsディレクトリのGemfileを開く
- 26行目付近の
gem 'rack-cors'
のコメントを外す - Dockerイメージを再ビルド
- 設定ファイルの編集
-
api/config/initializers直下にあるcors.rbが設定ファイル
-
下記のように編集
cors.rb# Be sure to restart your server when you modify this file. # Avoid CORS issues when API is called from the frontend app. # Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests. # Read more: https://github.com/cyu/rack-cors Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do # docker-compose.ymlで指定した値かその値がNullの場合は、空文字を入れる(エラーにならないように) origins ENV["ACCESS_CONTROL_ALLOW_ORIGIN"] || "" # 許可したいリソースファイル resource '*', headers: :any, # getのみ許可 methods: [:get] end end
-
- Gemのインストール
Dockerfile
railsイメージはDockerfileから作成するためDockerfileとentrypoint.shをrailsフォルダの下に作成する。
myapp/
|--docker-compose.yml
|--apache/
|--rails/
|--Dockerfile
|--entrypoint.sh
FROM ruby:2.7.2
RUN apt update -qq && \
apt install -y build-essential \
libpq-dev
# Dockerfile内で使用する変数名を指定
ARG WORKDIR
ENV APP_ROOT /$WORKDIR
RUN mkdir $APP_ROOT
WORKDIR $APP_ROOT
# このファイル(Dockerfile)と同じ階層にあるGemfile等をコンテナにコピー
COPY ./Gemfile $APP_ROOT/Gemfile
COPY ./Gemfile.lock $APP_ROOT/Gemfile.lock
# コンテナのGemfileを参考にGemをインストール
RUN bundle install
# このファイルが含まれているディレクトリをコンテナのルートディレクトリにコピー
COPY . $APP_ROOT
COPY ./entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
CMD ["rails", "server", "-b", "0.0.0.0"]
# !/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 "$@"
GemfileとGemfile.lock
myapp/
|--docker-compose.yml
|--apache/
|--rails/
|--Dockerfile
|--entrypoint.sh
|--Gemfile
|--Gemfile.lock
source 'https://rubygems.org'
gem 'rails', '6.0.0'
GemfileはRubyのライブラリをまとめたもので、Dockerfile内のbundle install
ではこのファイルを元にgemたちをインストールしている。
Gemfile.lockはGemfileをもとに実際にインストールされたgemの一覧とバージョンが記載されたファイルで、ここでは空のファイルを作成しておく。
イメージの構築、コンテナの作成・起動
ここまででとりあえず必要なファイルが揃ったので、イメージの構築等を行っていく。
rails new —api
rails new
はrailsアプリケーションの雛形を作成してくれるコマンドで、railsサーバを立ち上げるのに必要なgem等を作成してくれる。今回railsはAPIサーバとして用いるためAPIモードでアプリを作成するように--api
をオプションとして付けている。
docker-compose run rails rails new . --api --force --skip-bundle
docker-compose run
は引数で指定したサービスについて、イメージの構築から、コンテナの作成・起動までを行ってくれるコマンドで、それプラスサービス名の後にコマンドを打つとコンテナ内で実行してくれる。
ここではサービスにDockerfileで指定したrails:を指定しており、プラスアルファのコマンドとしてrails new .
を行っている。
--force
は既存のGemfileを上書きするためのオプションである。
後で、イメージを構築する際にbundle install
は行われるので、ここでは--skip-bundle
としている。
イメージの構築
docker-compose build
このとき、Dockerfileよりrailsのイメージが作成される。
コンテナの作成・起動
docker-compose up
httpdのイメージはこのときに、Docker Hubからローカルに持ってきている。
localhost:8080でapache/html
にアクセスできる。localhost:3000でrailsサーバにアクセスできる。
補足
docker-compose build
でbundle install
は行われるが、volumeとは紐付かないらしく、コンテナを起動する際にエラーが出る恐れがある。そのときは、volumeと紐づけられるrun
コマンドを実行する。
$ docker-compose run rails bundle install
または、rails new
で--skip-bundle
を付けなければ問題ない。
Docker Compose + Railsでイメージ内でbundle installしているはずなのにgemが無いとエラーがでる。 - Qiita
参考
DockerインストールからRails + Docker + MySQLで環境構築までの手順
【Mac編】DockerでRuby on Railsの開発環境を作ってみよう
Docker ComposeでNode.jsの環境構築 - Qiita
Rails6・Nuxt.js・PostgreSQLを動かすdocker-compose.ymlファイルを作成する - 独学プログラマ