Webアプリの鉄板構成Rails & Vue.js環境をDockerで構築してみよう！ 

```
mkdir myapp && cd myapp
```

こういう感じで作る。
まずはbackend。

```
├── backend
│   ├── app
│   ├── bin
│   ├── config
│   ├── db
│   ├── lib
│   ├── log
│   ├── public
│   ├── storage
│   ├── test
│   ├── tmp
│   └── vendor
└── frontend
    └── vite-project
```

```
mkdir backend && cd backend
$ touch Dockerfile
$ touch Gemfile 
$ touch Gemfile.lock
```


```Dockerfile:Dockerfile
# FROM：使用するイメージ、バージョン
FROM ruby:3.1
# 公式→https://hub.docker.com/_/ruby

# Rails 7ではWebpackerが標準では組み込まれなくなったので、yarnやnodejsのインストールが不要

# ruby3.1のイメージがBundler version 2.3.7で失敗するので、gemのバージョンを追記
ARG RUBYGEMS_VERSION=3.3.20

# RUN：任意のコマンド実行
RUN mkdir /app

# WORKDIR：作業ディレクトリを指定
WORKDIR /app

# COPY：コピー元とコピー先を指定
# ローカルのGemfileをコンテナ内の/app/Gemfileに
COPY Gemfile /app/Gemfile

COPY Gemfile.lock /app/Gemfile.lock

# RubyGemsをアップデート
RUN gem update --system ${RUBYGEMS_VERSION} && \
    bundle install

COPY . /app
```

Gemfile
```
source 'https://rubygems.org'
gem "rails", "~> 7.0.6"
```

Gemfile.lockは空。

myappに戻り


```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
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
      args:  #=== Dockerfileに引数として渡せる
        WORKDIR: app
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - './backend:/app'
    ports:
      - "3000:3000"
    environment:
        RAILS_ENV: development
    depends_on:
       - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local
```

```
docker compose run backend rails new . --api --force --no-deps --database=mysql
```


```./backend/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password # デフォルトだと空欄になっているはずなので変更
  host: db # デフォルトだとlocalhostになっているはずなので変更

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: <%= ENV["DATABASE_NAME"] %>
  username: <%= ENV["DATABASE_USERNAME"] %>
  password: <%= ENV["DATABASE_PASSWORD"] %>
```

```
$ docker compose build
$ docker compose up -d
$ docker compose run backend bundle exec rails db:create
localhost:3000で確認
```

次はfrontend

```
mkdir frontend && cd frontend
mkdir vite-project
```



```Dockerfile:Dockerfile
FROM node:16.17.1-bullseye
# ENV HOME=/app/vite-project
WORKDIR /app/vite-project
ADD ./vite-project /app/vite-project
RUN apt update \
&& yarn install
EXPOSE 5173
CMD ["yarn", "dev", "--host"]
```

```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
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
        #  args
        #  WORKDIR: app
    volumes:
      - ./frontend/vite-project:/app/vite-project
    ports:
      - '5173:5173'
    depends_on:
      - backend
    tty: true
    command: yarn dev --host
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
      args:  #=== Dockerfileに引数として渡せる
        WORKDIR: app
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - './backend:/app'
    ports:
      - "3000:3000"
    environment:
        RAILS_ENV: development
    depends_on:
       - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local
```

```
docker compose build 

docker compose run frontend bash

ディレクトリが/app/vite-projectであることを確認

yarn create vite .

yarn install

ここまで確認出来たら、exitでコンテナを抜けて改めてホストからdocker compose up をする
```

```
http://localhost:5173/
で確認
```

追記
マルチビルドステージでやる場合

```Dockerfile:Dockerfile
# ベースイメージとしてRubyを使用
FROM ruby:3.0.0 AS base

# 必要なパッケージをインストール
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    default-mysql-client

# プロジェクトディレクトリを作成
WORKDIR /app

# ホストのGemfileとGemfile.lockをコンテナにコピー
COPY Gemfile Gemfile.lock ./

# Gemをインストール
RUN gem install bundler:2.2.28
RUN bundle install --jobs 4 --retry 3 --without development test

# アプリケーションのファイルをコピー
COPY . .

# アセットのプリコンパイル
RUN bundle exec rails assets:precompile


# 最終ステージ（プロダクション環境）としてPumaを使用
FROM ruby:3.0.0 AS production

# 必要なパッケージをインストール
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    default-mysql-client

# プロジェクトディレクトリを作成
WORKDIR /app

# ホストのGemfileとGemfile.lockをコンテナにコピー
COPY Gemfile Gemfile.lock ./

# Gemをインストール
RUN gem install bundler:2.2.28
RUN bundle install --jobs 4 --retry 3 --without development test

# アプリケーションのファイルをコピー
COPY . .

# ポート番号のエクスポート
EXPOSE 3000

# サーバーの起動
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
```