12
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DockerでつくるRails6 + Vue3 + PostgreSQLの開発環境

Posted at

はじめに

ここまで以下の記事のとおり、Rails6 + PostgreSQLVue3の開発環境をDockerでそれぞれ構築してきました。

今回は、それぞれ構築したこの開発環境をDocker Composeを使って、まとめて管理できるようにしていきたいと思います。

目次

1. ディレクトリの構成
2. 完成したファイル
3. front/Dockerfileの修正
4. dockercompose.ymlの修正
5. 動作確認
6. さいごに

1. ディレクトリの構成

準備したファイルは以下のとおり、各ディレクトリに配置しています。

.
├── api
│   ├── Gemfile
│   ├── Gemfile.lock
│   ├── Dockerfile
│   └── entrypoint.sh
├── front
│   └── Dockerfile
└── dockercompose.yml
    

2. 完成したファイル

今回は最初に完成形のファイルをお示しした上で、前回までの記事で作成したファイルをどのように考え、どのように修正したかという点について、述べていきたいと思います。

./api/Gemfile
source 'https://rubygems.org'

gem 'rails', '~> 6.1'

./api/Gemfile.lock
# 何も書きません
./api/Dockerfile
FROM ruby:3.0

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

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

RUN bundle install


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"]
.api/entrypoint.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 "$@"

./front/Dockerfile
FROM node:16.16

RUN apt-get update -qq && yarn global add @vue/cli

WORKDIR /app
COPY . /app

CMD ["yarn", "serve"]
./dockercompose.yml
version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - postgresql_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password

  api:
    build: ./api
    volumes:
      - ./api:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

  front:
    build: ./front
    volumes:
      - ./front:/app
    ports:
      - "8080:8080"

volumes:
  postgresql_data:

3. front/Dockerfileの修正

前回の記事で作成していたDockerfileでは、最後のコマンドを

CMD ["/bin/bash"]

としていましたが、次のように修正しました。

CMD ["yarn", "serve"]

DockerfileのCMDはコンテナ起動時に実行するコマンドです。
前回の記事では、コンテナ内でコマンドを実行してVueのインストールなどを試していたので、bashを起動させるようにしていましたが、実際に開発を進める時は、コンテナを起動させるとVueプロジェクトのサーバーに立ち上がってほしいので、上記のように修正しました。

4. dockercompose.ymlの修正

今回、先に作成していたRails6 + PostgreSQLの環境にVue3を追加するにあたって、主に修正したのはdockercompose.ymlとなります。

もともと作成していたdockercompose.ymlは次のとおりです。

dockercompose.yml
version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

dbコンテナのvolumes

以前の設定では、DBのデータはホスト側の./tmp/dbにマウントしていましたが、volumesを使ってDocker側で管理することにしました。
Docker側で管理することのメリットは公式で以下のとおり説明されています。

  • ボリュームはバインドマウントよりも、バックアップや移行が容易です。
  • ボリュームは Docker CLI コマンドや Docker API を利用して管理することができます。
  • ボリュームは Linux と Windows 上のコンテナーにおいて動作します。
  • ボリュームは複数コンテナー間にて安全に共有できます。
  • ボリュームドライバーを用いると、リモートホスト上、あるいはクラウドプロバイダー上のボリュームに保存できるようになります。保存の際にはボリューム内データを暗号化することができ、その他にも種々の機能を利用することができます。
  • ボリュームを新たに生成すると、その内容はコンテナーがあらかじめ用意していた内容になります。
  • Docker Desktop 上のボリュームは、Mac や Windows ホストからのバインドマウントに比べて、より高い性能を実現します。

次のとおりvolumesを作成、作成したvolumesへのマウントを行っています。

# volumesを作成
volumes:
  postgresql_data:
# volumesへのマウント
 volumes:
      - postgresql_data:/var/lib/postgresql/data

apiコンテナのcommandを削除

dockercompose.ymlから次の箇所を削除しました。

command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

dockercompose.ymlのcommanddocker composeでコンテナを起動したとき、DockerfileのCMDを上書きして実行されます。

そのため、同じことを書いているのであれば、Dockerfileの

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

と、dockercompose.ymlの

command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

はいずれか一方でいいのではないかと考えました。

開発時のコンテナの起動はdocker compose使うつもりだったので、当初は「dockercompose.ymlに書いてあったら十分だな。Dockerfileを修正しよう。」と考えていましたが、公式で以下の記述を見つけたため、dockercompose.ymlを修正することにしました。

Dockerfile は、少なくとも1つの CMD か ENTRYPOINT 命令を書くべきです。

この点については自分なりに調べてこの結論を出しましたが、Docker Composeを使うときもこの公式の記述は適用すべきなのかは自信が持てずにいます。
「dockercompose.ymlに書くべきだ」や「両方に書くべきだ」という意見がありましたら、ぜひコメントをお願いします。

frontコンテナの追加

本来はここがメインになるはずでしたが、いざやってみると、

  • buildでDockerfileのパスを指定
  • volumesでマウント先の設定
  • portsでコンテナの8080ポートをホストの8080ポートに公開
    ということを淡々と設定したのみであっさりと完了しました。

5. 動作確認

まずはDockerのイメージを作成→Railsアプリを作成→Gemfileが更新されたのでイメージの再作成をします。

$ docker compose build
$ docker compose run --rm --no-deps api rails new . -f -T --api --database=postgresql
$ docker compose build

次にdatabase.ymlの設定をして、DBを作成します。

database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: 5

development:
  <<: *default
  database: api_development


test:
  <<: *default
  database: api_test
$ docker compose run --rm api rails db:create        

これでRailsアプリの作成は完了したので、次にVueプロジェクトを作成します。

$ docker compose run --rm front vue create .

Vue CLI v5.0.8
? Generate project in current directory? (Y/n) Y
? Please pick a preset: (Use arrow keys)
❯ Default ([Vue 3] babel, eslint) 
? Pick the package manager to use when installing dependencies: (Use arrow keys)
❯ Use Yarn 

さて、準備ができたの、コンテナを起動させます。

$ docker compose up

localhost:3000localhost:8080にアクセスすると、それぞれのウェルカムページが出迎えてくれます。

無事、DockerでRails6 + Vue3 + PostgreSQLの開発環境を構築することができました!

おまけ

Rails、Vueのウェルカムページが出迎えてくれたので、大丈夫な気がしつつも、本当にこれで開発を進めていける環境が構築できたのか少し不安な気持ちもありました。
なので、以前、某教材で作成したRails + Vueのリアルタイムチャットアプリにこの開発環境を導入してみることにしました。
アプリ内に、今回作成したDocker関連のファイルを配置して、コンテナを起動させてみます。

…特に問題なく動作する。大丈夫そうだ。

6. さいごに

これで長かった環境構築も一段落しました。
ここから先は実際に開発を進める中で必要に応じて、変更を加えていきたいと思います。

一方で、まだDockerを使ってやってみたいなと思うことは残っています。
今、関心があるのは、ベースイメージにslimを使って自分で必要なライブラリをインストールし、イメージサイズを抑えるということです。

こんな風に実際に手を動かす中で関心のあることは増えていくのですが、すべてに手を出していたら時間がいくらあっても足りません。
やっぱり、目的意識を持つことが、学習効率をとっても、時間効率をとっても重要だなとしみじみと感じているところです。

12
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?