Docker tutorial
The Toolbox installs Docker Client, Machine, Compose and Kitematic.
https://www.docker.com/products/docker-toolbox
Dockerは、Host環境上でDocker Engineを動かし、その上でコンテナをいくつも起動する。 Docker Engineを動かすためのHost OSは、コンテナがLinux Container技術を流用しているためLinuxで無ければならない。 MacやWindowsでDockerを動かすためには必然的に、仮想環境でHost OSを用意する必要がある。
仮想環境はVirtualBox, VMWare, AWS 様々なものが適用することができる。今回はVirtualBoxを利用する。
VituralBoxがインストール出来たら、VirtualBox上でDockerEngineを簡単に作ることが出来るツールdocker-machineを使う。 資料冒頭のdocker tool boxを導入していたらコマンドは既に入っている。
Docker Machine is a tool that lets you install Docker Engine on virtual hosts, and manage the hosts with docker-machine commands. You can use Machine to create Docker hosts on your local Mac or Windows box, on your company network, in your data center, or on cloud providers like AWS or Digital Ocean.
https://docs.docker.com/machine/overview/
# コマンドを入れずに説明を見る
$ docker-machine
# VirtualBoxをドライバとして、defaultという名前でDocker Engineを生成。
$ docker-machine create --driver virtualbox default
# 立ち上がっているDocker Engineを確認
$ docker-machine ls
# 先ほど作ったdefaultの環境を確認
$ docker-machine env default
# ホストマシン(Mac OSX)でdefaultの環境を適用(dockerコマンドを使いたいシェル毎に実行する)
$ eval "$(docker-machine env default)"
# UbuntuコンテナでHello world ubuntu -> busybox と変更すると、とても軽量なコンテナで実行できる。
$ docker run ubuntu /bin/echo 'Hello world'
# Dockerのイメージを確認する
$ docker images
# Dockerのコンテナを確認する
$ docker ps --all
# defaultを消す(練習では色んなイメージがゴミになるので、必ず最後Engineごと消す)
$ docker-machine rm default
Dockerは基本的には、単一のアプリケーション(Webサーバ, プログラム実行, etc...)を動かすためのものだ。 Docker上でアプリケーションが動く仕組を解説していく。
Docker環境上では複数の(単一)アプリケーションを動かすことができる。アプリケーションが動いている環境のことをDocker Containerと呼ぶ。 Containerは、Docker Imageを元にして作られる。Javaのクラスとインスタンスの関係によく似ている。 Hello Worldの説明でした、ubuntuやbusyboxがDocker Imageの例だ。 通常Dockerを利用する場合は、汎用的なOSイメージにアプリケーションを動かすためのパッケージ(言語コンパイラ・インタプリタ, Web Server, etc...) を追加していき、アプリケーションを動かす。 ユーザ自身が一からイメージを育てても良いが、Docker Hubで、公開されているイメージを使っても良い。
Docker ImageをDocker Hubから取得する方法は、pullコマンドを使う。試しにRuby imageのイメージを取得してみよう。
# イメージの名前だけを指定すると最新版のイメージ(latest)が取得できるがコロンを付けることで、タグを指定することが出来る。
$ docker pull ruby:2.3.1
$ docker images
$ docker run -it ruby:2.3.1 irb
もし軽量なイメージを使いたい場合は、Alpine Linuxを使用しているイメージを使うと良いだろう。 ただし、以下で紹介するrubyイメージはirbすら入っていない(パスが通ってないだけで入ってる?)。加えて追加でパッケージを入れる場合は、Alpine Linuxの作法(かなり大変)に従って書く必要があるので注意だ。
docker pull inzinger/alpine-ruby:2.3
Docker Imageだけでアプリケーションを動かせる場合は、Docker pullで引っ張ってきたimageをそのまま利用すれば良い。 しかし、必要なパッケージなどが足りない場合はDockerfileという設定ファイルを記述する必要がある。 Dockerfileを記述することにより新しいイメージを作ることができる。新しいイメージは差分のみが増える。 以下にDockerfileの例を示す。この資料では、Dockerfileの記述に関する説明は省略する。 https://docs.docker.com/engine/reference/builder/
FROM ruby:2.3.1
RUN gem install bundler
RUN gem install foreman
COPY . /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY config.ru /app/config.ru
COPY Procfile /app/Procfile
EXPOSE 4567
RUN bundler
CMD ["foreman", "start", "-d", "/app", "-f", "/app/Procfile", "-p", "4567"]
それでは実際にDockerfileからimageを生成してみよう。以下のリポジトリを手元にcloneしよう。 https://github.com/ababup1192/docker-sinatra
$ git clone https://github.com/ababup1192/docker-sinatra.git
$ cd docker-sinatra
$ git checkout refs/tags/sinatra-hello
# abab/sinatra という名前で、イメージを生成。
$ docker build -t abab/sinatra .
# イメージが出来ていることを確認。
$ docker images
今までDockerの仕組みを学んできた、ここで一旦Dockerを利用してSinatraのアプリを動かしてみよう。 先ほど作ったsinatraのイメージを使ってコンテナを動かす。以下の例では、dockerの中の4567ポートを、外(HostOS)のポートに繋いでいる。 その後、curlを使ってSinatraアプリの起動を確認するが、この時Dockerは、localhostではなくHost OSのVM上で動いていることを思い出そう。 VMのipを確認するには、docker-machine ip コマンドを打って確認しよう。
# コンテナのポートを外(Host OS)に繋いで確認する。
$ docker run -p 4567:4567 abab/sinatra
# Docker Engineが動いているipを確認する。
$ docke-machine ip default
# 別シェルで実行してみよう。defaultという名前だと、省略することが出来る。
$ curl http://$(docker-machine ip):4567/
Dockerでアプリを動かすための一連の流れを追ってみたが、Dockerfileからimageをbuildし、runをするのはコマンドを毎回打つのが大変だ。 そこで、コマンドで打つ内容をdocker-compose.ymlに保存しておいて、それを利用する方法を紹介する。 docker-compose.ymlの中身は以下のようになる。概ね上のコマンド通りだが、一箇所違う点は、volumeという機能を使っている。 volumeはdockerとHost OSでディレクトリを共有する仕組みで、コンテナを動かしている状態でもファイルの編集をすることでコンテナ内に影響を与えることができる。 試しにコンテナが動いてる間にソースコードを編集してみよう。
app:
build: .
ports:
- "4567:4567"
volumes:
- ./src:/app/src
そして以下のように利用する。
# コンテナを動かす
$ docker-compose up
# コンテナの終了
$ docker-compose down