🍇

Rails7の開発環境(docker)を構築する

2022/03/21に公開3

概要

Rails7の開発環境構築手順
コンテナイメージを軽くするためrails newしたあと、Dockerfileを書き換える手順にしてます

構成

  • Docker version 20.10.13
  • Docker Compose version v2.3.3
  • ruby3.1.1
  • rails7.0.2
  • mysql8.0

ディレクトリ階層

プロジェクトルート
├── docker-compose.yml
├── web ・・・(Railsのroot)
│   ├── Dockerfile
│   ├── Gemfile
│   ├── Gemfile.lock
└── data

手順1: 新規プロジェクトを作成する

ソースコード

docker-compose.yml

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    command: --innodb-use-native-aio=0
    environment:
      MYSQL_ROOT_PASSWORD: password
      TZ: "Asia/Tokyo"
    ports:
      - "3306:3306"
    volumes:
      - ./data:/var/lib/mysql
  web:
    build: 
      context: web
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ./web:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

Dockerfile

web/Dockerfile
FROM ruby:3.1.1-alpine as builder

ENV ROOT="/app"
ENV LANG=C.UTF-8
ENV TZ=Asia/Tokyo

WORKDIR ${ROOT}

COPY Gemfile Gemfile.lock ${ROOT}

RUN apk add \
    alpine-sdk \
    build-base \
    sqlite-dev \
    mysql-client \
    mysql-dev \
    tzdata \
    git 

RUN gem install bundler
RUN bundle install

Gemfile

web/Gemfile
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.1.1"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.2", ">= 7.0.2.3"
web/Gemfile.lock
# (空ファイル)

コンテナをビルドする

$ cd プロジェクトルート
$ docker-compose build

rails newする

$ docker-compose run --rm web bundle exec rails _7.0.2_ new . -d mysql -f

webディレクトリにrailsファイルが一式生成されます。

手順2: コンテナイメージを軽量化する

Dockerfileを書き換えます。

web/Dockerfile
FROM ruby:3.1.1-alpine as builder

ENV ROOT="/app"
ENV LANG=C.UTF-8
ENV TZ=Asia/Tokyo

WORKDIR ${ROOT}

COPY Gemfile Gemfile.lock ${ROOT}

RUN apk add \
    alpine-sdk \
    build-base \
    sqlite-dev \
    mysql-client \
    mysql-dev \
    tzdata \
    git 

RUN gem install bundler
RUN bundle install

FROM ruby:3.1.1-alpine

ENV ROOT="/app"
ENV LANG=C.UTF-8
ENV TZ=Asia/Tokyo

RUN apk update && \
    apk add \
        mysql-dev \
        tzdata \
        bash

WORKDIR ${ROOT}

COPY --from=builder /usr/local/bundle /usr/local/bundle
COPY . ${ROOT}
COPY entrypoint.sh /usr/bin/

RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

マルチステージビルドしています。
前半のFROM ruby:3.1.1-alpine as builderステージはgemインストールのみに使用します。

https://matsuand.github.io/docs.docker.jp.onthefly/develop/develop-images/multistage-build/

entrypoint.shを作成する

web/entrypoint.sh
#!/bin/bash
set -e

rm -f /app/tmp/pids/server.pid
exec "$@"

コンテナイメージ再ビルドする

$ docker-compose build

出来上がったコンテナサイズは171MBです。

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED             SIZE
test_web     latest    5afcfb48984a   5 seconds ago       171MB

手順3: rails を起動する

database.ymlを編集する

web/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
-  password: 
-  host: localhost
+  password: password
+  host: db

DBを作成する

$ docker-compose run --rm  web rails db:create 

コンテナを起動する

$ docker-compose up -d

http://localhost:3000にアクセスする

画面が表示されれば成功です。

以上

参考サイト

https://zenn.dev/tatsurom/articles/multi-stage-build
https://zenn.dev/hukurouo/articles/rails-alpine

Discussion

大学生だった.大学生だった.

コメント失礼します。

exec "$@"

"$@" 全部の引数を個別として処理とあるのでここにあるのを実行するのはなんとなく理解できるのですが、ここには何が入ってくるのでしょうか?

やまだのぶひこやまだのぶひこ

Dockerfileにて ENTRYPOINTCMD を組み合わせて指定すると、
ENTRYPOINT部がコマンドとして実行され、CMD部がそのコマンドの引数になります。

今回Dockerfileでは次のように指定しています。

CMD ["rails", "server", "-b", "0.0.0.0"]

結果として、$@にはこの4つの文字列が格納されています。

masamasa

これではCSSもJSもビルドできませんね。。。