Rails7をdocker-composeで構築しproductionモードで起動させてみる

# 概要
Rails7をdocker-composeからDockerfileを読み込んでデプロイ。
DBコンテナとともに起動させます。
ありきたりなので目新しいものがないですがrails new時にパーミッションエラーが
出たので自分なりに悪戦苦闘していました。



# 環境
ubuntu 20.0.4
docker-compose v2.2.3(Go版)
ruby 3.1.2p20
rails 7.0.3

docker-composeはGo実装のものですね。
すでにどのサイトの導入手順でも成功すると思いますので今回は省略します。
自分の環境では古いものを一度消してまっさら状態でないと失敗しました。

Dockerfileを配置するパスをカレントとし、以下ファイルを配置する。
・Dockerfile
・docker-compose.yml
・Gemfile
・Gemfile.lock


`Dockerfile`
```
FROM ruby:3.1.2

ARG UID=1000
ARG GID=1000

RUN groupadd -g $GID rails
RUN useradd -u $UID -g rails -m rails
RUN echo "rails ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn

RUN apt-get update -qq && apt-get install -y \
build-essential \
libpq-dev \ #(postgresqlの場合)
default-mysql-client \ #(mariadbの場合)
shared-mime-info \ #(有無で試しましたが問題なしか)
vim \
graphviz \ #(グラフィカルツール用)
locales \
locales-all \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /tmp
COPY Gemfile /tmp/Gemfile
COPY Gemfile.lock /tmp/Gemfile.lock

RUN gem update --system
RUN gem install bundler
RUN bundle install
RUN chown -R rails:rails /usr/local/bundle

RUN rm -f /tmp/Gemfile
RUN rm -f /tmp/Gemfile.lock

COPY ./work7 /work7

USER rails

RUN echo "alias ll='ls -la --color=tty'" >> /home/rails/.bashrc

WORKDIR /work7
```

`docker-compose.yml`
```
version: '3'
services:
  db:
    image: mariadb:10.7.3   #このバージョンを最近使っているのでここでも
    environment:
      MYSQL_ROOT_PASSWORD: rails
    ports:
      - "3306:3306"
    volumes:
      - ./mariadb:/var/lib/mysql   #永続ボリュームとしてコンテナ側の/var/lib/mysqlとローカル側の/mariadbとミラーさせる
    user: 0:0
  rails:
    build: .   #ローカルのDockerfileをビルド
    command: /bin/sh
    environment:
      RAILS_SERVE_STATIC_FILES: "1"   #ファイルの存在を明示化しておく
      EDITOR: "vim"
    volumes:
      - ./work7:/work7   #dbと同様にミラーさせる
    ports:
      - "3000:3000"
    depends_on:
      - db
    tty: true
    stdin_open: true
```

`Gemfile`
```
source 'https://rubygems.org'
gem 'rails', '>= 7.0.0','< 8.0.0'
```
`Genfile.lock`
```
空
```



# コンテナ起動
`$ docker compose up -d`

#コンテナにログイン
`$ docker compose exec rails bash`   #railsコンテナにログインします※１
`$ docker compose exec db bash`   #dbコンテナにログインし、mysqlコマンド等で作業可能

# rails new
※１のrailsコンテナにログイン後、projectという名前でプロジェクト作成。
ついでにtailwindも入れました。
`$ rails new project -d mysql -T -j esbuild --css tailwind`

ここで、`「Issue "build" not found"」`が出ます。
カレントの`package.json`に以下のようにログで表示された`"scripts"`内容を追記します。

`package.json`
```
{
  "name": "app",
  "private": "true",
  "dependencies": {
    "@hotwired/stimulus": "^3.0.1",
    "@hotwired/turbo-rails": "^7.1.3",
    "autoprefixer": "^10.4.7",
    "esbuild": "^0.14.39",
    "postcss": "^8.4.14",
    "tailwindcss": "^3.0.24"
  },
  "scripts": {
    "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
    "build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify"
  }
}
```
以下実行、
`$ yarn build`
`$ yarn build:css`
エラーメッセージでもなく警告でもなく、JSビルド関連選択の関係上こうなっているのかな？！

一旦ここで（bundle後だけど変化あるか確認）
`$ bundle install`   #不要だとは思うが
`app/assets`配下の生成ファイルを確認しておく。
試しに`scaffold`してみます。
`$ rails g scaffold Shop name:string description:text price:integer`
`$ rails db:create RAILS_ENV=production`
`$ rails db:migrate RAILS_ENV=production`
`$ rails assets:precompile RAILS_ENV=production`
まだこのコマンドが使用できました。
`public/assets`配下に生成されるファイル群とログを見ると何をやっていて今後どう進んでゆくかを考えてみるのもいいかもですね。
`$ rails s -e p`
起動しました。
`config/routes`に追加されたURLでアクセスします。
（ちなみに本環境で静的ファイルはAPIgatewayとなるリバースプロキシに置いています。）

# まとめ
Rails7をdocker-composeでデプロイしproductionモードで起動させてみました。
この後、比較的重めのmodelを多く作成し大量のデータ投入してテストしましたが問題なく動作しました。
完全移行ではないけれど移行も念頭においてもいいのかもしれません。
Tailwindのテストとしては、
htmlタグのclassに単一プロパティのハイフン列挙の思想で記述すると普通に反映されました。（ここら辺は現在奮闘中です）

`他コマンド`
コンテナ作り直しとかする際によく使ってるコマンドです。
`$ docker compose down --rmi local -v`   #コンテナ削除
`$ docker system prune`   #作成されたネットワークタスクなども削除
`$ docker images`   #不要なimageを選択し削除
などなど

# 参考
DHH氏のサイト&動画など、他