🐋

SadServers解説#18 "Salta":Docker container won't start.

2024/05/12に公開

https://ja.wikipedia.org/wiki/サルタ

問題概要

シナリオ

Dockerコンテナが開始されません

問題詳細

/home/admin/appディレクトリにDocker化されたNode.jsウェブアプリケーションがあります。Dockerコンテナを作成することで、そのWEBアプリケーションにポート番号「:8888」でcurlでアクセスできるようにしようとしています。解決策と判定されるためには、実行中のDockerコンテナが1つだけである必要があります。

解決判定

Check My Solutionボタンをクリックしてください。

解答が正解かどうか、コマンドプロンプト上で確認することも可能です。以下と同じ出力が得られた場合は正解です。

$ curl localhost:8888
Hello World!

 

問題解決の方針

【表示する】

今回の問題では、Dockerコンテナのトラブルシューティングが求められています。
Dockerコンテナの設定ファイルを確認しながら、問題を一つずつ解決していきましょう。

解決の手順を表示する
  1. Dockerコンテナのエラーログを確認し、問題に対処する
  2. 8888番ポートがすでに使われているか確認し、すでに使われている場合はポートを開放する。
  3. 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の問題に取り掛かってみてはいかがでしょうか。
https://zenn.dev/comf_nakamura/articles/linux_command

問題一覧はこちら

https://zenn.dev/comf_nakamura/articles/sadservers_sitemap

Discussion