SadServers解説#18 "Salta":Docker container won't start.
問題概要
シナリオ
Dockerコンテナが開始されません
問題詳細
/home/admin/app
ディレクトリにDocker化されたNode.jsウェブアプリケーションがあります。Dockerコンテナを作成することで、そのWEBアプリケーションにポート番号「:8888」でcurl
でアクセスできるようにしようとしています。解決策と判定されるためには、実行中のDockerコンテナが1つだけである必要があります。
解決判定
Check My Solution
ボタンをクリックしてください。
解答が正解かどうか、コマンドプロンプト上で確認することも可能です。以下と同じ出力が得られた場合は正解です。
$ curl localhost:8888
Hello World!
問題解決の方針
【表示する】
今回の問題では、Dockerコンテナのトラブルシューティングが求められています。
Dockerコンテナの設定ファイルを確認しながら、問題を一つずつ解決していきましょう。
解決の手順を表示する
- Dockerコンテナのエラーログを確認し、問題に対処する
- 8888番ポートがすでに使われているか確認し、すでに使われている場合はポートを開放する。
- Dockerコンテナを実行し、WEBサービスによって8888ポートが開かれているか確認する
ヒント
一部、SadServers公式のヒントを改変しています。
ヒント1
現在のコンテナの状態を確認します。
実行コマンド
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 1d782b86d6f2 20 months ago 124MB
node 15.7-alpine 706d12284dd5 3 years ago 110MB
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
124a4fb17a1c app "docker-entrypoint.s…" 20 months ago Exited (1) 20 months ago elated_taussig
すでに動いているコンテナがありますね。何か問題が起きているのでしょうか。
ヒント2
すでに動いているコンテナのログを見て、起きている問題に対処しましょう。
実行コマンド
$ sudo docker logs 124a4fb17a1c
node:internal/modules/cjs/loader:928
throw err;
^
Error: Cannot find module '/usr/src/app/serve.js'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:925:15)
at Function.Module._load (node:internal/modules/cjs/loader:769:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
at node:internal/main/run_main_module:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Error: Cannot find module '/usr/src/app/serve.js'
serve.js
が見つからないというエラーが出ています。
指定しているファイルのスペルミスですね。/home/admin/app/Dockerfile
の指定している場所を書き換えましょう。
実行コマンド
$ cp /home/admin/app/Dockerfile /home/admin/app/Dockerfile.bak
$ vi /home/admin/app/Dockerfile
$ diff /home/admin/app/Dockerfile /home/admin/app/Dockerfile.bak
19c19
< EXPOSE 8888
---
> EXPOSE 8880
22c22
< CMD [ "node", "server.js" ]
---
> CMD [ "node", "serve.js" ]
設定ファイルを見てみると、ポートを指定している行で8880ポートを指定していたため、こちらも併せて8888に直しました。
ヒント3
Dockerコンテナを再起動する前に、8888番ポートが使われていないか確認しましょう。
実行コマンド
$ sudo ss -natup | grep :8888
tcp LISTEN 0 511 0.0.0.0:8888 0.0.0.0:* users:(("nginx",pid=632,fd=6),("nginx",pid=631,fd=6),("nginx",pid=630,fd=6))
tcp LISTEN 0 511 [::]:8888 [::]:* users:(("nginx",pid=632,fd=7),("nginx",pid=631,fd=7),("nginx",pid=630,fd=7))
Nginxがすでに8888番ポートを使ってしまっているようなので、停止しましょう。
実行コマンド
$ sudo systemctl stop nginx
$ sudo ss -natup | grep :8888
8888ポートが未使用になりました。
ヒント4
編集したDockerfileをもとに、Dockerコンテナを起動しましょう。
Dockerコンテナ内のアプリケーションがポートを使えるようにするためには、コンテナの起動時にポートを指定する必要があることに注意しましょう。
実行コマンド
$ cd /home/admin/app
$ sudo docker build -t app .
Sending build context to Docker daemon 103.4kB
Step 1/7 : FROM node:15.7-alpine
---> 706d12284dd5
Step 2/7 : WORKDIR /usr/src/app
---> Using cache
---> 463b1571f18e
Step 3/7 : COPY ./package*.json ./
---> Using cache
---> acfb467c80ba
Step 4/7 : RUN npm install
---> Using cache
---> 5cad5aa08c7a
Step 5/7 : COPY ./* ./
---> eca53c3bd287
Step 6/7 : EXPOSE 8888
---> Running in e9b3523714a3
Removing intermediate container e9b3523714a3
---> 65bcc4f4e024
Step 7/7 : CMD [ "node", "server.js" ]
---> Running in ec1909b464fe
Removing intermediate container ec1909b464fe
---> 739f3cc3990f
Successfully built 739f3cc3990f
Successfully tagged app:latest
$ sudo docker run -d -p 8888:8888 app
008f1bdb6e3185083ef468271ad09cf039f97164671383133c1a909fbbcb4068
$ curl localhost:8888
Hello World!
レスポンスが返ってくるようになりました!
「いきなり問題を解き始めても調べるばかりになってしまう…」 「やりたいことが分かっても、コマンドが分からない…」 という方は、下記の記事でLinuxのコマンドを復習してから、SadServersの問題に取り掛かってみてはいかがでしょうか。
問題一覧はこちら
Discussion