Dockerを触り始めました -導入、dockerfile-

タイトル通りです、Dockerを触り始めました。
調べつつ導入方法から始めたのでそんなメモです。

というかDockerってなんですか?

Dockerについて、少しわかっている気でわかっていないことが多いぞと、
すぐに気が付いたのでいくつか見ながら確認。
(技術書典での購入物だったり、WEBの資料とか)

一旦以下の認識で進める。

  • Docker
    OSレベルのコンテナと呼ばれる仮想化環境を提供するOSS
  • DockerFile
    コンテナイメージのカスタマイズを定義するファイル
  • Docker Compose
    複数のコンテナをまとめて管理するためのツール

Dockerの導入

Qiita DockerをMacにインストールするを参考にしながら導入。

コマンド

バージョン確認

1
docker --version

イメージ関連

イメージの検索

1
docker search "イメージ名"

docker hubでも検索できる。

イメージの取得

1
docker pull "イメージ名"

取得済みイメージの一覧

1
2
docker image ls 
docker images

取得済みイメージの設定詳細を表示

1
docker inspect "イメージ名"

取得済みイメージを削除

1
docker image rm "イメージ名"

コンテナ関連

コンテナの実行状況

1
2
3
4
5
6
#実行中のコンテナのみ
docker container ls
docker ps
#終了したコンテナも表示する
docker container ls -a
docker ps -a

コンテナの作成(取得済みイメージがなければ取得から)、実行

1
2
3
docker run "イメージ名"
#正確には
docker run [オプション] "イメージ名" [コマンド] [引数]

上記のdocker run "イメージ名"最少コマンドに見えるが、落とし穴だった。
例えばCentOSのコンテナを実行時にdocker run centosとすると、コンテナから出られない状態になった・・・。

例に上がっていたhelloworldイメージのコンテナは実行例として、docker run hello-worldとしていた。
docker inspect hello-worldで確認すると"CMD"[/hello]となっている。/helloを実行して終了するのだと思う。
対してdocker inspect centosでは、"CMD"

1
2
3
4
5
6
[
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"/bin/bash"]"
]

となっていた。
入力を待ち受けているっぽい。

実行後に終了しないイメージなら、以下の2択になると思う。

1
2
3
4
5
6
# -i:標準入力を開く
# -t:ttyを割り当てる 付けなくても対話モードにはなるが、表示に難が出る。
# お作法として-itとする
docker run -it "イメージ名"
# -d:バックグラウンド実行
docker run -d "イメージ名"

ちなみに、コマンドで例えばdocker run centos lsのようにlsを渡すと実行後元のターミナルに戻ってくることができる。

コンテナの作成だけする

1
2
3
4
5
docker create "イメージ名"
# 正確には
docker create [オプション] "イメージ名" [コマンド] [引数]
# 対話モード起動
docker create -it "イメージ名"

docker create -d ~~~が無く、バックグラウンドモードの「作成だけ」は無い。

コンテナの開始

1
2
3
4
# "CONTAINER ID"と"NAMES"は"docker ps"で調べる
docker start "CONTAINER ID"or"NAMES"
# 起動して、対話モードに入る。
docker start -ai "CONTAINER ID"or"NAMES"

コンテナの停止

1
docker stop "CONTAINER ID"or"NAMES"

コンテナの削除

1
docker rm "CONTAINER ID"or"NAMES"

バックグラウンド実行しているコンテナをフォアグラウンドに持ってくる

1
2
# "--sig-proxy=false"を付けることでCTRL+Cでコンソールに戻れる
docker attach --sig-proxy=false "CONTAINER ID"or"NAMES"

新しいプロセスを実行しているコンテナに追加する

1
2
3
4
5
6
docker exec [オプション] "CONTAINER ID"or"NAMES" "コマンド"
# execを使用してバックグラウンド起動しているコンテナに別プロセスでアクセスできる
# 以下のコマンド
docker exec -it "CONTAINER ID"or"NAMES" bash
#バックグラウンド実行させるコマンドの追加も可能
docker exec -d "CONTAINER ID"or"NAMES" ping ~.~.~.~

コンテナからイメージを作る

1
2
docker commit "CONTAINER ID"or"NAMES" "リポジトリ名:タグ"
# "リポジトリ名:タグ"の部分は、"ユーザー名/任意名称"でよいそう

作成したイメージからまたコンテナを作成できる。

runとcreateのオプション

docker rundocker createのオプションは非常に多い。とはいえよく使われていたのは以下記載のものだと思う。

1
2
3
4
5
6
7
8
9
10
11
12
-p
# -p [ホストのポート]:[コンテナのポート]
# の記載でポートフォワーディングできる
-v
# -v [ホスト上のパス][コンテナ上のパス]
# の記載でホストのファイルとディレクトリをコンテナのファイルとディレクトリとしてアクセスさせる
--name
# --name [コンテナ名]
# の記載で任意のコンテナ名称が設定できる
-e
# -e [環境変数名]=[値]
# の記載で環境変数を設定できる

特に、-edockerhub mysqlを見ると、データベースのユーザー名設定ほか設定手順に記載があるので押さえておく必要があるみたい。


dockerfile

dockerfileを使用することで、イメージのカスタマイズができる。

dockerイメージから、カスタマイズを加えて、dockerイメージを作成する。

1
2
3
4
docker build [オプション] "dockerfileの保存先ディレクトリのパス"
# 作成されたイメージに名称(タグ)を付与するときは以下のようにする。
# 名称は"リポジトリ名:タグ"が推奨になるようだ。
docker build -t "リポジトリ名:タグ" .

dockerfileの書き方

dockerfileに記載するコマンド群
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
FROM "dockerイメージ名"
# カスタマイズ元となるdockerイメージ名

MAINTAINER "名前"
# 作成者情報

RUN "コマンド"
# docker build 実行時に実行する

CMD "コマンド"
# docker run 実行時に実行するコマンド
# 1つのdokerfileに一つ

ADD "ローカルファイル/ディレクトリ名" "追加先パス"
# ファイルとディレクトリの追加

COPY "ローカルファイル/ディレクトリ名" "追加先パス"
# ファイルとディレクトリのコピー

WORKDIR "ディレクトリパス"
#作業ディレクトリを指定

ENV "環境変数名"="値"
# 環境変数設定

USER "ユーザー名"
# 実行ユーザー指定

EXPOSE "ポート番号"
# 解放するポートを定義

以上をもとに、
centosのdockerイメージを元に、whichコマンド、nanoコマンドを追加するdockerfileを作ってみました。

1
2
3
4
5
6
from centos
MAINTAINER octo8080

RUN echo "Now building....."

RUN yum install -y which nano

これをもとにイメージを作成して、実行します。

1
2
3
4
# カレントディレクトリにあるdockerfileを使用してイメージをビルド
docker build -t centos-wwn .
# 作成したcentos-wwnイメージでコンテナ作成と実行
docker run -it centos-wwn

コンテナ名の中で、which nanoで結果が返ってくればOK!

CMDを設定しなかったが、この時は元のイメージの内容を引き継いでいるよう。

今度は、webサーバを立ち上げるdockerfileを作ってみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from centos
MAINTAINER octo8080

RUN echo "Now building....."

# パッケージインストール
RUN yum install -y nginx

# index.htmlの差し替えと権限変更
WORKDIR /usr/share/nginx/html
COPY ./index.html .
RUN chmod 755 ./index.html

# ポート解放
EXPOSE 80

# docker run 時実行内容
CMD ["nginx","-g","daemon off;"]

CMD ["nginx","-g","daemon off;"]の部分は、nginxイメージのinspect結果を参考にしてます。
同じ階層に適当にindex.htmlも作っておきビルドと実行。

1
2
3
4
# カレントディレクトリにあるdockerfileを使用してイメージをビルド
docker build -t centos-nginx .
# 作成したcentos-wwnイメージでコンテナ作成と実行
docker run -it centos-nginx

localhostにブラウザでアクセスすると、自身で用意したindex.htmlの内容が表示される。


Docker Compose

といいたいとこですが、長くなったのでDocker Composeは次にします。別に書きました。
Dockerを触り始めました2 - Docker Compose -

Dockerをちゃんと触り始めたのですが、VMWare WorkStation playerで仮想マシンを個別に立ち上げてきたこともあり、非常に手軽でいいなぁ。というのが感想でした。
今回だとnginxを立ち上げるイメージを作ってみましたが、nginxのイメージがあるのでそちらを使って、dockerfileで.conf他を追加して使うのがいいのかなと思いました。

ではでは