42
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

docker-composeを使った開発環境構築実践! Rails + Nuxt.js + MySQLを動かす

はじめに

docker-composeを使ったローカル開発環境構築について解説します!

ここでは、フロントエンドにNuxt.js, バックエンドにRails, DBにMySQLを使った構成にします。

YouTube動画

動画で確認したい方はこちらもどうぞ!
【YouTube動画】 docker-compose による開発環境構築入門
docker-compose による開発環境構築入門

GitHub

GitHubにコードを載せているので、実際に動かしてみたい方はこちらもどうぞ!
https://github.com/yassun-youtube/docker-compose-sample

git clone git@github.com:yassun-youtube/docker-compose-sample.git


実際のコード
docker-compose.yml
version: "3.8"
services:
  rails:
    build: ./rails-sample
    ports:
      - 3000:3000
    volumes:
      - ./rails-sample:/app
      - /app/node_modules
    stdin_open: true
    tty: true
    command: sh -c "yarn && bundle exec rails server -b 0.0.0.0 -p 3000"
    depends_on:
      - mysql
  nuxt:
    build: ./nuxt-sample
    ports:
      - 8000:8000
    volumes:
      - ./nuxt-sample:/app
      - /app/node_modules
    command: sh -c "yarn && yarn dev"
  mysql:
    image: mysql:8.0.22
    volumes:
      - db-data:/var/lib/mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      MYSQL_ROOT_HOST: '%'
      MYSQL_DATABASE: test-database
volumes:
  db-data:
# ./nuxt-sample/Dockerfile
FROM node:14.15.1-alpine3.12

WORKDIR /app

COPY package.json yarn.lock ./

RUN yarn install

CMD ["yarn", "dev"]
# ./rails-sample/Dockerfile
FROM ruby:2.7.1-alpine

RUN set -x && apk add --no-cache \
                      # for mysql
                      mysql-dev \
                      # for nokogiri
                      build-base \
                      # for tzinfo-data
                      tzdata \
                      yarn
WORKDIR /app

COPY Gemfile Gemfile.lock package.json yarn.lock ./

RUN bundle install
RUN yarn install

CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]
database.yml
default: &default
  adapter: mysql2
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  username: root
  password:
  database: rails-sample-dev
  host: mysql

test:
  <<: *default
  username: root
  password:
  database: rails-sample-test
  host: mysql
nuxt.config.js
...
  proxy: {
    '/api': 'http://rails:3000'
  },
...


docker-composeとは

docker-composeとは複数コンテナやネットワーク、ボリュームを一括管理できるツールです。
Dockerをインストールすれば、ついてくるので、別途インストールする必要はありません。

よく使うコマンド

docker-composeでよく使うコマンドを紹介します。

docker-compose up

docker-compose.ymlに記載されたコンテナを起動するために使います。
-d オプションを付けると、デタッチモードで起動します。

docker-compose down

起動したコンテナを停止して削除するときに使います。
削除しない場合は、CTRL + Cを押すか docker-compose stopで止めることができます。

コンテナをデタッチモードで動かしているときは、docker-compose psと併用して使います。

docker-compose build

docker-compose.ymlに記載されたサービス (nuxtとかrails, mysql) をビルドするときに使います。
ymlファイル内のimage:またはbuildに書かれているパスにあるDockerfileのイメージを参照して、ビルドを開始します。

docker-compose run <サービス名> <コマンド>

docker-compose.ymlに記載されたサービスを指定してコマンドを実行するときに使います。

docker-compose exec <サービス名> <コマンド>

既に起動しているコンテナを指定して、コマンドを実行するときに使います。

docker-compose.ymlの概要

docker-compose.ymlで指定できる、version services networks volumesについて紹介します。

version

docker-composeの書き方のバージョンを指定するときに使います。
この記事を書いている段階 (2020/11/29) では、3.8です。

services

コンテナを定義するために使います。
ここで、railsとかnuxt, mysqlのDockerfileを指定したり、イメージを直接指定して使います。

networks

各サービスがどのネットワークと接続するかを定義できます。

volumes

ホストOSとゲストOSでデータを同期するときに使います。
今回はMySQLのデータを同期するために使います。

実際の設定ファイル

実際の設定ファイルは以下のようになります。

docker-compose.yml
version: "3.8"
services:
  rails:
    build: ./rails-sample
    ports:
      - 3000:3000
    volumes:
      - ./rails-sample:/app
      - /app/node_modules
    stdin_open: true
    tty: true
    command: sh -c "yarn && bundle exec rails server -b 0.0.0.0 -p 3000"
    depends_on:
      - mysql
  nuxt:
    build: ./nuxt-sample
    ports:
      - 8000:8000
    volumes:
      - ./nuxt-sample:/app
      - /app/node_modules
    command: sh -c "yarn && yarn dev"
  mysql:
    image: mysql:8.0.22
    volumes:
      - db-data:/var/lib/mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      MYSQL_ROOT_HOST: '%'
      MYSQL_DATABASE: test-database
volumes:
  db-data:

大枠の設定

上記設定ファイルの大枠をみていきます。
設定ファイルはバージョン3.8を利用し、サービスにはrails, nuxt, mysqlを指定しています。
DBのデータを同期するために、volumes: db-data:を指定しています。

docker-compose.yml
version: "3.8"
services:
  rails: ...
  nuxt: ...
  mysql: ...
volumes:
  db-data:

services: mysqlの設定

imageでMySQL 8.0.22のDockerイメージを取得し、volumesでデータを同期しています。
environmentで環境変数を設定でき、ここではrailsからROOTユーザーとして、アクセスできるようにしています。
また、作成するDB名はtest-databaseとしました。

docker-compose.yml
mysql:
  image: mysql:8.0.22
  volumes:
    - db-data:/var/lib/mysql
  environment:
    MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    MYSQL_ROOT_HOST: '%'
    MYSQL_DATABASE: test-database

services: nuxtの設定

nuxtは別途Dockerfileを作成し、そこからイメージを取るようにしました。
Dockerfileの場所をbuildで指定しています。

portsでは、ホストOSの8000ポートとゲストOSの8000ポートを繋げる設定をしています。

volumesの1行目./nuxt-sample:/appは、ホストOSのnuxt-sampleをゲストOSのappと同期するための設定です。
2行目の/app/node_modulesはホストOSのnode_moduleとゲストOSのnode_moduleを同期しないための設定です。
node_modulesはOS依存のパッケージが入る可能性があるので、このように除外しています。

commandでは、コンテナ起動時にシェルで実行するコマンドを設定しています。
node_modulesを作るために、yarnを実行し、yarn devでnuxtを起動しています。

docker-compose.yml
nuxt:
  build: ./nuxt-sample
  ports:
    - 8000:8000
  volumes:
    - ./nuxt-sample:/app
    - /app/node_modules
  command: sh -c "yarn && yarn dev"

次にDockerfileをみていきます。
FROMで使用するDockerイメージを指定します。
開発環境なので、軽量なalpineにしています。

WORKDIRで以後、コマンドを実行するディレクトリを指定します。

COPY, RUN, CMDでパッケージをゲストOSにコピーし、yarn, yarn devを実行しています。
docker-compose.yml側で同じ設定をしているので、なくても大丈夫です。

# ./nuxt-sample/Dockerfile
FROM node:14.15.1-alpine3.12

WORKDIR /app

COPY package.json yarn.lock ./

RUN yarn install

CMD ["yarn", "dev"]

services: railsの設定

build, ports, volumesは先ほどと同じような意味です。

dockerでbinding.pryなどのデバッグができるように、stdin_open: truetty: trueを指定しています。

depends_onでは、mysqlを指定し、mysqlのコンテナが起動するまではrailsのコンテナが起動しないようにしています。

docker-compose.yml
rails:
  build: ./rails-sample
  ports:
    - 3000:3000
  volumes:
    - ./rails-sample:/app
    - /app/node_modules
  stdin_open: true
  tty: true
  command: sh -c "yarn && bundle exec rails server -b 0.0.0.0 -p 3000"
  depends_on:
    - mysql

Dockerfileの方もnuxtと同じように依存パッケージをインストールして、railsサーバーを起動しています。

# ./rails-sample/Dockerfile
FROM ruby:2.7.1-alpine

RUN set -x && apk add --no-cache \
                      # for mysql
                      mysql-dev \
                      # for nokogiri
                      build-base \
                      # for tzinfo-data
                      tzdata \
                      yarn
WORKDIR /app

COPY Gemfile Gemfile.lock package.json yarn.lock ./

RUN bundle install
RUN yarn install

CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]

database.ymlの設定

RailsサーバーとMySQLを接続するために、docker-compose.ymlのサービスで指定している名前をdatabase.ymlで設定する必要があります。

services: mysqlと設定していたので、database.ymlのhostにもmysqlと設定しておきます。

database.yml
default: &default
  adapter: mysql2
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  username: root
  password:
  database: rails-sample-dev
  host: mysql

test:
  <<: *default
  username: root
  password:
  database: rails-sample-test
  host: mysql

nuxt.config.jsの設定

NuxtからRailsにプロキシしたい場合は、nuxt.config.jsのproxyにサービス名を記述するだけでプロキシできます。

nuxt.config.js
...
  proxy: {
    '/api': 'http://rails:3000'
  },
...

おわりに

実際にコードを見ながら、動かしながら学んだ方が理解が深まると思うので、ぜひGitHubのリポジトリもご確認ください!
https://github.com/yassun-youtube/docker-compose-sample

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
42
Help us understand the problem. What are the problem?