はじめに
dockerとdocker-composeを使って既存のRails+PostgreSQLのプロジェクトをdocker化したので、備忘録として手順をまとめます。
作業環境
- M1Mac メモリ8GB
Dockerfileを用意する
Dockerコンテナを起動するためにはDockerImageの作成が必要になります。
DockerImageを作るために、Dockerfileを用意します。
ちなみに。
Dockerコンテナ:オブジェクト指向的に言えばインスタンス
DockerImage:Dockerコンテナの元となるもの(オブジェクト指向的に言えばクラス)
Dockerfile:DockerImageの設計書のようなもの
Rails用の Dockerfileを下記の通り用意しました。
FROM ruby:3.2.2
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y yarn
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp
FROM
でDockerImageの元となるImageを指定します。
RUN
でbuild
時に実行する内容を指定します。ここではRails起動のために必要な各パッケージのインストールを行っています。
Railsを動かすために必要なものはRuby,Yarn,PostgreSQL(デフォルトはSQLiteですが今回は変更しています。)
なので、
- RubyのDockerImageを元に生成
- Yarnをインストール
といった流れで進めました。(PostgreSQLは別のコンテナで用意したため含めてません)
今回のバージョンはRuby3.2.2,Rails7.0.6で実行したため上記のパッケージでしたが、バージョンによってこの辺りは差異があるので注意が必要です。
(Nodejsが必要だと思っていたけどこのバージョンだといらないっぽいですね)
WORKDIR
で作業ディレクトリの指定を行います。ルート直下のmyappディレクトリを指定しています(ないのでmkdirでディレクトリを作成しています)。
ADD
コマンドではDockerImageを作る際に、ホストからファイルをコピーします。COPY
でも同じ役割を果たすコマンドですがADD
では圧縮したtarファイルを展開してコピーを行ってくれます。
(上記のDockerfileはtarファイルがないのでCOPYでも良かったかもしれない)
新しくRailsのプロジェクトを作る場合には必要なファイルなどを生成する必要があるため、下記のコマンドを実行します(今回は既存プロジェクトだったため、省略しました。)
$ docker-compose run web rails new . --force --database=postgresql
docker-compose.ymlを作成する
Dockerの考えとして、1コンテナで1サービスが基本とのこと。
そのため、今回 RailsとPostgreSQLのコンテナをそれぞれ用意します。
複数コンテナを効率的に作成、起動するために、docker-composeを利用しますが、そのためのdocker-compose.ymlを以下のように記述します。
version: '3'
volumes:
data-base:
services:
db:
image: postgres:12
environment:
- 'POSTGRES_PASSWORD=password'
volumes:
- './data-base:/var/lib/postgresql/data'
web:
platform: linux/arm64/v8
build: .
environment:
- 'DATABASE_PASSWORD=password'
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
links:
- db
commandで複数のコマンドを指定したい場合には、bash -c ""でコマンドを囲うと実行できます。
今回は練習用だったので上記のようにDB接続用パスワードを記載していますが実際には他の方法で管理した方が良いかもしれません
ビルドを行う
以下のコマンドを行って、ビルドを行います
$ docker-compose build
DBの設定を変更する
DB接続用のユーザー名などの設定を変更します。
以下の内容を config/database.yml に記述していきます。
- RailsはデフォルトでSQLiteを利用する設定になっているため、一緒に作成したDBコンテナ(今回だとPostgreSQL)を利用するように記述
- 接続用ユーザー名、パスワードの設定
default: &default
adapter: postgresql
encoding: unicode
# 以下を追加
host: db
username: postgres
password: <%= ENV["POSTGRES_PASSWORD"] %>
パスワードなど機密情報に当たるものなどは直接記述するのではなく環境変数などを利用しましょう。
コンテナを起動する
$ docker-compose up
Rails用のコンテナとPostgreSQLのコンテナが起動します。
しかし、この時点ではDBが生成されていないため、localhost:3000にアクセスしてもエラーになります。なので以下のコマンドでDB生成を行います。
$ docker-compose run web rake db:create
DBが生成できたら再度以下のコマンドを実行します。
$ docker-compose up
「PendingMigrationError」といったエラーが出る場合には、マイグレートが保留になっているためマイグレートを行います。
$ docker-compose run web rake db:migrate
再度起動コマンドを実行。
$ docker-compose up
無事に起動できました
参考文献