さぁDockerを始めよう
Dockerに関しての入門記事。ここにあるfileは動作確認はしておりません。
こんなあなたに
- 開発環境を構築するのが非常にしんどい
- グループで開発しているが後輩がまだステージング領域の環境構築ができない
- グループで開発環境を一致させたい
Dockerならできること
-
apacheなどミドルウェアのインストールが楽チン
DockerHubから公式のイメージを引っ張ってきてコンテナを作るだけ。 -
あ、このミドルウェア削除したい。...けど色々依存関係を削除するの面倒い。
コンテナを削除するだけで、依存関係をすべて削除できる。クリーンな環境を提供。 -
Dockerの知識を覚えるのが面倒?Dockerなら次の1行でnginxを導入できます
docker container run -d -p 80:80 nginx
利点に関してはこちらの記事にとてもよくまとまっています。
Docker導入のための、コンテナの利点を解説した説得資料
Web開発知識
Docker概要
Dockerの仕組み自体は以下のサイトで確認してください。ぶっちゃけ下のサイトみたらこの記事読まなくても良い。
CentOSへの導入の仕方
CentOS7への導入の仕方は3通りあります。詳しくは公式のホームページを参照ください。こんかいは1のリポジトリを使ったインストールを前提とします。解説は優秀な記事に丸投げで。
- リポジトリを使ったインストール
- パッケージからのインストール
- 便利なスクリプトを使ったインストール
リポジトリを使ったインストール
公式のホームページ
qiita CentOS7にDockerをインストールする
Docker Hello World
ダウンロードしたら早速Dockerが使えるかHello World
をしましょう。
docker run hello-world
すると下のような画面がでたらインストール成功です.
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
Dockerを構成するものたち
Container
Dockerの肝となる機能。OS上に論理的な区画分けを作る。そこでアプリケーションやライブラリを1つにまとめ、あたかも1つのサーバーであるように動かす。
Image
昔IT関連の本にはソフトをダウンロードするCDが付いていた。ImageとはそのようなCDを想像してほしい。コンテナを作るひな形になる。その中身は、アプリケーションの実行に必要なファイル群を含むディレクトリである。Dockerコマンドを使うとimageをtarファイルに出力できる。
環境構築の方針としては、まず必要なイメージ(railsやmysqlなど)をDockerHubから引っ張ってきてそれを元にコンテナを作っていく。このとき後述のDockerComposeを使う。
Volume
containerは簡単に作成・削除ができるようになっており、containerを停止すると初期ファイル以外の内容が飛んでしまう。つまり途中で付け加えるデータ(データベースなど)はcontainer以外の部分に避難させなければならない。それがVollumeである。ちなみにこのVolumeに接続することをマウントするという。
また同様の理由から、railsのbundle install
はサーバーを再起動させる(Dockerのcontainerをリビルドする)必要がある。そうしないとせっかくbundle install
してもcontainerを停止するとライブラリの内容は飛んでしまう。
Dockerfile
DockerfileとはDockerのコンテナの設計図。DockerでHello world
したようにDockerは設計図を書かなくてもコマンドからコンテナを作成できる。しかし現在の構成を全体で共有する時やメンテナンスの点から見てもDockerfileを書くべき。以下の命令リストを見ながら実際のDockerfileを解読してみよう。
コマンドの説明は「プログラマのためのDocker教科書 第2版」を参照。
命令 | 説明 |
---|---|
FROM | ベースイメージの指定 |
RUN | コマンド実行 |
CMD | コンテナの実行コマンド |
LABEL | ラベルを指定 |
EXPOSE | ポートのエクスポート |
ENV | 環境変数 |
ADD | ファイル/ディレクトリの追加 |
COPY | ファイルのコピー |
ENTRYPOINT | コンテナの実行コマンド |
VOLUME | ボリュームのマウント |
USER | ユーザーの指定 |
WORKDIR | 作業ディレクトリ |
ARG | Dockerfile内の変数 |
ONBUILD | ビルド完了後に実行される命令 |
STOPSIGINAL | システムコンールシグナルの設定 |
HEALTHCHECK | コンテナのヘルスチェック |
SHELL | デフォルトシェルの設定 |
railsコンテナ
FROM ruby:2.5.1
RUN apt-get update -qq && \
apt-get install -y apt-utils \
build-essential \
libpq-dev \
nodejs \
mysql-client
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install -j4
ADD . /app
EXPOSE 3000
mysqlコンテナ
FROM mysql:8.0
RUN apt-get update && \
apt-get install -y apt-utils \
locales && \
rm -rf /var/lib/apt/lists/* && \
echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
ADD ./docker/mysql/charset.cnf /etc/mysql/conf.d/charset.cnf
nginxコンテナ
FROM nginx:1.11
RUN apt-get update && \
apt-get install -y apt-utils \
locales && \
sed -i -e 's/# ja_JP.UTF-8/ja_JP.UTF-8/g' /etc/locale.gen && \
locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LC_TIME C
ADD ./docker/nginx/nginx.conf /etc/nginx/nginx.conf
ADD ./docker/nginx/rails.conf /etc/nginx/conf.d/default.conf
Docker composeを使う
通常web開発するとき以下のものが必要になってくる。
- ウェブサーバー
- アプリケーションサーバー
- railsなどのフレームワーク
- データベース
- redis
- elasticsearch
これらを同一のDockerfileに書き込むとメンテンアンス性も下がる膨大なコンテナができてしまう。公式でも1つのコンテナに1つのミドルウェアを推奨している。そして、複数のコンテナを利用するのに便利なソフトがDockerComposeだ。DockerComposeファイルにそれぞれcontainerの起動の仕方をyaml形式で書いていく。Dockerfileを利用もできる。基本的なキーの意味は以下の通り。
version: '2'
services:
db:
image: postgres
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
キー | 説明 |
---|---|
version | Compose定義ファイルのバージョン。DockerEngineのバージョンに依存する. |
services | 管理したいコンテナのサービスを定義 |
networks | 管理したいコンテナのネットワークを定義 |
volumes | 管理したいコンテナのボリュームを定義 |
image | imageを指定 |
build | イメージの構成をDockerfileに記述している場合、それを自動でビルドしてベースイメージに指定するときはbuildを指定する。Dockerfileのパスを指定する。 |
command | コンテナ内で動かすコマンドの指定をする。 |
entrypoint | entrypointを上書きする。 |
links | コンテナ間の連携。連携先のコンテナ名を記述する。サービス名に別名をつけたいときは「サービス名:別名」を設定 |
volumes | コンテナのデータを管理する。接続先のボリュームのパスを指定する。 |
volumes_from | 別のコンテナからすべてのボリュームをマウントするときに、コンテナ名を指定する。 |
ports | コンテナ間の通信。公開するポート番号を指定するか、「ホストマシンのポート番号:コンテナのポート番号」とする。ホストマシンのポート番号を指定しない場合、ランダムな値が設定される。 |
exports | ホストマシンへポートを公開せず、リンク機能を使って連携するコンテナのみポートを後悔するときに指定する。ログサーバーなど、webアプリケーションサーバー機能を持つコンテナを介してのみアクセスを行いたいときに使う。 |
depends_on | サービスの依存関係を定義。依存先コンテナ名を書いておくことで順番に起動される。しかしコンテナの開始の順序を制御するだけで依存先のアプリケーションが利用可能になるまで待つわけではない。 |
environment | コンテナの環境変数を定義 |
env_file | 環境変数ファイルを読み込む |
container_name | コンテナの情報設定。DockerComposeで生成されるコンテナに名前をつける。 |
labels | コンテナにラベルをつける |
DockerComposeのインストール
公式サイト参照
Dockerとrailsとmysql
この記事を参考に初心者向けに解説。ちなみにミドルウェアがどれが良いかは省略。
nginx + Rails (unicorn) + MySQL 環境を Docker で構築する
なおwebサーバーやappサーバーの違いはジャスティンさんの記事が秀逸.
A Web Server vs. an App Server
その他応用的な知識
- docker machine
- docker swarm