【Ruby on Rails】在使用docker-compose运行Rails时的最小配置

前言

这篇文章是DMM WEBCAMP 2023年圣诞礼物日历的第二天文章。

请务必查看我们的其他文章,因为DWC导师和毕业生以Ruby on Rails为中心撰写了这些文章!

首先

你好,我是DMM WEBCAMP的导师@ukwhatn。

我在工作和私人生活中都使用Rails编写代码,尤其是在针对Rails 7的配置方面,我尝试在Docker(docker compose)中运行却找不到太多相关的资料,让我感到困惑了好几次。

虽然有像Ryan Williams的rails7-on-docker这样的模板仓库,但其中包含的内容有点过多,有些部分使用起来有些困难。

因此,本次我将介绍我个人构建的用于在Docker上运行Rails 7的模板存储库,并解释其内容。

得出結論

这是我做的。

 

在本文中,我们将简要解释这个模板仓库的重要部分。

说明

Docker相关

首先,我们来看一下关于”Docker运行”的部分。

编写.yml

代码
服务:
网络:
构建:
上下文:。
Dockerfile:./deployment/dockerfiles/web/Dockerfile
参数:
RUBY_VERSION:3.2.2
镜像:web-dev
入口点:[“bin/docker-entrypoint.sh”]
命令:bash -c “rm -f tmp/pids/server.pid && bin/rails s -p 3000 -b ‘0.0.0.0’”
挂载卷:
– .:/usr/src/app
– bundle:/usr/local/bundle
端口:
– “127.0.0.1:59998:3000”
环境变量:
– HISTFILE=/usr/src/app/log/.bash_history
– RAILS_ENV=development
– DB_HOST=${DEV_DB_HOST}
– DB_PORT=${DEV_DB_PORT}
– DB_USER=${DEV_DB_USER}
– DB_PASSWORD=${DEV_DB_PASSWORD}
依赖:
db:
条件:service_healthy
redis:
条件:service_healthy数据库:
镜像:postgres:15.4
环境变量:
– POSTGRES_USER=${DEV_DB_USER}
– POSTGRES_PASSWORD=${DEV_DB_PASSWORD}
挂载卷:
– pg_data:/var/lib/postgresql/data
重启:始终
健康检查:
测试:pg_isready -U postgres
间隔:2秒
超时:5秒
重试:30次

Redis:
镜像:redis:7.2.0
挂载卷:
– redis_data:/data
健康检查:
测试:redis-cli ping
间隔:2秒
超时:5秒
重试:30次

挂载卷:
pg_data:
redis_data:
bundle:

↑可以准确地说是compose.dev.yml的内容。
虽然还有compose.stg.yml和compose.prod.yml,但只是环境变量的前缀不同,所以略过不提。

在这个compose.yml中,以下容器将会运行。

web

railsアプリ本体が動作するコンテナです

Dockerfileは後述

ポイント

build引数としてRUBY_VERSIONを定義し、Dockerfileから参照することでベースイメージのバージョンを切り替えられるようにしています
environmentでRAILS_ENVやDB接続情報を渡しており、これを切り替えることでdev/stg/prodを分けています
depends_onでpostgresやredisの立ち上がり(service_healthy)を待ってからwebコンテナを上げています

db

みんな大好きpostgresのオフィシャルイメージです

ポイント

environmentで渡しているPOSTGRES_USERとPOSTGRES_PASSWORDはrailsに渡しているものと共通です

pg_isready -U postgresでhealthcheckを行うことで、service_healthyコンディションによるdepends_onを有効化しています

redis

セッションストアとして利用するためのredisコンテナです

ポイント

redis-cli pingでhealthcheckを行うことで、service_healthyコンディションによるdepends_onを有効化しています

Dockerfile(网络版)

在 deployment/dockerfiles/web/Dockerfile 文件中可以找到。

代码
ARG RUBY_VERSIONFROM ruby:${RUBY_VERSION}-slim

# OS级别的依赖
RUN –mount=type=cache,target=/var/cache/apt \
–mount=type=cache,target=/var/lib/apt,sharing=locked \
–mount=type=tmpfs,target=/var/log \
rm -f /etc/apt/apt.conf.d/docker-clean; \
echo ‘Binary::apt::APT::Keep-Downloaded-Packages “true”;’ > /etc/apt/apt.conf.d/keep-cache; \
apt-get update -qq \
&& apt-get install -yq –no-install-recommends \
build-essential \
gnupg2 \
less \
git \
libpq-dev \
postgresql-client \
libvips \
curl

ENV LANG=C.UTF-8 \
BUNDLE_JOBS=4 \
BUNDLE_RETRY=3

RUN gem update –system && gem install bundler

WORKDIR /usr/src/app

ENTRYPOINT [“./bin/docker-entrypoint.sh”]

EXPOSE 3000

我没有做太复杂的事情。

如果想要将数据库更改为MySQL之类的,请在此处安装适当的库,而不是libpq-dev或postgresql-client。

docker入口点脚本

这个位于bin/docker-entrypoint.sh的文件。
这是在compose.yml中设置的入口点。

代码
#!/bin/bash
set -eecho -e “———————-\n初始化Rails应用程序\n模式:$RAILS_ENV\n———————-\n”

# 删除可能已存在的Rails服务器进程文件
rm -f /usr/src/app/tmp/pids/server.pid

echo “rails: 安装gems…”
bundle check || bundle install –jobs 4

echo “rails: 创建数据库…”
bundle exec rake db:create
echo “rails: 迁移数据库…”
bundle exec rake db:migrate

# 如果是生产模式,则编译assets
if [ “$RAILS_ENV” = ‘production’ ]; then
echo “rails: 预编译assets…”
bundle exec rake assets:precompile
fi

# 然后执行容器的主进程(即Dockerfile中设置的CMD命令)
exec “$@”

只需要一种选项:
我所做的事情很简单,

    1. 删除server.pid

 

    1. 安装bundle

 

    1. 进行数据库迁移

 

    编译资产预编译(仅在生产模式下)

只需要以下一个选项:
如果在创建容器时有想要执行的任务,请在此处进行补充。


关于Docker,重要的事情大致就是这样。
总的来说,并不涉及太多复杂的事情,所以请根据需要进行修改和使用。

Ruby on Rails相关

我们将从这里开始查看在程序内部运行的Rails配置文件等。

Gemfile: 珠宝文件

# 内容标题: Ruby项目Gemfile配置“`ruby
代码
# 冻结字符串文字
# frozen_string_literal: true

source “https://rubygems.org”
git_source(:github) { |repo| “https://github.com/#{repo}.git” }

ruby “3.2.2”

# Rails 7
gem “rails”, “~> 7.0.7”, “>= 7.0.7.2”

# 用于资源管道
gem “sprockets-rails”

# Postgresql 驱动
gem “pg”, “~> 1.1”

# Web 服务器
gem “puma”, “~> 6.3”

# 使用import maps
gem “importmap-rails”

# 使用 Turbo
gem “turbo-rails”

# Stimulus 框架
gem “stimulus-rails”

# JSON 构建器
gem “jbuilder”

# Redis
gem “redis”, “~> 4.8.1”, “< 5” gem “redis-rails” # 创建密码哈希 # gem “bcrypt”, “~> 3.1.7”

# 用于 Windows 的时区
gem “tzinfo-data”, platforms: %i[mingw mswin x64_mingw jruby]

# 通过缓存减少启动时间
gem “bootsnap”, require: false

# 使用 Sass 处理 CSS
gem “dartsass-rails”
gem “sassc-rails”

# 使用 Active Storage 变体
gem “image_processing”, “~> 1.2”

# 用于本地化
gem “i18n_generators”
gem “rails-i18n”

# 用于读取 .env 文件
# gem “dotenv-rails”

# 用于 Discord OAuth2
# gem “omniauth-discord”

# 用于 Google OAuth2
# gem “omniauth-google-oauth2”

# 用于 GitHub OAuth2
# gem “omniauth-github”

# 用于 omniauth 的 CSRF 保护
# gem “omniauth-rails_csrf_protection”

group :development, :test do
# 查看 https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem “brakeman”
gem “bundler-audit”
gem “debug”, “1.8.0”, platforms: %i[mri mingw x64_mingw]
gem “rspec-rails”
gem “rubocop”
gem “rubocop-performance”
gem “rubocop-rails”
gem “rubocop-rspec”
end

group :development do
# 在异常页面上使用控制台 [https://github.com/rails/web-console]
gem “web-console”

# 添加速度徽章 [https://github.com/MiniProfiler/rack-mini-profiler]
gem “rack-mini-profiler”

# 对于运行缓慢的机器/大型应用程序加速命令 [https://github.com/rails/spring]
# gem “spring”
end

group :test do
# 使用系统测试 [https://guides.rubyonrails.org/testing.html#system-testing]
gem “capybara”
gem “selenium-webdriver”
gem “webdrivers”
end
“`

Note: This reply has been adjusted, and no longer reflects the answer to the original question.

如果想要使用OAuth2,请取消注释omniauth系列的Gem。在这里并没有太多偏离模板的地方。

.rubocop.yml的中文简 paragr 和忠。

コード
require:
– rubocop-rails
– rubocop-rspec
– rubocop-capybara
– rubocop-performanceAllCops:
TargetRubyVersion: 3.2.2
TargetRailsVersion: 7.0.1
DisabledByDefault: true
DisplayCopNames: true
NewCops: enable
Exclude:
– “bin/**/*”
– “vendor/**/*”
– “public/**/*”
– “node_modules/**/*”
– “db/schema.rb”

# —– bundler —–
Bundler:
Enabled: true

# —– layout —–

Layout:
Enabled: true

# —– lint —–

Lint:
Enabled: true

Lint/EmptyBlock:
Enabled: false
Exclude:
– “config/routes.rb”

# —– naming —–

Naming:
Enabled: true

# —– security —–

Security:
Enabled: true

# —– performance —–

Performance:
Enabled: true

# —– style —–

# ブロックの終了部分が適切にスタイル指定されているか
Style/EndBlock:
Enabled: true
# ハッシュの構文が適切か
Style/HashSyntax:
Enabled: true
# 文字列リテラルが適切にスタイル指定されているか
Style/StringLiterals:
Enabled: true
EnforcedStyle: “double_quotes”
Exclude:
– “config/**/*.rb”
– Rakefile
# caseの等価性が適切にチェックされているか
Style/CaseEquality:
Enabled: true
# クラスメソッドが適切に定義されているか
Style/ClassMethods:
Enabled: true
# クラス変数が適切に使用されているか
Style/ClassVars:
Enabled: true
# collectionメソッドが適切に使用されているか
Style/CollectionMethods:
Enabled: true
PreferredMethods:
collect: “map”
collect!: “map!”
inject: “reduce”
detect: “find”
find_all: “select”

因为这是一个模板仓库,所以我将rubocop只设为true必要的部分。特别是Style/*部分,请根据需要进行增删。

session_store.rb是一个Ruby文件。

这可以在config/initializers/session_store.rb文件中找到。

代码
secure = Rails.env.production?
key = Rails.env.production? ? “_app_session” : “_app_session_#{Rails.env}”
domain = ENV.fetch(“APP_DOMAIN”, “localhost”)Rails.application.config.session_store :redis_store,
servers: %w(redis://redis:6379/0/session),
expire_after: 90.minutes,
key: key,
domain: domain,
secure: secure,
httponly: true,
threadsafe: true

请查看redis-rails官方README文件以获取设置值。
我认为只有expire_after可能需要更改。


可以根据需要进行自定义,Rails的部分如下。

其他

Makefile -> 文件

因为键入docker命令太麻烦了,所以我把它们整理到了Makefile中。

代码
.PHONY:测试构建DIR_NAME:= $(shell basename $(CURDIR))

初始化:
cp .env.example .env

开发:
构建开发
上升开发
记录开发

构建开发:
集装箱构建-dev.ym文件

上升开发:
集装箱构成开发.yml文件 -d

下降开发:
集装箱开发文件 -d

清洁开发:
集装箱构成开发.yml文件 -d –rmi all –volumes –remove-orphans

记录开发:
集装箱构成开发.yml文件-日志 -f

产品:
构建产品
上升产品
记录产品

构建产品:
集装箱构建prod.yml文件

上升产品:
集装箱构成prod.yml文件 -d

下降产品:
集装箱产品文件 -d

记录产品:
集装箱构成prod.yml文件-日志 -f

Redis-cli:
集装箱构成开发.yml文件 -执行Redis redis-cli

例子环境变量文件

我们使得在开发/测试/生产环境中能够进行选择。

# — 开发 —
DEV_DB_HOST=”db”
DEV_DB_PORT=”5432″
DEV_DB_USER=”postgres”
DEV_DB_PASSWORD=”changeme”# — 部署 —
STG_DB_HOST=”db”
STG_DB_PORT=”5432″
STG_DB_USER=”postgres”
STG_DB_PASSWORD=”changeme”

# — 测试 —
TEST_DB_HOST=”db”
TEST_DB_PORT=”5432″
TEST_DB_USER=”postgres”
TEST_DB_PASSWORD=”changeme”

# — 生产 —
PROD_DB_HOST=”db”
PROD_DB_PORT=”5432″
PROD_DB_USER=”postgres”
PROD_DB_PASSWORD=”changeme”

dependabot.yml 可信赖的机器人配置文件

在 .github/depandabot.yml 文件中可以找到

代码
版本:2
更新:
– 包-生态系统:docker
目录: “/”
计划:
时间间隔:每日
– 包-生态系统:bundler
目录: “/”
计划:
时间间隔:每日
忽略:
– 依赖名称:”rails”
更新类型:[“版本更新:语义化主要版本”, “版本更新:语义化次要版本”]
– 包-生态系统:github-actions
目录: “/”
计划:
时间间隔:每日

当我们阅读Gemfile时,如果有更新,就会为我们创建一个PR。考虑到其便利性,建议我们将其启用。


就是这样。

由于这个模板是比较随意地制作的,所以如果您有任何疑问或建议,请在评论或PR中提出。

由于我们将在明天继续发布,因此请期待我们的圣诞倒数日历!

广告
将在 10 秒后关闭
bannerAds