環境構築のためのDocker
はじめに
これはMuroran Institute of Technology Advent Calendar 2018 - Adventarの記事です.
- ホストマシンのOSはWindowsやmacOSを使いたい.
- Linuxも使いたい.(GUIは必要ない.)
- ホストマシンの環境をできるだけ変更したくない.
- 同じ開発環境を再現できるようにしたい.
- できれば賢い誰かが構築した環境を利用したい.
そんな時,ホストマシンにDockerをインストールしておくと,
- CUIだけの軽量なLinux仮想環境を構築できる.
- 環境構築の手順はテキストファイルに記述できる.
- そのファイルから開発環境を自動的に構築できる.
- Docker Hubにアップロードされた環境を利用できる.
なんて,素晴らしい.
インストール
それぞれのOSにおけるDockerのインストール方法を以下に示します.
Windows 10 64bit : Pro, Enterprise or Education
Install Docker Desktop on Windows | Docker Documentation
それ以外のWindows
macOS
Install Docker Desktop on Mac | Docker Documentation
Ubuntu
sudo apt install docker sudo apt install docker-compose
Docker
Dockerはイメージをもとにコンテナを生成し,コンテナ内の環境でアプリケーションを実行します. イメージはアプリケーションとその実行環境の情報をまとめたもので,Docker Hubからpullしてきたり,Dockerfileから作成したりすることで用意します. コンテナはイメージを実体化したもので,実行中のアプリケーションの状態を保持します. Docker Hubは利用可能なイメージが集まったDockerのサービスです. Dockerfileはイメージを作成する手順を記述したテキストファイルです.
Docker Hubからpullしてきたり,Dockerfileから作成したりしたイメージは,ダウンロードしてきたり,ソースコードからビルドしたりしてSSDに保存したプログラムに例えることができると思います. また,イメージをもとに実体化され,実行されるコンテナは,SSDからメモリにロードされ実行されるプログラムに例えることができると思います.
dockerのコマンド
docker --help
: dockerのヘルプを表示する.docker build -t イメージ名 ディレクトリ
: 指定されたディレクトリ
のDockerfileから指定されたイメージ名
のイメージを作成する.docker run イメージ [コマンド]
: 指定されたイメージ
を基にコンテナを起動し,コンテナ内で指定されたコマンド
を実行する.docker stop コンテナ
: 指定された実行中のコンテナ
を停止する.docker ps
: 実行中のコンテナ一覧を表示する.docker images
: ホストマシンにあるイメージ一覧を表示する.docker rm コンテナID
: 指定されたコンテナID
を持つコンテナを削除する.docker rmi イメージID
: 指定されたイメージID
を持つイメージを削除する.
Dockerfile
Dockerfileはイメージを作成する手順を記述したテキストファイルで,以下のように記述します.
# 基にするイメージを指定する.Docker Hubから探してくることが多い. FROM ベースイメージ # 作業ディレクトリを指定する. WORKDIR /workdir/path # ホストマシンのファイルやディレクトリをコンテナ内に複製する. COPY host/path/ container/path # Shellコマンドを実行する.アプリケーション実行のための準備を行う. RUN shell command # コンテナ実行時に実行されるアプリケーション実行コマンドを指定する. CMD ["アプリケーション実行コマンド", "コマンドライン引数1", "コマンドライン引数2", ...]
使用例
Hello World
次のコマンドを実行すると,
docker run hello-world
dockerはホストマシンに保存されているhello-world
イメージからコンテナを生成し,Hello Worldを出力するアプリケーションをコンテナ内で実行します.
ホストマシンにhello-world
イメージがないときは,dockerはDocker Hubからhello-world
イメージをpullしてきてホストマシンに保存します.
Bash
次のコマンドを実行すると,
docker run -i -t ubuntu bash
dockerはホストマシンに保存されているubuntu
イメージから(無いときはDocker Hubからpullして保存する.)コンテナを生成し,コンテナ内でBashを実行します.
-i
, -t
オプションはホストマシンのの標準入出力とコンテナの標準入出力を繋いぐためのオプションです.
C++
次の内容のファイルを用意します.
- ./Dockerfile
FROM ubuntu WORKDIR /home/app COPY ./src/main.cpp /home/app RUN apt update -y && apt upgrade -y && apt install -y g++ RUN g++ -o main main.cpp CMD ["./main"]
- ./src/main.cpp
#include<iostream> int main(int argc, char *argv[]) { std::cout << "hello docker-cpp" << std::endl; }
次のコマンドを実行すると,
docker build -t docker-cpp ./
カレントディレクトリのDockerfile
からdocker-cpp
という名前のイメージが作成されホストマシンに保存されます.
docker-cpp
は具体的にはDockerfile
に従い以下のように作成されます.
- ubuntuのイメージをダウンロードする.
- 作業ディレクトリを
/home/app
に設定する. apt update -y && apt upgrade -y && apt install -y g++
を実行し,アプリケーションのビルドの準備をする.g++ -o main main.cpp
を実行し,アプリケーションをビルドする.- コンテナ起動時に
./main
というコマンドでアプリケーションを実行するように設定する.
イメージ作成後に次のコマンドを実行すると,
docker run docker-cpp
ホストマシンに保存されたdocker-cpp
という名前のイメージからコンテナが生成された後に./main
が実行されて次の実行結果が得られます.
hello docker-cpp
Docker Compose
Docker Composeはdocker-compose.ymlに記述された設定に従って,1つ以上のコンテナを連携させて起動するものです. docker-compose.ymlはコンテナ起動時の設定を記述するテキストファイルです.
docker-composeのコマンド
docker-compose --help
: docker-composeのヘルプを表示する.docker-compose build
:docker-compose.yml
に従ってイメージを作成し,保存する.docker-compose up [-d]
:docker-compose.yml
に従ってコンテナを起動する.-d
オプションを付けるとコンテナをバックグラウンドで実行する.docker-compose run コンテナ名 コマンド
:コンテナ名
を持つコンテナを起動し,コンテナ内でアプリケーションの代わりにコマンド
を実行する.docker-compose exec コンテナ名 コマンド
:コンテナ名
を持つ起動中のコンテナ内でコマンド
を実行する.docker-compose stop
: 起動したコンテナを停止する.
docker-compose.yml
# docker-compose.ymlのバージョンを指定する.'3'を指定する. version: '3' # コンテナごとの設定を記述する. services: コンテナ名: # コンテナの名前をコンテナ名に設定する. container_name: 'コンテナ名' # imageまたはbuildでコンテナのイメージを指定する. # イメージを直接指定するときはimageで指定する. image: 'イメージ' # イメージをDockerfileで指定するときはbuildで指定する. build: # Dockerfileがあるディレクトリを指定する. context: 'Dockerfileのディレクトリ' # Dockerfileのファイル名を指定する. dockerfile: 'Dockerfile名' # ホストマシンのディレクトリをコンテナにマウントする. volumes: - 'ホストマシンのディレクトリ:コンテナのディレクトリ' # ホストマシンのポートを開放し,コンテナのポートに接続する. ports: - 'ホストマシンの開放ポート:コンテナの開放ポート' # コンテナ起動時に実行されるコマンドを指定する. command: ["コマンド", "コマンドライン引数1", ... ]
使用例
Python
次のファイルを用意します.
- ./docker-compose.yml
version: '3' services: docker-py: container_name: 'docker-py' image: 'python:3' working_dir: '/home/app' volumes: - './app:/home/app' command: ["python", "main.py"]
- ./app/main.py
print("hello docker-py")
次のコマンドを実行すると,
docker-compose up
カレントディレクトリのdocker-compose.yml
の設定に従って,docker-py
という名前のコンテナが起動し,次の実行結果が得られます.
hello docker-py
docker-py
は具体的にはdocker-compose.yml
に従い以下のように起動されます.
- python:3のイメージをダウンロードする.
- 作業ディレクトリを
/home/app
にする. - ホストマシンの
./app
をコンテナの/home/app
にマウントする. - コンテナを起動して
python main.py
を実行する.
また,次のコマンドを実行して,
docker-compose run docker-py bash
コンテナ内でpython
を実行するとPythonが対話モードで起動します.
Gnuplot
次のファイルを用意します.
- ./Dockerfile
FROM ubuntu WORKDIR /home/files COPY ./files /home/files RUN apt update -y && apt upgrade -y && apt install -y gnuplot CMD ["gnuplot", "plot-cos.plt"]
- ./docker-compose.yml
version: '3' services: gnuplot: build: context: './' dockerfile: 'Dockerfile' container_name: 'gnuplot' volumes: - './files:/home/files/'
- ./files/plot-cos.plt
set terminal pdfcairo set output 'plot-cos.pdf' set xrange [-2*pi:2*pi] set yrange [-1.5:1.5] set samples 500 plot cos(x)
- ./files/plot-sinc.plt
set terminal pdfcairo set output 'plot-sinc.pdf' set xrange [-10*pi:10*pi] set yrange [-1:1.2] set samples 500 plot sin(x)/x
次のコマンドを実行すると./files/plot-cos.pdf
が生成されます.
docker-compose build docker-compose up
次のコマンドを実行して,
docker-compose build docker-compose run gnuplot bash
コンテナ内でgnuplot ./plot-sinc.plt
を実行すると./files/plot-sinc.pdf
が生成されます.
PHP
次のファイルを用意します.
- ./docker-compose.yml
version: '3' services: docker-php: container_name: 'docker-php' image: 'php:7.2-apache' volumes: - './html:/var/www/html' ports: - '8080:80'
- ./html/index.php
<?php echo "hello docker-php" ?>
次のコマンドを実行して,
docker-compose up -d
ブラウザでhttp://localhost:8080
にアクセスするとhello docker-php
と表示されます.
まとめ
- DockerとDocker Composeを利用すると,ホストマシンのOSに依らずに,再現性のある軽量な仮想Linux環境を自動的に構築できます.
- Dockerはイメージからコンテナを実体化し,アプリケーションを実行します.
- Docker Composeはdocker-compose.ymlの設定に従ってコンテナを起動します.
- Dockerfileにはイメージの作成手順を書き,docker-compose.ymlにはコンテナ起動時の設定を書きます.