Docker-composeを使って初めてRails+PostgreSQLの環境構築したときのメモです。
Dockerfile作成
$ mkdir product-register && cd product-register
$ touch Dockerfile Gemfile Gemfile.lock
FROM ruby:2.5
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
postgresql-client \
yarn
WORKDIR /product-register
COPY Gemfile Gemfile.lock /product-register/
RUN bundle install
source 'https://rubygems.org'
gem 'rails', '~>5.2'
GemfileをDockerfileでCOPYすることでRailsをインストールします。
$ docker build .
Docker-composeを使う
どんな時に使うのか?
-
$ docker run
のコマンドが長くなる時
今回もしこのまま$ docker run
をするならコマンドは、以下のように長くなるので使用。
$ docker run -it -v ~/Desktop/product-register:/product-register -p 3000:3000 <image> bash
- 複数のコンテナをまとめて起動する時。
今回はRailsのコンテナとPostgreのコンテナを使うので使用。
docker-compose.ymlの使い方と書き方
-
docker-compose.yml
というファイルを作りそこに$ docker run
時のオプションコマンドなどを書いて設定しておく。
今からDocker compose書くよ宣言
service1:
service1のパラメータ
service1のパラメータ
service2
service2のパラメータ
service2のパラメータ
-
kye:value
の組み合わせで書く。 - value部分が複数ある場合は
-
を使ってリスト形式 - docker-composeでのパスの指定は相対パスで書く。
docker-compose.yml
version: "3"
services:
web:
build: .
ports:
- "3000:3000"
volumes:
- ".:/product-register"
tty: true
stdin_open: true
-
build
は$ docker build .
-
ports
は-p
オプション -
volumes
は-v
オプション -
tty
とstdin_open
は-it
オプション
Docker composeコマンド一覧
$ docker build <build context>
$ docker-compose build
$ docker run <image>
$ docker-compose up
$ docker-compose up --build
up
はimageが作られてない場合、build
も一緒にする。
Dockerfileを更新した場合は-- build
をつけることでbuild
してからrun
してくれるのでimageも更新される。
$ docker ps
$ docker-compose ps
$ docker exec <container> <command>
$ docker-compose exec <service> <command>
- 便利コマンド
$ docker-compose down
コンテナをstopしてから消してくれる。
実際に起動してみる。
バックグラウンドで動かしたいので-d
オプションをつける
$ docker-compose up -d
$ docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
product-register-web-1 "irb" web running 0.0.0.0:3000->3000/tcp
起動が確認できたので実際にコンテナに入ってみる。
$ docker-compose exec web bash
root@8d2ab4ae68c0:/product-register#
入れてたらOK
Railsセットアップ
コンテナ内で実行します。
$ rails new . --force --database=postgresql --skip-bundle
--force
は全て上書き --database
でデータベースの指定 --skip
でbundle install
をskipしています。
bundle install
をskipしている理由は、Dockerfileの最後にRUN
でbundle install
を指定していて、Gemfileが更新されたらその都度コンテナを抜けて再度コンテナをbuildするのでbundle install
をわざわざここでする必要はないからです。
コンテナを抜けコンテナを削除します。
$ exit
$ docker-compose down
再度build
して確認します。
$ docker-compose up --build -d
$ docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
product-register-web-1 "irb" web running 0.0.0.0:3000->3000/tcp
buildされていたらOKです。
docker-compose.ymlのDB部分を追記する
DBはDB用のコンテナを作るのでDBの設定を記述していきます。
default: &default
adapter: postgresql
encoding: unicode
host: db
user: postgres
port: 5432
password: <%= ENV.fetch("DATABASE_PASSWORD") %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host
で指定した名前(今回はdb)がdocker-compose.ymlのservice
部分になります。
version: "3"
volumes:
db-data:
services:
web:
build: .
ports:
- "3000:3000"
volumes:
- ".:/product-register"
environment:
- "DATABASE_PASSWORD=postgres"
tty: true
stdin_open: true
depends_on:
- db
links:
- db
db:
image: postgres
volumes:
- "db-data:/var/lib/postgresql/data"
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=postgres"
volumes
の部分はデータベースで保存したものをhost側で保管するための記述。
environment
は環境変数。
depends_on
で指定したものができてから$ docker run
するという記述。
links
はここで指定したものがwebからアクセスできるようにするための記述。
RailsとDBをセットアップ
Docker composeでそれぞれのコンテナを立ち上げRailsのコンテナに入ります。
$ docker-compose up -d
$ docker-compose exec web bash
入ったコンテナ内でDBを作成します。
$ rails db:create
$ rails s -b 0.0.0.0
サーバーを立ち上げていつものRailsの最初の画面が出たら完成。
参考