最終更新日
Docker は OS レベルの仮想化技術を利用して、コンテナーと呼ばれる形式 でソフトウェアのパッケージを提供する技術です。コンテナー内で実行される プロセスは、他のプロセスやファイルシステムから隔離され、独自のファイル システもやプロセステーブルを持ち、あたかもそれ専用のコンピューターで実 行されているかのように見えます。
(ファイルやポートを共有するように起動時に設定しない限り)コンテナー 内で実行するプロセスは、コンテナー外のプロセスやファイルシステムに影響 を及ぼすことはありません。
Docker コンテナーは、OS 自体を実行するわけではないので、仮想マシンな どと比べると軽量で、一つのハードウェアでも多数実行することができます。
参考
Windows Subsystem for Linux 2 により、Windows 上でも手軽に Docker を実行で きるようになりました。
ここでは香川研究室で Docker を使用するときに、特に必要な事柄を説明します。
Dockerfile は、Docker イメージを構築するための命令の集まりです。 Docker イメージは Docker コンテナーの土台・ひな型です。 Dockerfile を作成しておくと、Docker が動いている環境ならどこ でも、サーバー環境をコマンド一つで起動することができます。
卒業論文や修士論文の研究で作成したシステムにサーバー側のプログラムを含 んでいる場合は(例えば Java Servlet/JSP, node.js, PHP, WAI, Django, Flask, Ruby on Rails などで作成している場合は)Dockerfile を作成してお いて、サーバー側プログラムを、どのマシンにでも、すぐに配備できるように 準備しておいてもらえると、卒業・修了後に後輩が気軽に試せるようになりま す。 というわけで、サーバー側のプログラムを使っている場合は、Dockerfile も同時に用意するようにしてください。(また、同時にクライアント側のプロ グラムはソースの少数の箇所を書き換えるだけで、サーバー側の URL を変更で きるようにしておいてください。)
Dockerfile の命令には、元となるイメージの指定
(FROM
)、ファイルの取得
(ADD
, COPY
)、コマンドの実行
(CMD
)などがあります。詳しくは Dockerfile
のリファレン
スを見てください。
ここでは使用頻度の高い命令だけを紹介します。
作成する Docker イメージの元になるイメージ名を指定します。 C や Haskell をコンパイルしてできるバイナリーファイルを置くならば、 バイナリーファイルをビルドするのと同じ環境 (ubuntu など)を指定します。 Java や Kotlin のプログラムを動かすのならば ecliplse-temurin, sapmachine あるいは tomcat などが良いでしょう。 インタプリター方式の言語については python, node など、専用のイメージを探しましょう。
例:
Docker Hub の Browse Popular Images
で、元にする Docker Image を探すことができます。例えば、Node.js を使うなら、オフィシャルイメージの
node
を使うことができます。
maintainer="〜"
として作成者のメールアドレスを指定します。
例:
任意のコマンドをイメージ上で実行します。
apt-get
などのコマンドで、必要なソフトウェアをインストールするなどのときに使います。
例:
以降で実行する命令の作業ディレクトリーを指定します。
例:
どちらもイメージにファイルを追加します。
ADD
命令と COPY
命令は似ていますが、
ADD
命令のほうは tar ファイルを展開できる、ソースとして URL を指定できる、
などの違いがあるようです。
COPY
命令は、ファイルやディレクトリーを文字通りコピーするだけです。
単なるファイルのコピーならば、単純なほうの COPY
命令を使うとよいでしょう。
例:
Dockerfile 内の ADD
コマンド、COPY
コマン
ドは、シンボリックリンクをたどりません。しかし、場合によっては、シンボ
リックリンクをたどってほしいことがあります。そういうときは、build
コマンドを実行するときに、以下のよう
に tar
コマンドと組み合わせると、シンボリックリンクをたどっ
てくれます。
tar -czh . | docker build - -t tagname
参考: How to make a symlinked folder appear as a normal folder
環境変数を指定します。
例:
以降の RUN などの命令を実行するユーザーとグループを指定します。
例:
マウントポイントを作成します。
コンテナーを docker
コマンドで起動するときに
-v
オプションでホスト上のディレクトリーを
マウントするときなどに使用します。
例:
コンテナーを実行するときにリッスンするポートを指定します。
コンテナーを docker
コマンドで起動するときに
-p
オプションでコンテナーのポートを公開するときに使用します。
例:
コンテナーが実行するコマンドを指定します。
例:
Docker コンテナー起動するときのコマンド(docker run
)の
よく使うと思われるオプションとして、次のようなものがあります。
-p
-v
--restart
例:
docker run -p 127.0.0.1:8080:80 -v /home:/home --restart unless-stopped imagename &
詳しくは、
docker run
のコマンドライン・リファレンスを見てください。
Docker で配備したサーバー側のプログラムを、研究室の外にも公開する場 合、NGINX の Reverse Proxy の設定で 80 番ポートへのアクセスを Docker コンテナーのポートへ通過させる場合が多い と思われます。 詳しくは、香川研究室での NGINX の使い方 を見てください。
あるポートをサービスの待受けに使ったら、他の人が使ったポートと衝突しないように
/etc/nginx/conf.d/default.conf
の先頭に、コメントのカタチ
でメモしておいてください。
また、ポートの代わりに Unix Domain Socket を使えば、ポートが誰か他の人と衝突しないか、 あまり、気にしなくても良くなります。 NGINX は Unix Domain Socket をサポートしています。 もちろん、サーバー側のプログラムも Unix Domain Socket で待ち受ける必要があります。
Jetty
を始め、ほとんどのサーバー側フレームワークは Unix Domain Socket を
サポート(参考:
Class UnixSocketConnector)しています。
Warp も runSettingsSocket
という関数で Unix Domain Socket をサポート(参考: Warp: Binding to Unix Domain Sockets)するようです。
もしサーバー側プログラムが Unix Domain Socket をサポートしてい
ない場合は、コンテナーで socat
などのプログラムを実行する
という手段もあります。
例
socat UNIX-LISTEN:/path/to/socket,fork,user=www-data,reuseaddr TCP4:127.0.0.1:8080