前回、「Dockerfileの書き方」を解説しました。
今回は、RailsとMySQLそれぞれのDockerfileからコンテナを起動させ、「Dockerネットワーク(docker network)」を使ってコンテナ間通信をしてみましょう。
- Dockerネットワークの作成
- MySQLコンテナの作成と起動
- Railsコンテナの作成と起動
- ブラウザからRailsに接続
コンテナ間で通信する方法は、Dockerネットワークを使った方法以外にも、「--link」オプションをコンテナ起動時に指定する方法があります。
ですが、この「--link」オプションは公式で非推奨とされているため、ここでは紹介しません。

もくじ
Dockerネットワークの作成
Dockerネットワーク(docker network)とは、複数のDockerコンテナをまとめて管理するための仕組みです。
Dockerネットワークを利用することで、コンテナにつけた名前を「ホスト名」として指定できるようになり、コンテナ間での通信が簡単に実現できるようになります。
サクッと作成できるので、まずはDockerネットワークを作ってみましょう。
$ Dockerネットワーク作成
$ docker network create test-network
# Dockerネットワーク一覧
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
0061ad21155a bridge bridge local
52c761fea972 host host local
a3a448796918 none null local
9d32fabfc11d test-network bridge local
MySQLのイメージ作成からコンテナ起動まで
次に、Railsと接続するために使うMySQLのコンテナを起動させましょう。
ここでは、新しく「docker」ディレクトリを作成し、以下のような構成でファイルを準備したあと、MySQLコンテナを起動させます。
docker
└── mysql
├── Dockerfile
└── app.cnf
MySQLのDockerfileを作成
まずは、MySQLのイメージを作るためにDockerfileを作成します。
ここでは「MySQL8.0」をベースイメージを使用しますが、1つだけ注意することがあります。
コメントにも書いてありますが、MySQL8.0のデフォルト認証方式のままだとエラーが発生するため、MySQL5.7以前の認証方式に変更します。
# MySQLをインストール
FROM mysql:8.0
# Railsから接続する際に「Authentication plugin 'caching_sha2_password' cannot be loaded:」とエラーが発生するため
# Mysqlの認証方式を「caching_sha2_password」から「mysql_native_password」に変更
COPY app.cnf /etc/mysql/conf.d/app.cnf
「COPY」コマンドでホストマシンにある「app.cnf」ファイルをコンテナにコピーしています。
「app.cnf」ファイルは、僕が作ったMySQLの設定ファイルです。
[mysqld]
default_authentication_plugin= mysql_native_password

MySQLコンテナの作成と起動
MySQLのイメージを作成し、コンテナの作成と起動をおこないます。
注目してほしいところは、「--network」オプションで、さきほど作ったDockerネットワークを指定しているところです。
これにより、指定されたネットワークの中でMySQLコンテナが起動します。
また、コンテナを作成する際に「-e」オプションでMySQLのパスワードを設定しています。
「-e」オプションは「environment(環境)」の略で、コンテナ内で利用する環境変数を設定できます。
# 移動
cd /path/to/docker
# Dockerイメージ作成(ビルド)
$ docker build -t mysql ./mysql
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM mysql:8.0
8.0: Pulling from library/mysql
Digest: sha256:415ac63da0ae6725d5aefc9669a1c02f39a00c574fdbc478dfd08db1e97c8f1b
Status: Downloaded newer image for mysql:8.0
---> c7109f74d339
Step 2/2 : COPY app.cnf /etc/mysql/conf.d/app.cnf
---> bfb0496f17cf
:
:
# MySQLコンテナの作成と起動
$ docker run --name mysql --network test-network -e MYSQL_ROOT_PASSWORD=root -d mysql
56368bf5241f6be8ebe85996cac852cbed2e2998a44bdcad237176a4de232333
# コンテナを確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56368bf5241f mysql "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp mysql
Railsのイメージ作成からコンテナの起動まで
ここでは、Rubyのベースイメージを使ってRailsイメージを作成します。
Dcokerビルドに必要な以下のファイルを準備し、Dockerイメージを作成することで、最終的にRailsコンテナが起動します。
docker
└── rails
├── Dockerfile
├── Gemfile
├── Gemfile.lock
└── config
└── database.yml
RailsのDockerfileを作成
まずは、基本となるDockerfileを作成します。
Rubyのベースイメージを使い、その上にRails環境を構築するためのコマンドを記述していきます。
何をしているかは、各命令コマンドのコメントを読んでもらえると理解できると思います。
# Rubyをインストール
FROM ruby:2.6
# 必要なパッケージをインストール
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
&& apt-get install -y nodejs
# 公式では以下のコマンドを推奨しているが、nodeのバージョンが低くBootstrapが使えない
# RUN apt-get update -qq && apt-get install -y nodejs
# 環境変数を設定
ENV APP_HOME /app
# ディレクトリの作成と移動
WORKDIR $APP_HOME
# ホストのGemfileなどをコンテナへコピー
COPY Gemfile $APP_HOME/Gemfile
COPY Gemfile.lock $APP_HOME/Gemfile.lock
# BundlerでGemをインストール
RUN bundle install
# Railsアプリを作成(新規でアプリを作成する場合のみ)
RUN rails new . --database=mysql
# DBの設定ファイル書き換え(新規でアプリを作成する場合のみ)
COPY ./config $APP_HOME/config
# 3000番ポート解放
EXPOSE 3000
# コンテナ起動時にRailsサーバを起動
CMD ["rails", "server", "-b", "0.0.0.0"]
Dockerfileで必要となる「Gemfile」と「Gemfile.lock」を作成します。
「Gemfile.lock」は空ファイルを作成(ファイルだけ用意)し、「Gemfile」は新しくRailsをインストールするための記述をします。
$ source 'https://rubygems.org'
gem 'rails', '5.2.3'

次に、RailsからMySQLへのアクセスに必要な設定ファイルを作成します。
以下は、Railsで自動生成される「database.yml」をベースに、「password」や「host」を変更したものです。
同じDockerネットワークの中でRailsとMySQLのコンテナを起動させる予定なので、「database.yml」の中でもMySQLのコンテナ名(ホスト名)を指定できるようになります。
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: root
host: mysql
development:
<<: *default
database: app_development
test:
<<: *default
database: app_test
production:
<<: *default
database: app_production
username: app
password: <%= ENV['APP_DATABASE_PASSWORD'] %>
Railsコンテナの作成と起動
RailsのDockerfileが準備できたら、あとはビルドしてRailsコンテナを起動してみましょう。
MySQL同様、コンテナ起動時に「--network」オプションでDockerネットワークを指定しています。
# 移動
cd /path/to/docker
# Railsイメージ作成(ビルド)
$ docker build -t rails ./rails
Sending build context to Docker daemon 5.632kB
Step 1/11 : FROM ruby:2.6
2.6: Pulling from library/ruby
Digest: sha256:90e8ee6a35bdecdb67cb1d5f0333c79604eab86b7a5a6ad2417378a216f7a316
Status: Downloaded newer image for ruby:2.6
---> 877a53569182
Step 2/11 : RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - && apt-get install -y nodejs
---> bb4c92a7781e
Step 3/11 : ENV APP_HOME /app
---> fe301413b470
Step 4/11 : WORKDIR $APP_HOME
---> Running in d9e435494245
Removing intermediate container d9e435494245
---> 6d74e94e6f71
Step 5/11 : COPY Gemfile $APP_HOME/Gemfile
---> 66c9af8d1539
Step 6/11 : COPY Gemfile.lock $APP_HOME/Gemfile.lock
---> 6db2c578f0eb
Step 7/11 : RUN bundle install
---> Running in 317163df5cea
:
:
Step 8/11 : RUN rails new . --database=mysql
---> Running in 852135468e53
:
:
Step 9/11 : COPY ./config $APP_HOME/config
---> 27b6c946f4cb
Step 10/11 : EXPOSE 3000
---> Running in f4299b8b396c
Removing intermediate container f4299b8b396c
---> 9b338a9b57f7
Step 11/11 : CMD ["rails", "server", "-b", "0.0.0.0"]
---> Running in f6b55d845e1b
:
:
# Railsコンテナの作成と起動
$ docker run --name rails --network test-network -p 3000:3000 -d rails
216f34ddf82f11f16c8829eba1e790cd3a482ed485eeaf94c70a9a4e674bda2e
# コンテナを確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
216f34ddf82f rails "rails server -b 0.0…" 59 seconds ago Up 58 seconds 0.0.0.0:3000->3000/tcp rails
56368bf5241f mysql "docker-entrypoint.s…" 13 minutes ago Up 13 minutes 3306/tcp, 33060/tcp mysql
コンテナ間通信の確認(ブラウザから接続)
RailsとMySQLのコンテナが起動した状態で「http://IPアドレス:3000」に接続すると、上のようなエラーが表示されると思います。
これは、MySQLコンテナにRails用のデータが存在しないために起こっています。
このエラーを解消するためには、Railsコンテナにログインし、データベースを作成するRailsコマンドを実行する必要があります。
# Railsコンテナにログイン
$ docker exec -it rails bash
root@216f34ddf82f:/app#
# Railsコマンドでデータベースを作成
$ rails db:create
Created database 'app_development'
Created database 'app_test'

コマンドを実行すると、上のようなRailsの初期画面が表示されたはずです。
これで、Dockerネットワークを使った「Rails」と「MySQL」のコンテナ間通信ができました。
まとめ:より実践的なDockerを使い方を学ぼう!
ここでは、Dockerネットワークを学ぶために、RailsとMySQLのコンテナ間で通信をしてみました。
Dockerネットワークの仕組み自体は、そこまで難しくないのですが、記事を書きながら「Dockerfileのほうが難しいな」と感じるところがありました。
Dockerfileを書くためには、Linuxなどのインフラ知識が必須となるため、「ちょっと難しいかも」と感じた方は、Vagrantなどを使ってLinuxに慣れてから始めてみましょう。

次は「Docker Composeの使い方」を読んで、より実用的なコンテナ間通信をおこないます。
またね、キツネ(@kitaaaa_kitsune)でした!

