【rails 7.2】rails newを調査

# はじめに
ふと気づけば、rails7.2がリリースされており、すでに7.2.1とのこと。

https://techracho.bpsinc.jp/hachi8833/2024_08_23/144672

なので、以前に書いた下記の記事の内容だったり、その他の変更点についてざっくり見てみようという記事となります。

https://qiita.com/youfuku/items/797cf0f745c7c7bbf0f6

また、今回もdevcontainer利用前提で進めていきます。


# 環境構築

## ファイルの準備
```shell:コマンド
touch Dockerfile
touch Gemfile
touch Gemfile.lock
```

```Dockerfile:Dockerfile
FROM public.ecr.aws/docker/library/node:21.7-slim AS node
FROM public.ecr.aws/docker/library/ruby:3.3-slim

RUN apt-get update -y -qq \
    && apt-get install -y build-essential libpq-dev default-libmysqlclient-dev git \
    && rm -rf /usr/local/bundle/cache/* /usr/local/share/.cache/* /var/cache/* /tmp/*

# install node
COPY --from=node /opt/yarn-* /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \
  && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg

ENV TZ Asia/Tokyo

WORKDIR /workspaces

# gem
COPY Gemfile* /workspaces/
RUN gem update --system && \
    bundle update --bundler && \
    bundle install

COPY . /workspaces
```

```ruby:Gemfile
source 'https://rubygems.org'
gem 'rails'
```

## build

```shell:コマンド
docker build -f Dockerfile -t rails_new_image/72 .
```


# rails newの確認
```shell:コマンド
docker run rails_new_image/72 rails new -h
```

```diff:表示内容
$ docker run rails_new_image/72 rails new -h
Usage:
  rails new APP_PATH [options]

Options:
                 [--skip-namespace]                                            # Skip namespace (affects only isolated engines)
                                                                               # Default: false
                 [--skip-collision-check]                                      # Skip collision check
                                                                               # Default: false
  -r,            [--ruby=PATH]                                                 # Path to the Ruby binary of your choice
                                                                               # Default: /usr/local/bin/ruby
  -n,            [--name=NAME]                                                 # Name of the app
  -m,            [--template=TEMPLATE]                                         # Path to some application template (can be a filesystem path or URL)
+  -d,            [--database=DATABASE]                                         # Preconfigure for selected database
                                                                               # Default: sqlite3
+                                                                               # Possible values: mysql, trilogy, postgresql, sqlite3
  -G,            [--skip-git]                                                  # Skip git init, .gitignore and .gitattributes
                 [--skip-docker]                                               # Skip Dockerfile, .dockerignore and bin/docker-entrypoint
                 [--skip-keeps]                                                # Skip source control .keep files
  -M,            [--skip-action-mailer]                                        # Skip Action Mailer files
                 [--skip-action-mailbox]                                       # Skip Action Mailbox gem
                 [--skip-action-text]                                          # Skip Action Text gem
  -O,            [--skip-active-record]                                        # Skip Active Record files
                 [--skip-active-job]                                           # Skip Active Job
                 [--skip-active-storage]                                       # Skip Active Storage files
  -C,            [--skip-action-cable]                                         # Skip Action Cable files
  -A,            [--skip-asset-pipeline]                                       # Indicates when to generate skip asset pipeline
  -a,            [--asset-pipeline=ASSET_PIPELINE]                             # Choose your asset pipeline
                                                                               # Default: sprockets
                                                                               # Possible values: none, sprockets, propshaft
  -J, --skip-js, [--skip-javascript]                                           # Skip JavaScript files
                 [--skip-hotwire]                                              # Skip Hotwire integration
                 [--skip-jbuilder]                                             # Skip jbuilder gem
  -T,            [--skip-test]                                                 # Skip test files
                 [--skip-system-test]                                          # Skip system test files
                 [--skip-bootsnap]                                             # Skip bootsnap gem
                 [--skip-dev-gems]                                             # Skip development gems (e.g., web-console)
+                 [--skip-rubocop]                                              # Skip RuboCop setup
+                 [--skip-brakeman]                                             # Skip brakeman setup
                 [--skip-ci]                                                   # Skip GitHub CI files
                 [--dev], [--no-dev], [--skip-dev]                             # Set up the application with Gemfile pointing to your Rails checkout
+                 [--devcontainer], [--no-devcontainer], [--skip-devcontainer]  # Generate devcontainer files
                                                                               # Default: false
                 [--edge], [--no-edge], [--skip-edge]                          # Set up the application with a Gemfile pointing to the 7-2-stable branch on the Rails repository
  --master,      [--main], [--no-main], [--skip-main]                          # Set up the application with Gemfile pointing to Rails repository main branch
                 [--rc=RC]                                                     # Path to file containing extra configuration options for rails command
                 [--no-rc]                                                     # Skip loading of extra configuration options from .railsrc file
                 [--api], [--no-api], [--skip-api]                             # Preconfigure smaller stack for API only apps
                                                                               # Default: false
                 [--minimal], [--no-minimal], [--skip-minimal]                 # Preconfigure a minimal rails app
  -j, --js,      [--javascript=JAVASCRIPT]                                     # Choose JavaScript approach
                                                                               # Default: importmap
                                                                               # Possible values: importmap, bun, webpack, esbuild, rollup
  -c,            [--css=CSS]                                                   # Choose CSS processor. Check https://github.com/rails/cssbundling-rails for more options
                                                                               # Possible values: tailwind, bootstrap, bulma, postcss, sass
  -B,            [--skip-bundle]                                               # Don't run bundle install
                 [--skip-decrypted-diffs]                                      # Don't configure git to show decrypted diffs of encrypted credentials

Runtime options:
  -f, [--force]                                      # Overwrite files that already exist
  -p, [--pretend], [--no-pretend], [--skip-pretend]  # Run but do not make any changes
  -q, [--quiet], [--no-quiet], [--skip-quiet]        # Suppress status output
  -s, [--skip], [--no-skip], [--skip-skip]           # Skip files that already exist

Rails options:
  -h, [--help], [--no-help], [--skip-help]           # Show this help message and quit
  -v, [--version], [--no-version], [--skip-version]  # Show Rails version number and quit

Description:
    The `rails new` command creates a new Rails application with a default
    directory structure and configuration at the path you specify.

    You can specify extra command-line arguments to be used every time
    `rails new` runs in the .railsrc configuration file in your home directory,
    or in $XDG_CONFIG_HOME/rails/railsrc if XDG_CONFIG_HOME is set.

    Note that the arguments specified in the .railsrc file don't affect the
    default values shown above in this help message.

    You can specify which version to use when creating a new rails application 
    using `rails _<version>_ new`.

Examples:
    `rails new ~/Code/Ruby/weblog`

    This generates a new Rails app in ~/Code/Ruby/weblog.

    `rails _<version>_ new weblog`

    This generates a new Rails app with the provided version in ./weblog.

    `rails new weblog --api`

    This generates a new Rails app in API mode in ./weblog.

    `rails new weblog --skip-action-mailer`

    This generates a new Rails app without Action Mailer in ./weblog.
    Any part of Rails can be skipped during app generation.
```

7.1時点になかった部分を配色しました。(細かく見ればもっとあります)

まず、DBに関しては「trilogy」が選べるようになっていました。
自分は未だに使ったことがありませんが、調べたところmysql2より早いらしいです。

https://zenn.dev/happy_elements/articles/e2f63494dcceb0

次に、rubocopとbrakemanがデフォルトになりました。
rubocopに関しては、「おまかせ」という別のgemで提供されているようです。

最後に、devcontainerが組み込まれました。
説明は以前の記事がありますので、割愛させていただきます。

# rails new 実行
```
docker run --rm -v .:/workspaces rails_new_image/72 rails new .  \
--database=mysql  \
--skip-action-mailer \
--skip-action-mailbox  \
--skip-test   \
--javascript=esbuild  \
--css=tailwind  \
--devcontainer \
--force 
```

# ファイルの確認
## Gemfile
brakemanとrubocop(rubocop-rails-omakase)が導入されてるのが分かります。
```diff:Gemfile
source "https://rubygems.org"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.2.1"
# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]
gem "sprockets-rails"
# Use mysql as the database for Active Record
gem "mysql2", "~> 0.5"
# Use the Puma web server [https://github.com/puma/puma]
gem "puma", ">= 5.0"
# Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails]
gem "jsbundling-rails"
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "turbo-rails"
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
gem "stimulus-rails"
# Bundle and process CSS [https://github.com/rails/cssbundling-rails]
gem "cssbundling-rails"
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem "jbuilder"
# Use Redis adapter to run Action Cable in production
# gem "redis", ">= 4.0.1"

# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"

# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
# gem "bcrypt", "~> 3.1.7"

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ windows jruby ]

# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", require: false

# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"

group :development, :test do
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
  gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"

  # Static analysis for security vulnerabilities [https://brakemanscanner.org/]
+  gem "brakeman", require: false

  # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
+  gem "rubocop-rails-omakase", require: false
end

group :development do
  # Use console on exceptions pages [https://github.com/rails/web-console]
  gem "web-console"
end
```

## .devcontainer
以前調べたものと同一で差分はありませんでした

https://qiita.com/youfuku/items/797cf0f745c7c7bbf0f6

## Dockerfile
大きく変わったところはありませんが、buildやrunのコマンドがコメントで書かれてるのは個人的には助かります
```
# syntax = docker/dockerfile:1

# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
# docker build -t my-app .
# docker run -d -p 80:80 -p 443:443 --name my-app -e RAILS_MASTER_KEY=<value from config/master.key> my-app

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.3.4
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base

# Rails app lives here
WORKDIR /rails

# Install base packages
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl default-mysql-client libjemalloc2 libvips && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Set production environment
ENV RAILS_ENV="production" \
    BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development"

# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential default-libmysqlclient-dev git node-gyp pkg-config python-is-python3 && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Install JavaScript dependencies
ARG NODE_VERSION=21.7.3
ARG YARN_VERSION=1.22.19
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
    /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
    npm install -g yarn@$YARN_VERSION && \
    rm -rf /tmp/node-build-master

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
    bundle exec bootsnap precompile --gemfile

# Install node modules
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Copy application code
COPY . .

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile


RUN rm -rf node_modules


# Final stage for app image
FROM base

# Copy built artifacts: gems, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails

# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
    useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
    chown -R rails:rails db log storage tmp
USER 1000:1000

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]
```


# 最後に
やっとrubocopとbrakemanがデフォルトになったのかーと思います。
railsの開発はdevcontainerが中心になると思っていますので、今回devcontainerの利用を前提にcompose.ymlの作成は無しにしました。



# 最後の最後に(感想文的な)
ここ最近、環境構築系の記事ばっかり書いてるいる気がします。
次の記事の内容を準備してる時に、バージョンアップなどされて、それを調べるという寄り道をした結果です・・・orz
がんばって、もう少し面白い記事を書きたいものです。