docker
dockerfile

【学習メモ】Dockerコマンド(17個)を、コンテナにApacheをインストールする流れでおさらい

はじめに

Docker Engineのコマンドを覚えるための学習メモです。
apacheをコンテナにインストールし動かす流れでおさらいします。
流れは、イメージのダウンロード、Apacheをインストールしてビルド、コンテナの起動とビルドと削除です。
おさらいできるdockerコマンドは以下の通りです。

イメージ操作
search, pull, images, build, rmi, image prune
コンテナ操作
run, exec, attach, stop, start, restart, commit, rm, container prune
```s
```sh:コンテナ確認
history, ps
ログ確認
logs

回線速度にもよりますが、10分あればおさらいできます。
ApacheをインストールするコンテナはCentos7を想定しています。
Dockerは17.05.0-ce, Build 89658beです。
間違いの指摘や、学習の上で○○したほうが良いというような
改善のコメント大歓迎です。

また、初めてDockerを学ぶうえではこちらの記事が参考になりました。
Dockerハンズオン基礎編:コンテナとイメージのライフサイクルを理解

同じように流れで覚える記事がありました。
Docker pull commit push Dockerfile Apache Tomcat環境をつくる
こちらの方がやりごたえあります。

イメージのダウンロード

docker search

公式docker hubからイメージがあるか検索します。

公式イメージの検索
docker search -f "is-official=true" centos

docker pull

公式docker hubからイメージ+タグを指定してローカル環境にダウンロードします。
Tags一覧の取得方法は以下のリンクをご覧ください。
DockerHubのイメージのタグ一覧をコマンドで取得する

Dockerリンク : explorercentosubuntu

コロンで区切ってバージョンを指定。latestが最新。バージョン指定も可。
docker pull centos:latest
docker pull centos:7.3.1611
docker pull php:apache

docker image

ローカル環境に保存されたイメージを確認します。

イメージ確認、どれも同じ動作
docker images
docker image list
docker image ls

ビルド

Dockerfileの作成

runコマンドでレイヤーを重ねていくのは大変なので
Dockerfileを作成し、レイヤーをまとめて重ねます。

Centos6/7でDockerfileのコメントを分けています。
from行はdocker pullで取得したイメージを使用するので、同じように[REPOSITORY]:[TAG]と記述します。

コメント行以外は1度は手打ちしても良いかも
tee Dockerfile <<- 'EOF'
Dockerfileの中身
## -------------- ##
#FROM centos:latest
FROM centos:7.3.1611
#FROM centos:6.9
## -------------- ##

RUN sed -ie 's@^gpgcheck=1@#gpgcheck=1\ngpgcheck=0@g' /etc/yum.conf
RUN yum install -y httpd
RUN echo "It Works, maybe" >> /var/www/html/index.html

## -----------------------------------##
### centos 7
###RUN systemctl start httpd.service
RUN systemctl enable httpd.service

### centos 6.9
#RUN service httpd start
#RUN chkconfig --level 345 httpd on
## -----------------------------------##

yum installでsignature: NOKEYが出ますので、キーは入れずyumのgpgcheckを無効にして対応しています。
Proxy環境下の人はyumコマンドの前に以下を入れます。

Dockerfileでyum.confにproxy設定を追加する
RUN echo "proxy=http://[proxy]:[port]/" >> /etc/yum.conf

docker build

イメージを新しく作成します。
カレントディレクトリに作成したDockerfileを使用します。
コマンドの末尾のドットハイフンを忘れずに。
Docker-docs-ja 1.13.RC コマンドラインリファレンス>build

Dockerfileをつかう
docker build -t [new-image-name] .
Dockerfile以外をリダイレクトしてつかう
docker build -t [new-image-name] - < Dockerfile-dev

これでapacheがインストールされたベースイメージが完成します。

コンテナが生成されたか確認
docker images

docker history

コンテナにどんなレイヤーが積み重なっているのか確認します。

Dockerfileの履歴が適用されているか確認
docker history [new-image-name]

DockerfileでRUNコマンドを4つ動かしているので、
historyの最新部分はその4層が表示されます。

コンテナの起動とビルドと削除

docker run

コンテナを起動(レイヤーを追加)します。
DockerfileにあるRUNコマンドと同じです。
runはコンテナを起動するときに使います。

ホスト側ポート8080とコンテナ側ポート80を結合
docker run --privileged \ #特権。SElinuxが有効なときに必要。
           -h httpd2 \    #ホスト名
           -d \           #デタッチした状態
           -p 8080:80 \   #ポートの指定、ホスト側:コンテナ側
           --name [new-container-name] \ #新しく作るコンテナ名
           [new-image-name] \ #コンテナの元にするイメージ
            /sbin/init \  #コンテナで起動するプログラム
コピペのためのワンライナー
docker run --privileged -h [host-name] -d -p 8080:80 --name [container-name] [image-name] /sbin/init
公式のapacheイメージを使ってコンテナ起動
docker run -d -p 8080:80 httpd
249808a3abd5da227e7d2a7a176107d07c41392fab4c1eba38a5bb01dabc637e
公式のphp-apacheイメージを使ってコンテナ起動
docker run -d -p 8080:80 php:apache                                                                 
cdb3f19a74ca0a9810aa3dddb97aa79a8dc79aaa746ecf035a4848bc7ef523ba
  • 公式のhttpdやphp:apacheイメージはコンテナを立ち上げるときにコマンドを入れる必要がありません。

一読すると良い記事
CentOS 7のDockerコンテナ内でsystemdを使ってサービスを起動する

docker ps

起動中のコンテナ一覧を表示します。
起動したコンテナが一覧に表示されるか確認します。

起動中コンテナの一覧
docker ps
停止中のコンテナも含めた一覧
docker ps -a

リストに[new-container-name]があるか確認します。
名前があればコンテナが起動している状態です。
コンテナ内のapacheが起動しているので、ローカル環境からdockerホストの8080ポートへhttp接続できるか確認します。

wgetで確認
wget localhost:8080
cat index.html
curlで確認
curl localhost:8080
curl localhost:8081

Dockerfileのindex.htmlに追記した内容が表示されているはずです。
apacheの公式コンテナは<html><body><h1>It works!</h1></body></html>が表示されるはずです。
php-apacheの公式コンテナはルートディレクトリを表示できないと返ってきます。

docker logs

実行中のコンテナのログを確認します。
上記で公式コンテナを使った場合、アクセスログは以下のコマンドで取得します。

logsコマンド
docker logs 2498
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.4. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.4. Set the 'ServerName' directive globally to suppress this message
[Tue Feb 06 10:09:37.438655 2018] [mpm_event:notice] [pid 1:tid 140545174194048] AH00489: Apache/2.4.29 (Unix) configured -- resuming normal operations
[Tue Feb 06 10:09:37.441405 2018] [core:notice] [pid 1:tid 140545174194048] AH00094: Command line: 'httpd -D FOREGROUND'
172.17.0.1 - - [06/Feb/2018:10:09:46 +0000] "GET / HTTP/1.1" 200 45
172.17.0.1 - - [06/Feb/2018:10:10:06 +0000] "GET / HTTP/1.1" 200 45
  • 2498は、コンテナを起動したときに出る文字列で、立ち上げたコンテナのIDの先頭4文字です。コマンド上でコンテナを指定するときは、立ち上げのときに--nameで付けたコンテナ名か、コンテナIDを使います。コンテナIDは全桁入力せず、先頭の数桁を指定するだけで指定できます。
  • コンテナ内のLogfileの多くは、./access.log -> /dev/stdoutのように記述されています。

参考資料
docker logs(docs.docker.com)
dockerのlog周りの対応(christina04.hatenablog.com)

docker exec / docker attach

実行中のコンテナにコマンドを実行させます。
runはコンテナ起動+コマンドを実行させるときに使いますが、
execは起動中のコンテナにコマンドを実行させるときに使います。
docker runとdocker execの違いの解説

コマンドを実行させてみる
docker exec [new-container-name] sleep 180 &

シェルを起動し、接続します。

コンテナ内シェルを起動して接続
docker exec -it [new-container-name] /bin/bash

httpdやsleepが起動しているか確認します。

コンテナ内でhttpdやsleepが起動しているか確認
# ps aux | grep -e "httpd" -e "sleep"

docker exec -it [new-container-name] /bin/bashでコンテナに入ったときはexitで抜けますが、
docker attachで入ったときはCtrl + P -> Ctrl + Qで抜ける必要があり、注意が必要です。

attachで入る
docker attach [new-container-name]

Dockerコンテナ内で操作 attachとexecの違い

docker exec で公式コンテナに入って、apacheのログファイルの実体を確認します。

docker exec -it cdb /bin/bash
root@cdb3f19a74ca:/var/www/html# ls -l /var/log/apache2/           
total 0
lrwxrwxrwx. 1 root root 11 Feb 16  2018 access.log -> /dev/stdout
lrwxrwxrwx. 1 root root 11 Feb 16  2018 error.log -> /dev/stderr
lrwxrwxrwx. 1 root root 11 Feb 16  2018 other_vhosts_access.log -> /dev/stdout

docker stop / docker start

コンテナを停止させます。

コンテナを停止
docker stop [new-container-name]
コンテナを再開
docker start [new-container-name]
コンテナを停止して再開
docker restart [new-container-name]

docker startしても、Exited(0)などですぐ止まってしまうときは、初めてコンテナを起動(run)したときのCOMMANDが終了しているからだと思われます。
docker run -it [image-name] /bin/bashで起動すれば、exitで抜けてもdocker startで起動できます。

docker commit

コンテナをイメージに変換します。
runで重ねたイメージレイヤーを結合し、イメージにします。

コンテナをイメージ[new-image-name2]へ変換
docker commit [new-container-name] [new-image-name2]

docker rm / docker container prune

停止しているコンテナを削除します。

コンテナをローカル環境から削除
docker rm [new-container-name]

起動していないコンテナをすべてローカル環境から削除します。

停止中のコンテナをすべてローカルから削除
docker container prune

docker rmi / docker image prune

ローカル環境に保存されたイメージを削除します。

ローカル環境に保存されたイメージを削除
docker rmi [new-image-name]

コンテナに利用されていないイメージをすべてローカル環境から削除します。

使用していないイメージをローカル環境からすべて削除
docker image prune

あとはDockerfileを削除すれば、環境はきれいになるはずです。
以上でおさらいは終了です。
お付き合いありがとうございました。