DockerでRails6 + Vite + PostgreSQL（w: pgadmin4）の開発環境をつくる

# はじめに
　Ruby on Rails で、Webアプリ（SPA）を作ってみたくなった。Ruby on Rails にAPIモードというのがあり、フロントエンドと組み合わせて開発ができるらしい。筆者はRuby on Rails を触ったことは殆どないので、自分の勉強のため、まずは開発環境を構築することにした。
　とりあえず、先達の真似をしてなるべく最速でつくりたかった。私はマシンのNodejsバージョンを切り替えるなど管理がおっくうなので、プロジェクトのフォルダの中にDockerで環境を作りたかった。さらにいえば、docker compose up ズドンと一発で作りたい。調べてみたが、「一発」で作っている先達は見つからなかった。途中でDB環境ファイルを書き換えるなどの作業が必要で一発は無理らしい。しかも、RoRはWebアプリ開発初心者に人気とのことであったが、SPA開発Docker環境の構築が初心者向けだとは誰も言ってなさそうだ。
　以下、備忘録として、先達の真似をした事前調査を踏まえ自分なりにうまく行った環境構築例を書いておく。
 
　なお、本件は以下PC環境での2023年11月初旬現在の構築例である。
```
OS: ubuntu 22.04.3 LTS
docker version 24.0.7
docker compose plugin v2.21.0
```
# 事前調査


### Rails API mode ?

https://qiita.com/ASONE0923/items/a8dae59b3092298059d3

https://zenn.dev/akino/articles/bf245128f390d7


### 先達の例（１）

https://qiita.com/jibiking/items/fc7b0141af4b13a32ec3

最後まで手順通り進め、docker compose up　するが、次のエラーを出してrailsのdockerが立ち上がらない。Rails7.1.1で、どのような環境変数を設定してこのsecret_key_baseの問題を解決するのか、わからないのであきらめた。（先達の例は、Rails7.0なのであろう。Gemfileでrailsのバージョンを指定すればうまくいくのかもしれない。）そもそもRails7での開発の参考情報が私には手に入りにくいので、現在の最新環境Rails7にこだわらず、あきらめることにした。

```
/usr/local/bundle/ruby/3.2.0/gems/railties-7.1.1/lib/rails/application.rb:641:in `validate_secret_key_base': Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit` (ArgumentError)
```
 Rails7は、私のような初心者・情報弱者が手をだすものではない、ということがわかった。

### 先達の例（２)

https://qiita.com/subun33/items/b3b48b7fb04113f4a049

　これはうまく行きそうだった。しかもこの先達の例では、railsとfrontのフォルダを分けてファイルを管理しようとしている。node_moduleの管理に独特のこだわりがある点にも好感をもてた。参考にしたい。

 ### viteについて
　最近のVue3は、プロジェクトの管理にViteを使うらしいから、自分はViteを使って構築できるようにした。viteを使えば、フロントはvue3とかreactとか選択もできるだろう。あと詳しくはわからないが、動作が早い（vite = フランス語で「素早い」の意味）らしいので。SPA動作が早いに越したことはないと期待して。

 https://ja.vitejs.dev/guide/why.html

 https://zenn.dev/tasuya/articles/158209072d3715

 ### pgadmin4について
 　開発環境でDBを直に覗いてみたくなる事態が予想されるので、postgreSQLを操作できるGUIもつけておきたい。

  https://qiita.com/Akhr/items/8d5b5127ee971a640253

# 方法

1. ディレクトリ（フォルダ）構成
　先達（２）の真似をしつつも、ちょっと異なる。主な理由は、viteで構築される環境ファイルの置き場所の指定の問題が発生するからだ。ついでにrailsの環境ファイルの中にDockerfile、entrypoint.shを置かないように考えてみた。
 
```
.
├── api
│   └── Gemfile
├── dockerfiles
│   ├── api
│   │   └── Dockerfile
│   │   └── entry-point.sh
│   └── front
│       └── Dockerfile
├── front
│   └ node_modules（空のフォルダ）
└── dockercompose.yml
```

2. 配置したファイルの内容

```./api/Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6.1'
```
```./api/Gemfile.lock
#（何も書きません）
```
```./dockerfiles/api/Dockerfile
FROM ruby:3.2

RUN 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 -qq \
    && apt-get install -y nodejs yarn postgresql-client git imagemagick

WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

RUN bundle install


COPY entry-point.sh /usr/bin/
RUN chmod +x /usr/bin/entry-point.sh
ENTRYPOINT ["entry-point.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
```
```./dockerfiles/api/entry-point.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```
```./dockerfiles/front/Dockerfile
FROM node:18
WORKDIR /app
COPY . /app
CMD ["/bin/bash", "-c", "yarn install && yarn dev"]
```
```docker-compose.yml
version: "3.6"
services:
  db:
    image: postgres
    volumes:
      - postgresql_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password

  pgadmin:
    image: dpage/pgadmin4
    ports:
      - 8005:80
    volumes:
      - pgadmin4_data:/var/lib/pgadmin
    environment:
      PGADMIN_DEFAULT_EMAIL: example@example.com
      PGADMIN_DEFAULT_PASSWORD: password
    depends_on:
      - db

  api:
    build: 
      context: ./api
      dockerfile: ../dockerfiles/api/Dockerfile
    volumes:
      - ./api:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

  front:
    build:
      context: ./front
      dockerfile: ../dockerfiles/front/Dockerfile
    volumes:
      - ./front:/app
    ports:
      - "8110:8110"

volumes:
  postgresql_data:
  pgadmin4_data:
```
3.　環境構築コマンドの実行

　先達の説明のとおり、はじめにRails環境をつくり、そのDB設定ファイルを書き換えるなどの処理をする。

 ```sh
$ docker compose build
$ docker compose run --rm --no-deps api rails new . -f -T --api --database=postgresql
$ docker compose build
```
（DB設定ファイルの書き換え）ターミナル上で書き換えようとすると、（DockerコンテナのAdminが作ったファイルなので）ファイルへのアクセス権限がなくて、sudoなどで書き換えの実行が要求される。sudoできないときはコンテナ経由で書き換えるのかな・・・
　
```./api/config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: db
  username: postgres
  password: password

development:
  <<: *default
  database: api_test


test:
  <<: *default
  database: app_test

# もし、productionリリースしたくなったらどうすればいいのだろう？
# 将来に備えてメモしておく。
#production:
#  database: app_production
#  username: app
#  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
```
```sh
$ docker compose run --rm api rails db:create        
```

（CORS の設定）
```./api/Gemfile
#（コメントアウトされている行を有効化する）
gem 'rack-cors'
```
ターミナル上で書き換えようとすると、（DockerコンテナのAdminが作ったファイルなので）ファイルへのアクセス権限がなくて、sudoなどで書き換えの実行が要求される。sudoできないときはコンテナ経由で書き換えるのかな・・・

```./api/config/initializers/cors.rb
#以下を追記する。
Rails.application.config.middleware.insert_before 0, Rack::Cors do
    allow do
      origins 'http://localhost:8110'
  
      resource '*',
          headers: :any,
          methods: [:get, :post, :put, :patch, :delete, :options, :head],
          credentials: true
    end
  end
```
cors設定が有効になるように、もっかいビルドする。
```sh
docker compose build
```

いよいよ、viteだ。

```sh
$ docker compose run front npm create vite@latest .
```
　最後に"."をつけるのがミソ。（プロジェクト名でフォルダを作る処理がオミットされるので、frontフォルダ直下に必要ファイル配置が行われる。）なお、当初のフォルダ構成でfrontフォルダの下に予めnode_modulesフォルダを作っておいたのは、筆者の好みの問題。
 画面の指示にしたがって、Vue3でもReactでも好みのものを選択して進める。


 　以上で環境構築準備完了。

# 環境の利用

```sh
$ docker compose up
```

これで、 localhost:3000 (Rails6)、localhost:8110（Vite）、localhost:8005（PGAdmin4）にアクセスできる。

# 参考
 docker build したときに、Warningが表示される。
 ```sh
 WARN[0000] buildx: failed to read current commit information with git rev-parse --is-inside-work-tree 
 ```
 git のコマンドの実行について、docker が何かいいたけだ・・・ということしかわからない。軽く調べてみたが、gitの実行環境設定で表示されなくなるものらしい。・・・Warningだから解決しなくてもいいか、と放置することにした。

# まとめ
　Dockerを使ってRubyOnRails(6)+Viteの、ローカルでの開発環境の雛形を作ることができた。この調査、構築作業だけで、丸２日かかった。時間がかかった作業については、Qiitaに書きたくなるものだ。