Ruby環境をDockerで構築する

# きっかけ
・以前からDockerについて概念は少し知っていましたが今回できるようにしようと思ってメモとして残しておきます。

# 主な対象者
・Web開発、PHPでAPI作ったくらいの初心者
・主にUnity,Unrealでプログラミング経験者
・Linuxコマンドはまぁまぁわかる程度

# 実施環境
・Mac M2 Sonoma 14.6.1
・Docker for Mac 4.40.0
・Docker 28.0.4
・Ruby 3.4.3

# こちらをベースに作業
https://qiita.com/3Zz8Xx/items/3341a795e1c6fa24bf33

・Docker for Macをインストール
https://docs.docker.com/desktop/setup/install/mac-install/

``` ターミナル.
myapp % docker --version
Docker version 28.0.4, build b8034c0
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141761/fa8a7039-5152-4f7a-bfe1-7f1694ea25dd.png)


# Ruby準備

``` ターミナル.
.% mkdir myapp
.% cd myapp
myapp % touch {Dockerfile,docker-compose.yml,Gemfile,Gemfile.lock,entrypoint.sh}
```

``` Dockerfile.
# Rubyバージョン指定
FROM ruby:3.4.3

# yarnパッケージ管理ツールをインストール
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 nodejs yarn
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

RUN yarn install --check-files
RUN bundle exec rails webpacker:compile

# コンテナ起動時に実行させるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Railsサーバー起動
CMD ["rails", "server", "-b", "0.0.0.0"]
```

``` docker-compose.yml
# version: '3'
services:
  db:
    image: mysql:8.4.5
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: myapp_development
    ports:
      - "3306:3306"
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./tmp/db:/var/lib/mysql
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
```

``` Gemfile.
source 'https://rubygems.org'
gem 'rails', '~> 8.0', '>= 8.0.2'
gem 'mysql2', '>= 0.5'
gem 'bootsnap', '~> 1.18', '>= 1.18.4'
```

``` Gemfile.lock
```

``` entrypoint.sh
#!/bin/bash
set -e # エラーが発生するとスクリプトを終了する意味

# server.pid が存在するとサーバーが起動できない対策のために server.pid を削除するように設定
rm -f /myapp/tmp/pids/server.pid

# DockerfileのCMDで渡されたコマンド（Railsサーバー起動）を実行
exec "$@"
```


``` ターミナル.
myapp % docker-compose build --no-cache // キャッシュ無視ビルド
myapp % docker-compose run web rails new . --force --no-deps --database=mysql
myapp % docker-compose build

myapp % docker-compose up
```

以下エラーが発生
``` ターミナル.
web-1  | /usr/local/bundle/ruby/3.4.0/gems/railties-8.0.2/lib/rails/application/configuration.rb:524:in 'Rails::Application::Configuration#secret_key_base=': Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit` (ArgumentError)
```

調べてみると設定すれば良いのでひとまず設定してみる

``` docker-compose.yml
  web:
    environment:
      RAILS_MASTER_KEY: <ここにconfig/master.keyの内容（32文字程度の文字列）>
```

``` ターミナル.
myapp % docker-compose up --build
```

URLアクセスしてみどり画面が表示される
http://localhost:3000/up


以下URLでアクセスできないのも気持ち悪いのでもう少し進める
http://localhost:3000/

get "up"をget "/"に変更
``` config/routes.rb
  get "/" => "rails/health#show", as: :rails_health_check
```

``` ターミナル.
Ctrl+C
myapp % docker-compose up --build
```

http://localhost:3000/

OK

# 最後に
以下の点については未調査なので実装しながら調査していく
・製品リリース時のセキュリティ問題
・dockerのContainer/Image/Volume等について
・dockerの詳細な記述について
・Rubyの使い方