はじめに
株式会社サイシードのインターンシップにて、Dockerを導入しました。
本稿が少しでもみなさまの参考になれば幸いです。
導入環境
・windows7
・vagrant
Dockerの使い方
Dockerコンテナへのアクセス
vagrant側のポートフォワードを正しく設定して、ホスト側(PC側)からvagrantの
特定のポートにアクセスできるようにする。
コンテナへのアクセスは、以下のように行われる。
PC ⇔ vagrant ⇔ Dockerコンテナ
例えば、
PC ⇔ vagrant
PCとvagrantのIPアドレスとポートフォーワードを以下のように設定
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.network "forwarded_port", guest: 8888, host: 8080
vagrant ⇔ Dockerコンテナ
vagrantとDockerコンテナのポートフォワードを以下のように設定
$ sudo docker run -d -p 8080:3000 tera_shin/centos_test:latest
PCからDockerコンテナへのアクセス
上記のような設定になっている時、PCからvagrantのIPアドレス(192.168.33.10)またはsshアドレス(127.0.0.1)の8888番ポートにアクセスすると、
vagrantの8080番ポートを介して、Dockerコンテナの3000番ポートにアクセスすることができる。
Dockerfileについて
Dockerfileとは
Dockerfileは、Dockerイメージの構成内容をまとめて記述できるファイル。
"docker build"を行う際に参照され、このファイルに記述された内容が実行された上で、
Dockerイメージが作成される。
設定をコードとして明示的に記述することで、ミスを防ぎ変更を容易にすることできる。
1.基本
Dockerfileの基本的な書き方
1行につき1つの操作を"命令"と"引数"でスペース区切りで記述する。
命令 引数
"#"から始まる行はコメントとして処理される。
"docker build"コマンドによって、Dockerfileファイルの上から順番に処理が実行される。
docker build
$ sudo docker build -t Dockerhubのユーザー名/任意のイメージ名 Dockerfileのディレクトリ(今いるディレクトリなら".(ピリオド)")
よく用いる命令の一覧
命令 | 用途 |
---|---|
FROM | 元となるDockerイメージの指定 |
MAINTAINER | 作成者の情報 |
RUN | コマンドの実行 |
COPY | ファイル/ディレクトリの追加 |
CMD | コンテナーの実行コマンド 1 |
ENTRYPOINT | コンテナーの実行コマンド 2 |
WORKDIR | 作業ディレクトリの指定 |
ENV | 環境変数の指定 |
USER | 実行ユーザーの指定 |
EXPOSE | ポートのエクスポート |
VOLUME | ボリュームのマウント |
記述例:
具体的には以下のように記述する。
FROM centos:centos6
MAINTAINER tera_shin <tera_shin@gmail.com>
RUN yum -y update && \
yum install -y \
sudo \
git \
make \
gcc \
gcc-c++ \
httpd
RUN groupadd -r developers && \
useradd -r -g developers developer && \
echo 'developer:1234' | chpasswd && \
echo "developer ALL=(ALL) ALL" >> /etc/sudoers && \
chown -R developer ~/ && \
chown -R developer /usr/share/nginx/html
ENV HOME=/home/developer
WORKDIR $HOME
ENV APP_ROOT=/var/www/html
VOLUME $APP_ROOT
COPY my_app $APP_ROOT/my_app
EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
2."命令"の説明
"命令"のいくつかについて説明します。
(1)FROM
"docker build"でdockerイメージを作成する際の元となるdockerイメージを指定する。
記述例ではcentos:centos6
を指定している。
dockerイメージは、DockerHubで探すこともできる。
(2)MAINTAINER
Dockerfileの作成者についての情報を記述する。
DockerHubのユーザー名とメールアドレスを記述するのが一般的。
(3)RUN
buildしたときに元となるdockerイメージに対して実行する処理を記述する。
\(バックスラッシュ)
を用いて、複数行に分けることもできる。
最新バージョンのパッケージをインストールする際は、
yum update
とyum install -y
を同じRUN
命令文で連結するようにする。
記述例の2つめのRUN
では、グループとユーザーを追加している。
ユーザーを追加しておくと、dockerイメージに対してRUN
などの"命令"を
実行するユーザーを"root"以外にも指定することができる。
実行ユーザーを指定する際は、USER
を用いる。
USER ユーザー名
# 例:
USER developer
(4)ENV
作成するdockerイメージの環境変数を設定することができる。
(5)WORKDIR
処理を実行するディレクトリを指定する。
(6)VOLUME
dockerイメージ内のディレクトリをVOLUME
に指定することができる。
VOLUME
に指定されたディレクトリ内に対して行われるすべての変更は
dockerイメージには含まれない。
作成したdockerイメージをrun
する際に、
VOLUME
に指定されたディレクトリに対してマウントを行うと、
コンテナの停止とともにコンテナのVOLUME
内の変更は破棄される。
また、VOLUME
に指定されたディレクトリに対してマウントを行っている状態で
コンテナをイメージ化すると、
コンテナ内のVOLUME
に指定されたディレクトリはイメージに含まれず、
それ以外がイメージ化されるため、
開発中のアプリケーションと開発環境を分離することができる。
(7)COPY
dockerイメージ内に追加するディレクトリを指定することができる。
以下のように記述する。
COPY ホスト側のディレクトリ dockerイメージ側のディレクトリ
※ホスト側のディレクトリは、
Dockerfileのあるディレクトリからの相対パスでも指定できる。
dockerイメージ側のディレクトリは、絶対パスで記述する。
(8)EXPOSE
コンテナが外部に露出するポートを指定することができる。
EXPOSE
に露出ポートを指定するだけでは、コンテナにアクセスすることはできず、
コンテナの実行時に、さらに-p
または-P
フラグでポートを公開することで、
コンテナへアクセスできるようになる。
(9)CMD
run
時にコンテナ内で実行する処理を記述することができる。
Dockerfileに1つだけ記述できる。
CMDでは、配列内にコンマ区切りでコマンドを記述する。
記述例のCMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
は、以下と同じ意味。
$ /usr/sbin/httpd -D FOREGROUND
Dockerfileで使用しないファイルおよびフォルダの除外方法
Dockerfileからイメージをビルドする場合、Dockerfileの存在するディレクトリの中身は
Dockerに渡される。
不要なファイルまたはフォルダまでも渡してしまうと、その分だけビルドに余計な時間が
かかってしまう。
そこで、 .dockerignoreを利用して、不要なファイルまたはフォルダを指定する。
例:
.rspec
log
tmp
db/*.sqlite3
db/*.sqlite3-journal
vendor/assets
node_modules
※.dockerignoreファイルは、ファイル名を".dockerignore."と指定しすれば作成できる。
docker-composeについて
docker-composeとは
docker-composeとは複数のコンテナからなるdockerアプリケーションを定義・実行するツールで、docker-compose用の設定ファイルを用意してコマンドを実行することで、記述されたコンテナを一気に起動することができる。
1.docker-composeのインストール
参照:Install Docker Compose
Docker Toolboxをインストールしている場合は、docker-composeもインストールされるので、
そのまま利用できる。
そうでない場合は、以下のようにインストールを行う。
(1)docker-composeをインストール
$ curl -L "https://github.com/docker/compose/releases/download/1.11.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
(2)パーミッションを与える
$ chmod +x /usr/local/bin/docker-compose
2.docker-composeの書き方
"docker-compose.yml"というファイルを作成し、YAML形式で記述する。
よく用いる構文の一覧
構文 | 用途 |
---|---|
services | 各serviceの設定を束ねる |
image | 元となるDockerイメージの指定 |
environment | 環境変数の指定 |
volumes | ボリュームの指定 |
ports | ポートフォワードの指定 |
extends | 共通の設定を利用するサービスを指定 |
command | デフォルトのコマンドを上書きする |
links | リンクするサービスを指定 |
build | Dockerfileのあるディレクトリのパスを指定 |
logging | ログを出力する場所を指定 |
記述例:
version: '2'
services:
db:
image: mysql:5.7.17
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
volumes:
- db-data:/var/lib/mysql
redis:
image: redis:3.2.8
volumes:
- ./data/redis:/data
ports:
- '6379:6379'
app:
build:
context: .
dockerfile: Dockerfile.dev
environment:
HOME: $HOME
APP_ROOT: $APP_ROOT
MYAPP_DATABASE_USERNAME: root
MYAPP_DATABASE_HOST: db
REDIS: "//redis:6379"
REDIS_HOST: redis
REDIS_PORT: 6379
web:
extends:
service: app
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
links:
- db
- redis
worker:
extends:
service: app
command: bundle exec sidekiq -q notification
volumes:
- .:/myapp
links:
- db
- redis
volumes:
db-data:
driver: local
3.構文の説明
構文のいくつかについて説明します。
(1)services
各サービスの設定を束ねる。
各サービスの設定はservices
構文の中に記述する。
(2)image
各サービスでrun
する時に利用するdockerイメージを指定することができる。
image
でdockerイメージを指定するか、build
でDockerfileを実行して、
docker-composeの実行とともにdockerイメージを作成し、それを利用する。
(3)volumes
各サービスでrunする時に、マウントするボリュームを指定することができる。
データベースなどのデータを永続化したい場合は、必ず指定する。
記述例では、dockerが管理するボリュームを指定している。
以下のように記述する。
volumes ホスト側のディレクトリ:dockerコンテナのディレクトリ
※ホスト側のディレクトリは、
docker-compose.ymlのあるディレクトリからの相対パスでも指定できる。
dockerコンテナ側のディレクトリは、絶対パスで記述する。
※ボリュームについての詳しい情報を表示したい時は、以下のようにして確認できる。
** (3-1)ボリューム一覧を表示**
$ sudo docker volume ls
** (3-2)ボリュームの詳細を表示**
$ sudo docker volume inspect ボリューム名
(4)ports
各サービスでrun
する時に、ホスト側(vagrant)とコンテナ側でポートフォワードする
ポートを指定することができる。
以下のように記述する。
ports ホスト側のポート:dockerコンテナのポート
(5)extends
サービス間で設定が共通している場合には、extends
を利用して共通化することができる。
extends
で指定したサービスの設定を継承できる。
(6)links
links
を設定すると、そのサービスのIPアドレスのエイリアスとして、サービス名を利用
できるようになる。
コンテナ内の /etc/hosts
の中にサービス名が追加される。
例:
172.17.2.186 db
172.17.2.187 redis
(7)build
Dockerfile のあるディレクトリのパスを指定できる。
docker-compose.ymlがあるディレクトリからの相対パスで指定することもできる。
以下のように指定した場合は、docker-compose.ymlがあるディレクトリを基準に
./Dockerfile
を参照する。
build: .
"Dockerfile"以外のファイル名のDockerfileを指定したい場合は以下のように記述する。
context: .
dockerfile: Dockerfile.prod
contextで、ファイルのパスを指定し、dockerfile
でDockerfileの名前で指定する。
この例では、./Dockerfile.prod
を参照する。
(8)command
デフォルトのコマンドを上書きすることができる。
(9)logging
特に設定しない場合はdriver: json-file
となり、ホストの
/var/lib/docker/containers/*/*-json.log
にログが出力される。
Dockerコンテナを使う
1.Dockerコンテナを作る
実際にDockerを利用する場合は、作成したイメージからまずDockerコンテナを作る。
2.Dockerコンテナにプログラムをマウントする
作成したDockerコンテナに開発中のプログラムをDockerコンテナのボリュームにマウントする。
3.プログラムの開発を行う
ホスト側のプログラムを編集する。
編集内容は、Dockerのマウント機能によってコンテナ側に反映されるため、
Dockerコンテナにアクセスすることで、プログラムの実行内容を確認しながら、
開発を進めることができる。
4.開発環境の共有
開発中に開発環境の変更があった場合も、Dockerコンテナをイメージ化し、
DockerHubにあげることで、他の開発者と開発環境を共有することができる。
Dockerイメージはボリュームの中身を含まないため、DockerHubに上げられた
Dockerイメージを引っ張ってくれば、再び同じようにコンテナを作成し、
開発中のプログラムをマウントすることで、簡単に新しい開発環境で開発を
進めることができる。
参考
http://dotinstall.com/lessons/basic_docker
http://docs.docker.jp/engine/articles/dockerfile_best-practice.html
http://www.atmarkit.co.jp/ait/articles/1407/08/news031.html
http://paiza.hatenablog.com/entry/docker_intro
http://qiita.com/munisystem/items/b0f08b28e8cc26132212
http://qiita.com/pokohide/items/7397b92a188da841b435
http://qiita.com/oshin/items/0d011610238eb4df83fd
http://knowledge.sakura.ad.jp/knowledge/5021/
http://qiita.com/zembutsu/items/9e9d80e05e36e882caaa
最後に
オリジナル音楽の投稿配信サービスMicstackを運営しています。
よろしければご利用ください。