Docker: Ruby on Rails を使う

こちらと同じことを Arch Linux で行いました。
[Ruby 3.1 + Rails 7 + MySQL 8 + Docker 環境構築](https://qiita.com/neet244/items/8c5ed68fdc28121eecd7)

## Docker が実行できるようにする

```bash
sudo pacman -S docker
sudo pacman -S docker-compose
sudo systemctl start docker
```

一般ユーザーで docker コマンドが使えるようにする

```bash
sudo gpasswd -a uchida docker
sudo chmod 0666 /var/run/docker.sock
```

確認

```bash
docker ps
```

## ファイルの用意

```text
Dockerfile
Gemfile
Gemfile.lock
docker-compose.yml
entrypoint.sh
```

Gemfile.lock は空のファイルなので次のようにして作成します。

```bash
touch Gemfile.lock
```

```text:Dockerfile
FROM ruby:3.1
ARG RUBYGEMS_VERSION=3.3.20
RUN mkdir /rails_practice
WORKDIR /rails_practice
COPY Gemfile /rails_practice/Gemfile
COPY Gemfile.lock /rails_practice/Gemfile.lock
RUN bundle install
COPY . /rails_practice

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"]
```

```text:Gemfile
source 'https://rubygems.org'
gem 'rails', '~>7.0.4'
```

```yml:docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/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:
      - .:/rails_practice
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local
```

```bash:entrypoint.sh
#!/bin/bash
set -e

rm -f /docker_rails/tmp/pids/server.pid

exec "$@"
```

## アプリケーションの作成

```bash
docker-compose run web rails new . --force --no-deps --database=mysql --skip-test --webpacker
```

```bash
docker-compose build
```

データベースの作成

```bash
docker-compose run web rake db:create
```

## 実行

```bash
docker-compose up
```

コンテナーの状況

```text
$ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED       STATUS         PORTS                                                  NAMES
b176d03f284e   ror2-web    "entrypoint.sh bash …"   3 hours ago   Up 7 seconds   0.0.0.0:3000->3000/tcp, :::3000->3000/tcp              ror2-web-1
d134e77d45c0   mysql:8.0   "docker-entrypoint.s…"   3 hours ago   Up 8 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   ror2-db-1
```

## ブラウザーでアクセス
http://0.0.0.0:3000/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a06acd10-9aa1-d55d-f607-2bd1da28be7f.png)

## データベースにアクセス

```text
$ docker exec -it ror2-db-1 bash
bash-4.4# mysql -uroot -ppassword -hdb
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.0.34 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+----------------------------+
| Database                   |
+----------------------------+
| information_schema         |
| mysql                      |
| performance_schema         |
| rails_practice_development |
| sys                        |
+----------------------------+
5 rows in set (0.01 sec)

mysql>
```

## Web サーバーにアクセス

```text
$ docker exec -it ror2-web-1 bash
root@b176d03f284e:/rails_practice# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
root@b176d03f284e:/rails_practice#
```

## プログラムの改造

Rails の操作

Web サーバーにログインして次の操作を行います。

```bash
rails g controller users index
```

ホスト側で、ファイルを編集します。

```rb:app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    render plain: '皆さん　こんにちは'
  end
end
```

http://0.0.0.0:3000/users/index にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/cf1ef23a-9ace-840d-3aea-bfe95699f759.png)

## Tips

作成したdockerコンテナをすべて削除する方法

```bash
docker-compose down --rmi all --volumes --remove-orphans
```