Docker / Rails / Next.js
docker compose up
で ArgumentError 発生
ArgumentError の意味
- Argument = 引数
- ArgumentError:引数の数があっていないとき、もしくは期待される値ではないときに発生する
compose.yaml / Dockerfile / Gemfile
services:
db:
image: postgres:16.4
environment:
POSTGRES_DB: app_development
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
backend:
build:
context: ./backend
command: bash -c "bundle exec rails s -b '0.0.0.0'"
volumes:
- ./backend:/app
ports:
- "3000:3000"
depends_on:
- db
tty: true
stdin_open: true
volumes:
postgres_data:
FROM ruby:3.3.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /app
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"]
source "https://rubygems.org"
ruby "3.3.5"
gem "rails", "~> 7.2.1", ">= 7.2.1.2"
# postgreSQL
gem "pg", "~> 1.1"
# default gem
gem "bootsnap", require: false
gem "puma", ">= 5.0"
gem "tzinfo-data", platforms: %i[ windows jruby ]
# CORS
gem "rack-cors"
group :development, :test do
end
エラー
backend-1 | /usr/local/bundle/ruby/3.3.0/gems/railties-7.2.1.2/lib/rails/application/configuration.rb:519:in `secret_key_base=': Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit` (ArgumentError)
backend-1 |
backend-1 | raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `bin/rails credentials:edit`"
backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
secret_key_base
って何?
secret_key_base()
The
secret_key_base
is used as the input secret to the application’s key generator, which in turn is used to create allActiveSupport::MessageVerifier
andActiveSupport::MessageEncryptor
instances, including the ones that sign and encrypt cookies.
In development and test, this is randomly generated and stored in a temporary file intmp/local_secret.txt
.
You can also setENV["SECRET_KEY_BASE_DUMMY"]
to trigger the use of a randomly generatedsecret_key_base
that’s stored in a temporary file. This is useful when precompiling assets for production as part of a build step that otherwise does not need access to the production secrets.
Dockerfile example:RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile
.
In all other environments, we look for it first inENV["SECRET_KEY_BASE"]
, thencredentials.secret_key_base
. For most applications, the correct place to store it is in the encrypted credentials file.
参照:secret_key_base - Rails::Application
翻訳:
secret_key_base()
は、アプリケーションのキージェネレーターへの入力シークレットとして使用され、これは次にcookieの署名と暗号化を含むすべての ActiveSupportMessageVerifier
とActiveSupport::MessageEncryptor
インスタンスの作成に使用されます。
開発環境とテスト環境では、これはランダムに生成されて tmp/local_secret.txt
の一時ファイルに保存されます。
また、ENV["SECRET_KEY_BASE_DUMMY"]
を設定することで、一時ファイルに保存されるランダムに生成された secret_key_base
の使用をトリガーすることもできます。これは、本番環境のシークレットにアクセスする必要がない場合のビルドステップの一部として、本番環境用のアセットをプリコンパイルする際に便利です。
Dockerfileの例: RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile
他のすべての環境では、最初にENV["SECRET_KEY_BASE"]
、次にcredentials.secret_key_base
で探します。ほとんどのアプリケーションでは、暗号化された認証情報ファイルに保存するのが正しい場所です。
rails new
により Dockerfile が上書きされていた
原因:Rails7.1 から rails new
すると、Dockerfileも自動生成されるようになった。
そのため、事前に用意していた Dockerfile が上書きされて、エラーが発生した。
なお、Rails が自動生成する Dockerfile は本番用で、開発環境用は別で用意する必要がある。
自動生成された Dockerfile:
# 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.5
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 libjemalloc2 libvips postgresql-client && \
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
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libpq-dev pkg-config && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# 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
# Copy application code
COPY . .
# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/
# Final stage for app image
FROM base
# Copy built artifacts: gems, application
COPY "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY /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"]
解決方法について考えてみる
-
Rails で自動生成(上書き)されたものは削除し、以前の記述に戻す
-
Rails で自動生成されたものを活用する
参考: -
Rails で自動生成されたものを本番用として残しつつ、開発用のDockerfileを新規作成する
参考: -
マルチステージビルドを活用する
参考:Dockerのマルチステージビルドで依存先を統一した回
今回の進め方
- 以前の記述に戻しつつ、3. 開発用と本番用の Dockerfile を用意する形で進める
Github Avtions について
Github Actions の内容は以下記事がとてもわかりやすかった。
【初心者向け】【入門】GitHub Actionsとは?書き方、デバッグ設定、runs-onやcheckoutなどの仕組みや構造も含めて徹底解説 #Linux - Qiita
コードの内容理解
RSpec(テスト)、RuboCop, ESLint(コードルール)のチェックを行う。
name: Continuous Integration
on: push
jobs:
RSpec:
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
services:
mysql:
image: postgres:16.4.0
ports:
- "5432:5432"
env:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3.5
bundler-cache: true
- name: Cache node modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-node-
- name: Bundler and gem install
run: |
gem install bundler
bundle install --jobs 4 --retry 3 --path vendor/bundle
- name: Database create and migrate
run: |
cp config/database.yml.ci config/database.yml
bundle exec rails db:create RAILS_ENV=test
bundle exec rails db:migrate RAILS_ENV=test
- name: Run rspec
run: bundle exec rspec
RuboCop:
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3.5
bundler-cache: true
- name: Bundler and gem install
run: |
gem install bundler
bundle install --jobs 4 --retry 3 --path vendor/bundle
- name: Run rubocop
run: bundle exec rubocop
ESLint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install packages
run: npm install
- name: Run lint
run: npm run lint
-
on: push
:ブランチへの push 時に workflow を実行 -
jobs:
:処理の内容を記述-
RSpec:
:RSpec がオールグリーンであることをチェック -
RuboCop:
:RuboCop のルール違反がないことをチェック -
ESLint:
:ESLint のルール違反がないかチェック
-
-
defaults.run.working-directory
:作業ディレクトリを指定 -
jobs.<job_id>.steps
:具体的に行う処理の内容。上からコマンドを実行。 - PostgreSQL の記述は「 PostgreSQLサービスコンテナの作成 」を参照
-
POSTGRES_PASSWORD
は、Github Secrets に格納