Railsで開発した個人アプリに、後からDockerを導入しました。
その時知識不足なせいでハマってしまった場面があったので、自分の中で整理してアウトプットすることを目的にこの記事を書き残します。
ちなみに、以下の記事を主に参考にさせていただきました。
DockerをMacにインストールする
Docker + Rails + Puma + Nginx + MySQL
RailsアプリにDockerを導入する手順+事前知識
まずは事前知識として、これは知っておいたほうがいいというものを簡単に書いていきます。
事前知識 - Docker関係
Docker(ドッカー)
※1.軽量な仮想化環境を実現するためのツール。
OS やアプリケーションを設定したものを丸ごと実行イメージとして保存できるので、Docker が導入されている別のマシンにそのまま持って行くことができる。
実行環境をテキストファイルとして共有できるのでとても便利。
※1.仮想化環境とは、コンピュータ上にソフトウェアによって仮想的に構築されたコンピュータ(仮想マシン)が備える仕様や機能の総体のこと。
Dockerイメージ
Dockerイメージは、コンテナを起動させるためのベースとなるもの(オブジェクト指向でいうと「クラス」にあたる)
テキストファイル(Dockerfile)からビルドされる。(後に記述)
DockerHub(Docker向けのコンテナ共有サービス)では、既に多くのイメージが公開されている。
Dockerコンテナ
Dockerのコンテナは、 Dockerイメージを元に作成される仮想環境の実行部分(オブジェクト指向でいうと「インスタンス」にあたる)
原則1コンテナ1アプリ。
Dockerfile(ドッカーファイル)
指定したベースのDockerイメージに加える変更を記述するファイル。
Dockerfileを使うことでオリジナルのDockerイメージを作成することができる。
docker-compose(ドッカーコンポーズ)
複数のコンテナから構成されるアプリケーションで、Dockerイメージのビルドや各コンテナの起動・停止などをより簡単に行えるようにするツール。
docker-composeを使用する際は「docker-compose.yml」が必要になる。
事前知識 - サーバ関係
ミドルウェア
OSとアプリケーションの間に入り、中間的な処理を行うソフトウェアのこと。
ー 例 ー
- Webサーバ
- Apache、NginXなど
- APサーバ
- Puma
- Unicornなど
- DBサーバ
- MySQL
- PostgreSQLなど
Nginx(エンジンエックス)
webサーバの一つ。
Apacheよりも処理能力が高い。
puma(プーマ)
※1.Rackという機能を提供するためのアプリケーションサーバ。
webサーバの1つでもある。
※1.RackとはWeb サーバと Rubyやフレームワークをつなぐ最小のインタフェースを提供するもの。
Docker導入手順
① Docker for Macを公式サイトからインストール、そして起動
**公式サイト**で会員登録を済ませた後、Docker for Macをダウンロードしインストール。
インストールが終わったら、Dockerを起動しておく。
(MACの画面上部にDockerのマークが出れば起動できてる証拠)
②作成済みのアプリケーションフォルダの直下に「Dockerfile」、「docker-compose.yml」ファイルを新しく作成する。
フォルダ構成
- 既存のRailsアプリフォルダ
- app
- bin
- config
- db
- ・・・
- Dockerfile
- docker-compose.yml
③Dockerfileに記述する(アプリケーションフォルダ直下)
FROM ruby:2.5.1
RUN apt-get update && \
apt-get install -y mysql-client nodejs vim --no-install-recommends && \
rm -rf /var/lib/apt/lists/*
RUN mkdir /myproject
WORKDIR /myproject
ADD Gemfile /myproject/Gemfile
ADD Gemfile.lock /myproject/Gemfile.lock
RUN gem install bundler
RUN bundle install
ADD . /myproject
RUN mkdir -p tmp/sockets
④docker-compose.ymlに記述する(アプリケーションフォルダ直下)
version: '2'
services:
db:
image: mysql:5.6
environment:
- ./environments/db.env
volumes:
- mysql-data:/var/lib/mysql
ports:
- "4306:3306"
app:
build: .
command: bundle exec puma -C config/puma.rb
volumes:
- .:/myproject
- public-data:/myproject/public
- tmp-data:/myproject/tmp
- log-data:/myproject/log
web:
build:
context: containers/nginx
volumes:
- public-data:/myproject/public
- tmp-data:/myproject/tmp
ports:
- 80:80
volumes:
mysql-data:
public-data:
tmp-data:
log-data:
⑤アプリケーションフォルダ直下に「environments」フォルダを作成、さらにenvironmentsフォルダ直下に「db.env」ファイルを作成する。
- 既存のRailsアプリフォルダ
- app
- bin
- config
- db
-
environments
- db.env
- ・・・
- Dockerfile
- docker-compose.yml
⑥db.envを編集
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=user
MYSQL_PASSWORD=password
⑦database.ymlを編集
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch('MYSQL_USER') { 'root' } %>
password: <%= ENV.fetch('MYSQL_PASSWORD') { 'root' } %>
host: db
⑧アプリケーションフォルダ直下に「containers」フォルダを作成、さらにcontainersフォルダ直下に「nginx」フォルダを作成する。
フォルダ構成
- 既存のRailsアプリフォルダ
- app
- bin
- config
-
containers
- nginx
- db
- environments
- db.env
- ・・・
- Dockerfile
- docker-compose.yml
⑨作成したnginxフォルダ直下に「Dockerfile」、「nginx.conf」ファイルを作成する。
- 既存のRailsアプリフォルダ
- app
- bin
- config
- containers
- nginx
- Dockerfile
- nginx.conf
- nginx
- db
- environments
- db.env
- ・・・
- Dockerfile
- docker-compose.yml
⑩Dockerfileに記述する(containers/nginxフォルダ直下)
FROM nginx:1.15.8
RUN rm -f /etc/nginx/conf.d/*
ADD nginx.conf /etc/nginx/conf.d/myproject.conf
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
⑪nginx.confに記述する(containers/nginxフォルダ直下)
upstream myproject {
server unix:///myproject/tmp/sockets/puma.sock;
}
server {
listen 80;
server_name 13.112.60.229;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root /myproject/public;
client_max_body_size 100m;
error_page 404 /404.html;
error_page 505 502 503 504 /500.html;
try_files $uri/index.html $uri @myproject;
keepalive_timeout 5;
location @myproject {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://myproject;
}
}
⑫puma.rbを編集
app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"
stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true
⑬ターミナルでコマンドを実行
ファイルの準備が整ったら、最後にターミナル上でコマンドを実行。
(railsアプリケーションフォルダ内で実行する)
イメージを構築する
$ docker-compose build
railsのコンテナを作成し、データベースの作成処理を行う
$ docker-compose run --rm app rake db:create db:migrate
全てのコンテナを構築・起動する
$ docker-compose up
上記の流れが終わったあとlocalhostにアクセスすると、しっかり確認することができました。
ちなみに今回書きまとめたものは、DBもDockerで管理することになりますが、DBはローカルのものを参照したいという場合、以下の記事が参考になるかと思います。
既存のRailsアプリをDocker化し、ローカルのDBに接続する方法
(おまけ)
Dockerfileに記述できるコマンド一覧
コマンド | 意味 |
---|---|
FROM | ベースとなるイメージ |
RUN | docker build 時に実行するコマンド |
CMD | docker run 時に実行するコマンド |
ENTRYPOINT | docker run 時に実行するコマンド |
MAINTAINER | 作者情報 |
LABEL | ラベル情報(メタデータ) |
EXPOSE | 公開ポート番号 |
ENV | 環境変数 |
ARG | 一時変数 |
COPY | ホストからコンテナへのファイルコピー |
ADD | ファイル/ディレクトリの追加 |
VOLUME | ボリュームのマウント |
USER | 実行ユーザ |
SHELL | シェル指定 |
WORKDIR | ワークディレクトリ |
ONBUILD | ビルド時に実行するコマンド |
STOPSIGNAL | コンテナ終了時に送信されるシグナル |
HEALTHCHECK | ヘルスチェック |
ターミナル上で実行できるdocker-composeコマンド一覧
コマンド | 意味 |
---|---|
build | サービスの構築または再構築 |
config | compose ファイルの確認と表示 |
create | サービスの作成 |
down | コンテナ・ネットワーク・イメージ・ボリュームの停止と削除 |
events | コンテナからリアルタイムにイベントを受信 |
help | コマンド上でヘルプを表示 |
kill | コンテナを kill (強制停止) |
logs | コンテナの出力を表示 |
pause | サービスを一時停止 |
port | ポートに割り当てる公開用ポートを表示 |
ps | コンテナ一覧 |
pull | サービス用イメージの取得 |
restart | サービスの再起動 |
rm | 停止中のコンテナを削除 |
run | 1度だけコマンドを実行 |
scale | サービス用コンテナの数を指定ド |
start | サービスの開始 |
stop | サービスの停止 |
up | コンテナの作成と開始 |
version | Docker Compose のバージョン情報を表示 |