Rails8
Rails4ごろから使ってきて、既に5世代目。
最近の開発ではRailsはバックエンドapiでしか使用していないが、Active RecordやActive Modelは便利だし、今後もRailsは使っていくと思う。
apiモード
ということでRailsはフロントエンドからjsonが取得できればそれでいい。Rails8のapiモードで何をskipすればいいのかを検証してみた。
前準備
- projectディレクトリを作成し、compose.yamlを作成
mkdir project
cd project && touch compose.yaml
- backendディレクトリを作成し、更に配下にapiディレクトリを作成
mkdir backend && mkdir backend/api
- 必要ファイル(Dockerfile,Gemfile,Gemfile.lock)作成
cd backend && touch {Dockerfile,Gemfile,Gemfile.lock}
この時点でのディレクトリ構成
project/
├── backend/
│ ├── Dockerfile
│ ├── Gemfile
│ ├── Gemfile.lock
│ └── api/
└── compose.yaml
- Dockerfile
FROM ruby:3.3.0
ENV APP /api
ENV TZ Asia/Tokyo
WORKDIR $APP
ADD Gemfile $APP/Gemfile
ADD Gemfile.lock $APP/Gemfile.lock
RUN bundle install
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
- Gemfile
source 'https://rubygems.org'
gem "rails", "~> 8.0.0"
- compose.yaml
services:
apitest:
build: ./backend/
platform: linux/x86_64
environment:
TZ: Asia/Tokyo
volumes:
- type: bind
source: ./backend/api
target: /api
- type: volume
source: gemdata
target: /usr/local/bundle
ports:
- "3000:3000"
volumes:
gemdata:
ノーマルのrails new --api(--skipオプションをつけない)
まずはノーマルのapiモードでrails newしてみる
docker compose run --rm apitest rails new . --api
ずらずらずら
[+] Creating 2/0
✔ Network apitest_default Created 0.1s
✔ Volume "apitest_gemdata" Created 0.0s
[+] Building 68.6s (11/11) FINISHED docker:orbstack
=> [apitest internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 230B 0.0s
=> [apitest internal] load metadata for docker.io/library/ruby:3.3.0 12.9s
=> [apitest internal] load .dockerignore 0.0s
=> => transferring context: 2B
####以下略#####
api以下にrails8のファイルが作成された。
この状態でrailsを起動
docker compose up -d
Rails8が起動した!DBの設定をしなくとも起動するようだ。
気になるのはdatabase.yml
何もskipしない状態のapiモードだと、database.ymlにはcacheやqueue、cableのDB設定の項目がある。
####前略########
# Store production database in the storage/ directory, which by default
# is mounted as a persistent Docker volume in config/deploy.yml.
production:
primary:
<<: *default
database: storage/production.sqlite3
cache:
<<: *default
database: storage/production_cache.sqlite3
migrations_paths: db/cache_migrate
queue:
<<: *default
database: storage/production_queue.sqlite3
migrations_paths: db/queue_migrate
cable:
<<: *default
database: storage/production_cable.sqlite3
migrations_paths: db/cable_migrate
スキップする前にRails8の各機能について
おさらいの意味も含めて、rails newのskipコマンドを見てみて、要否の判断をしてみる。
skipしてもよさそう
- --skip-docker
Skip Dockerfile, .dockerignore and bin/docker-entrypoint
→ Dockerで構築しているのに、更にDockefileを作る。不要 - --skip-action-mailer
- --skip-action-mailbox
- --skip-action-text
→ Action Mailer,Action Mailbox,Action Textは使用しない - --skip-active-job
- --skip-action-cable
→ activejob(queue機能)は使用しない
→ activecable(websocket通信)は使用しない - --skip-asset-pipeline
→ apiモードではアセットは使用しない - --skip-javascript
→ apiモードではjavascriptは使用しない - --skip-hotwire
→ 他のフロントエンドフレームワークReact、Vue.js、Angularなど、別のJavaScriptフレームワークやライブラリを使用してインタラクティブなUIを作成する場合、Hotwireは不要 - --skip-jbuilder
→ apiはjsonを返すので一見必要そうに見えるが、render jsonを返す場合は必要なし - --skip-test
→ キリッ - --skip-system-test
→ APIでシステムテストはしないため不要 - --skip-thruster
→ HTTP/2プロキシ「Thruster」APIモードには不要 - --skip-rubocop
→ rubyコードの静的チェック。不要 - --skip-brakeman
→ Brakemanとはソースコードに、SQLインジェクションやXSS等の脆弱性がないかを解析してくれるGem。不要 - --skip-ci
→ GitHub CI filesを生成しない - --skip-kamal
- --skip-solid
→ Rails8の機能であるkamalもSolid Cache,Queue,Cableも必要ない - --skip-devcontainer
→ devcontainerは使用しない - --skip-edge
→ 最新の Rails 開発版を使用して作成するためのもの。不要 - --skip-main
→ gitのmainブランチをGemfileにむにゃむにゃ(よくわからんが不要)
skipしない方がよさそう
- --skip-git
Skip git init, .gitignore and .gitattributes
→ git関連のファイルを作成しない。あったほうがいい - --skip-keeps
Skip source control .keep files
→ .keepファイルは空のディレクトリの中に配置されて、空のディレクトリをGitに含めるために使用する。あったほうがいい - --skip-active-record
→ Active Recordは使用する - --skip-active-storage
→ フロントからファイルアップロードを行う場合があるので使用する - --skip-bootsnap
→ bootsnapは起動を高速化させるので必要 - --skip-dev-gems
→ developmentのgemは必要
これを踏まえてskip版コンテナを作成する
比較のためにskip版コンテナ用のbackend2を作成する
projectディレクトリ直下に移動してmkdir
mkdir backend2 && mkdir backend2/api
cd backend2 && touch {Dockerfile,Gemfile,Gemfile.lock}
この時点でのディレクトリ構成
project/
├── backend/
│ ├── Dockerfile
│ ├── Gemfile
│ ├── Gemfile.lock
│ └── api/
├── backend2/
│ ├── Dockerfile
│ ├── Gemfile
│ ├── Gemfile.lock
│ └── api/
└── compose.yaml
- Dockerfile(backend2側)
FROM ruby:3.3.0
ENV APP /api
ENV TZ Asia/Tokyo
WORKDIR $APP
ADD Gemfile $APP/Gemfile
ADD Gemfile.lock $APP/Gemfile.lock
RUN bundle install
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
- Gemfile(backend2側)
source 'https://rubygems.org'
gem "rails", "~> 8.0.0"
- compose.yaml
compose.yamlでskip版のコンテナを設定する
GemのVolumeも分ける
services:
apitest:
build: ./backend/
platform: linux/x86_64
environment:
TZ: Asia/Tokyo
volumes:
- type: bind
source: ./backend/api
target: /api
- type: volume
source: gemdata
target: /usr/local/bundle
ports:
- "3000:3000"
# 以下はskip版コンテナの設定
apiskiptest:
build: ./backend2/
platform: linux/x86_64
environment:
TZ: Asia/Tokyo
volumes:
- type: bind
source: ./backend2/api
target: /api
- type: volume
source: gemdata2
target: /usr/local/bundle
ports:
- "3001:3000"
volumes:
gemdata:
gemdata2:
skipオプションてんこもりでnewしてみる
こちらは--skipオプションてんこもりでnewしてみる。
docker compose run --rm apiskiptest rails new . --api --skip-docker --skip-action-mailer --skip-action-mailbox --skip-action-text --skip-active-job --skip-action-cable --skip-asset-pipeline --skip-javascript --skip-hotwire --skip-jbuilder --skip-test --skip-system-test --skip-thruster --skip-rubocop --skip-brakeman --skip-ci --skip-kamal --skip-solid --skip-devcontainer --skip-edge --skip-main
ずらずらずら(略)
docker compose up -dする
docker compose up -dすると
- localhost:3001でskip版apiモードのRails8コンテナ
- lcoalhost:3000で通常のapiモードのRails8コンテナ
が起動する。
skipてんこ盛りでも問題なく起動
比較のため--api --minimalも作成
ここまで来たらminimalモードと何が違うのかということで--api --minimalでnewするためのコンテナをbackend3配下に作成する。手順は省略。
こちらも問題なくrails newはできた。
docker compose run --rm apiskiptest rails new . --api --minimal
それぞれの配下のディレクトリ、ファイル数の違い
- 通常のapiモード(backend配下)
tree
###略###
301 directories, 1692 files
- skip版apiモード(backend2配下)
tree
###略###
289 directories, 1332 files
- minimal版apiモード(backend3配下)
tree
###略###
31 directories, 51 files
少なっ!!!!
これでもgemにsolid_cache、solid_queue、kamal、thrusterが入っている
結果
ミニマリストには以下のnewコマンドが最強
docker compose run --rm apiminimaltest rails new . --api --minimal --skip-test --skip-system-test --skip-thruster --skip-rubocop --skip-brakeman --skip-ci --skip-kamal --skip-solid --skip-devcontainer
この場合のディレクトリ&ファイル数は以下の通り
tree
###略###
24 directories, 36 files