課題: Docker を使って、ステートレス Web サーバーを立ち上げてください
あなたはすぐにできますか?
わたしはと言うと、方法は知っていても実際に出来るかどうかまでは試したことがありませんでした。
なので、やってみました。
実際やってみると、いろいろと分かっていないことが分かるものです。
もしあなたも同じように自信が無いのなら、手を動かしアタマを使い、取り組んでみてはいかがでしょうか?
今回わたしは 次のような手順↓で進めました。
1) Docker
手元の PC は Windows なので、Docker Desktop for Windows を使いました。
セットアップ手順は過去の記事と同じなので省略します。
2) nginx
Web サーバーとして nginx を選びました。
nginx は使い道がたくさんありますが、今回はもっとも単純な使い方をします。
過去の記事では Docker Compose を使ったのですが、今回は起動したいコンテナーが 1 つだけなので、コマンドラインから立ち上げることにしました。
2-1) 起動確認
Docker Hub にアップされている情報を眺めながら、サービスの起動方法を確認しました。
https://hub.docker.com/_/nginx
コンテナーを起動するために次のコマンドを実行しました。
C:\Users\abech> docker run -itd -dp 80:80 nginx:latest
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
8559a31e96f4: Pull complete
8d69e59170f7: Pull complete
3f9f1ec1d262: Pull complete
d1f5ff4f210d: Pull complete
1e22bfa8652e: Pull complete
Digest: sha256:21f32f6c08406306d822a0e6e8b7dc81f53f336570e852e25fbe1e3e3d0d0133
Status: Downloaded newer image for nginx:latest
cfb0f90ba079a3310dfe9ea9d55815f826604b8aa327ea42f8873ad87fc7b7a5
ブラウザーから localhost にアクセスして、Web サービスが起動していることを確認しました。
一旦、あと片付けをしました。
C:\Users\abech> docker stop f90ba079a3310dfe9ea9d55815f826604b8aa327ea42f8873ad87fc7b7a5
f90ba079a3310dfe9ea9d55815f826604b8aa327ea42f8873ad87fc7b7a5
C:\Users\abech> docker container prune -f
Deleted Containers:
cfb0f90ba079a3310dfe9ea9d55815f826604b8aa327ea42f8873ad87fc7b7a5
0bad81f01e4220a72b62ebb1cd69e80437215d7b73de21aa94c42a8bb810020e
Total reclaimed space: 1.114kB
念のため nginx のバージョンを確認しました。(ver.1.19.0 でした)
C:\Users\abech> docker inspect nginx:latest
[
{
"Id": "sha256:2622e6cca7ebbb6e310743abce3fc47335393e79171b9d76ba9d4f446ce7b163",
"RepoTags": [
"nginx:latest"
],
"RepoDigests": [
"nginx@sha256:21f32f6c08406306d822a0e6e8b7dc81f53f336570e852e25fbe1e3e3d0d0133"
],
"Parent": "",
"Comment": "",
"Created": "2020-06-09T16:57:42.632836191Z",
"Container": "53e54c20f21e263548ac09475373e20dfef58dd38aebc6caec258b4ff6c2446c",
"ContainerConfig": {
"Hostname": "53e54c20f21e",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.19.0",
"NJS_VERSION=0.4.1",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"nginx\" \"-g\" \"daemon off;\"]"
],
"ArgsEscaped": true,
"Image": "sha256:096f75b5300eeb60b7ec16dcf3bcd48abcde14a9a379a96f42d5ffc26fcfdf1b",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGTERM"
},
"DockerVersion": "18.09.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.19.0",
"NJS_VERSION=0.4.1",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"ArgsEscaped": true,
"Image": "sha256:096f75b5300eeb60b7ec16dcf3bcd48abcde14a9a379a96f42d5ffc26fcfdf1b",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGTERM"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 132122017,
"VirtualSize": 132122017,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/90190329a2c0cdc1ef09f4b04ad36b714064a2fbc7ed8e55ad9dddc47084aae2/diff:/var/lib/docker/overlay2/2b150d9f432964ff28de11ad10b3b19081c59ca7b8cd9daff18a0aaa2f27704f/diff:/var/lib/docker/overlay2/077a5167708f61e6520dcb810d29163d4a6826dce881072e1e114627881bc1e9/diff:/var/lib/docker/overlay2/4e3a6b7437bda08b6a0c3a16269f907c1fb1cffa434e226d79528ad13e43390b/diff",
"MergedDir": "/var/lib/docker/overlay2/8406c69e5cad126aedfa198de536b67e80991c249aefdef051bd1dbddb058882/merged",
"UpperDir": "/var/lib/docker/overlay2/8406c69e5cad126aedfa198de536b67e80991c249aefdef051bd1dbddb058882/diff",
"WorkDir": "/var/lib/docker/overlay2/8406c69e5cad126aedfa198de536b67e80991c249aefdef051bd1dbddb058882/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:13cb14c2acd34e45446a50af25cb05095a17624678dbafbcc9e26086547c1d74",
"sha256:d4cf327d8ef50eb2e31b646f17217a3baf455391bfd59bce47df50c770ff8c07",
"sha256:7c7d7f4461826dd22f9234a81f9bed9c0bdb0b70b3ce66228bfc87418a9b8313",
"sha256:9040af41bb6677b114134de15ddeb10b070eb1f940dbbe277574ee154d89f6b9",
"sha256:f978b9ed3f26a49b55cf4849e4cadb29335be45a633cbe95a2f4e445e70086bf"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
2-2) 設定ファイルとコンテンツの準備
nginx 公式サイトにある Beginner's Guide を一読して、簡単な設定ファイルの書き方を確認しました。
https://nginx.org/en/docs/beginners_guide.html
カレントフォルダーに設定追加ファイル nginx.conf を準備しました。
/etc/nginx/nginx.conf の置き換えを想定した構成になっています。
http {
server {
root /usr/share/nginx/html;
}
}
この設定内容は冗長なものとなっていますが、将来あるかもしれないカスタマイズに備えておくことにしました。
そしてカレントフォルダーにダミーのコンテンツフォルダーを準備しました。
./html/index.html の本文は Hello World 的なメッセージです。
./
└─html
└─index.html
本来ならリポジトリから git clone される想定です。
2-3) サービス起動
C:\Users\abech> docker run -itd -v %cd%/html:/usr/share/nginx/html:ro -v %cd%/nginx.conf:/etc/nginx/nginx.conf:ro -dp 80:80 nginx
9ead21a685b476e04f6bcca1630c22f02cac9595a9ba6b48e8ad142bc6ea8d76
2-4) 動作確認
ブラウザーからアクセスする代わりに curl を使うことにしました。
C:\Users\abech> curl localhost
curl: (7) Failed to connect to localhost port 80: Connection refused
何やら失敗してしまったので、ログを確認しました。
C:\Users\abech> docker container logs 9ead
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2020/06/17 12:41:17 [emerg] 1#1: no "events" section in configuration
nginx: [emerg] no "events" section in configuration
設定ファイル nginx.conf の問題と判明し、2-2 からやり直しました。
2-2') 設定
events {
}
http {
server {
root /usr/share/nginx/html;
}
}
2-3') サービス起動(設定ファイルの反映)
nginx へ reload シグナルを送ることで設定ファイルの再読み込みが行えるので、使ってみました。
C:\Users\abech> docker exec 9ead nginx -s reload
2020/06/17 13:01:47 [notice] 29#29: signal process started
やや graceful さを欠きますが、ここは "docker restart 9ead" でも良かったかもしれません。
2-4') 動作確認
C:\Users\abech> curl localhost
Hello nginx from ./html/index.html.
2-5) あと片付け
C:\Users\abech> docker stop 9ead
9ead
C:\Users\abech> docker container prune -f
Deleted Containers:
9ead21a685b476e04f6bcca1630c22f02cac9595a9ba6b48e8ad142bc6ea8d76
Total reclaimed space: 4.456kB
振り返り
反省点は↓以下のとおり。
・ nginx について知らなさ過ぎたため、簡単なタスクなのに少々時間が掛かってしまった
・ 覚えたこと/細かい知識
・ docker volume の引数指定には相対パスが使えない
・ nginx.conf の events コンテキストは省略できない
・ docker inspect
・ docker logs
この記事が気に入ったらサポートをしてみませんか?