[SadServers] 解説 "Salta": Docker container won't start.
"Salta": Docker container won't start.
SadServersの "Salta": Docker container won't start の解説です。
SadServers って何? って人は、 SadServers解説 を見てください。
一言でいうと、LeetCode (コーディング問題集) の Linuxサーバ設定版のようなものです。
問題
Scenario: "Salta": Docker container won't start.
Level: Medium
Description: There's a "dockerized" Node.js web application in the /home/admin/app directory. Create a Docker container so you get a web app on port :8888 and can curl to it. For the solution to be valid, there should be only one running Docker container.
/home/admin/app ディレクトリに "dockerized" Node.js web アプリケーションがあります。Docker コンテナを作成し、ポート :8888 でウェブアプリケーションを取得し、それに curl できるようにします。このソリューションを有効にするには、実行中のDockerコンテナが1つだけである必要があります。
Test: curl localhost:8888 returns Hello World! from a running container.
Time to Solve: 15 minutes.
OS: Debian 11
解説
まず、curl
を実行してみます。 Dockerを動かしていないので、失敗(TCP接続ができない)することが期待です。
# `-v` により、詳細情報を出力
admin@ip-172-31-34-17:~/app$ curl -v http://localhost:8888
* Trying 127.0.0.1:8888...
* Connected to localhost (127.0.0.1) port 8888 (#0)
> GET / HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.18.0
< Date: Mon, 26 Dec 2022 09:56:54 GMT
< Content-Type: text/html
< Content-Length: 44
< Last-Modified: Fri, 16 Sep 2022 21:03:18 GMT
< Connection: keep-alive
< ETag: "6324e496-2c"
< Accept-Ranges: bytes
<
these are not the droids you're looking for
* Connection #0 to host localhost left intact
どうも curl
自体は成功しています。 Server: nginx/1.18.0
と、あるので、nginx
が動作しているようです。
systemctl
で nginx
を止めます。
# nginx を止める。
admin@ip-172-31-34-17:~/app$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: en>
Active: inactive (dead) since Mon 2022-12-26 09:57:18 UTC; 16s ago
Docs: man:nginx(8)
Process: 572 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process o>
Process: 594 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=>
Process: 1851 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 ->
Main PID: 603 (code=exited, status=0/SUCCESS)
CPU: 66ms
Dec 26 09:48:36 ip-172-31-34-17 systemd[1]: Starting A high performance web server>
Dec 26 09:48:36 ip-172-31-34-17 systemd[1]: Started A high performance web server >
Dec 26 09:57:18 ip-172-31-34-17 systemd[1]: Stopping A high performance web server>
Dec 26 09:57:18 ip-172-31-34-17 systemd[1]: nginx.service: Succeeded.
Dec 26 09:57:18 ip-172-31-34-17 systemd[1]: Stopped A high performance web server >
再度、curl
を試します。
admin@ip-172-31-34-17:~/app$ curl -v http://localhost:8888
* Trying 127.0.0.1:8888...
* connect to 127.0.0.1 port 8888 failed: Connection refused
* Failed to connect to localhost port 8888: Connection refused
* Closing connection 0
curl: (7) Failed to connect to localhost port 8888: Connection refused
期待通り、失敗して、8888ポートが空きました。
さて、いよいよ Dockerを動かす準備をします。
# /home/admin/app/ に移動して、Dockerfileを確認。
admin@ip-172-31-35-220:/$ cd /home/admin/app/
admin@ip-172-31-35-220:~/app$ ls
Dockerfile package-lock.json package.json server.js
Dockerfile
をビルドして、実行します。
sudo
をつけずにdocker
コマンドを実行すると、Permissoin denied
エラーがでるので、sudo
をつけます。
# nodeという名前でDockerイメージを作成する。
admin@ip-172-31-35-220:~/app$ sudo docker build -t node .
Sending build context to Docker daemon 101.9kB
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 ./* ./
---> Using cache
---> a6ee5c4d5a96
Step 6/7 : EXPOSE 8880
---> Using cache
---> 0b18357df7c9
Step 7/7 : CMD [ "node", "serve.js" ]
---> Using cache
---> 1d782b86d6f2
Successfully built 1d782b86d6f2
Successfully tagged node:latest
# Dockerイメージ(node)を実行する。
admin@ip-172-31-35-220:~/app$ sudo docker run -it --rm -p 8888:8888 node
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: []
}
Dockerイメージ(node)
を実行するとエラーがでます。 Error: Cannot find module '/usr/src/app/serve.js'
で /usr/src/app/srve.js
が無いといっています。
Dockerfile
を確認します。
admin@ip-172-31-35-220:~/app$ cat Dockerfile
# documentation https://nodejs.org/en/docs/guides/nodejs-docker-webapp/
# most recent node (security patches) and alpine (minimal, adds to security, possible libc issues)
FROM node:15.7-alpine
# Create app directory & copy app files
WORKDIR /usr/src/app
# we copy first package.json only, so we take advantage of cached Docker layers
COPY ./package*.json ./
# RUN npm ci --only=production
RUN npm install
# Copy app source
COPY ./* ./
# port used by this app
EXPOSE 8880
# command to run
CMD [ "node", "serve.js" ]
ふむふむ、最終行の serve.js
を実行しようとしています。
serve.js
があるのか確認します。
admin@ip-172-31-35-220:/$ cd /home/admin/app/
admin@ip-172-31-35-220:~/app$ ls
Dockerfile package-lock.json package.json server.js
存在するのは、server.js
なので、おそらく、Dockerfileのtypoですね。
また、port番号は8888なので、EXPOSE 8880
も修正します。
admin@ip-172-31-35-220:~/app$ cat Dockerfile
# documentation https://nodejs.org/en/docs/guides/nodejs-docker-webapp/
# most recent node (security patches) and alpine (minimal, adds to security, possible libc issues)
FROM node:15.7-alpine
# Create app directory & copy app files
WORKDIR /usr/src/app
# we copy first package.json only, so we take advantage of cached Docker layers
COPY ./package*.json ./
# RUN npm ci --only=production
RUN npm install
# Copy app source
COPY ./* ./
# port used by this app
EXPOSE 8888 # <== 8888に修正
# command to run
CMD [ "node", "server.js" ] # <== server.jsに修正
Dockerfile
を修正したので、再度、docker buildをして、docker runをする。
admin@ip-172-31-35-220:~/app$ sudo docker build -t node .
admin@ip-172-31-35-220:~/app$ sudo docker run -it --rm -p 8888:8888 node
Server Started on: 8888
正常に起動して、8888
で待ち受けているようです。
curl
で確認します。
admin@ip-172-31-34-17:~/app$ curl -v http://localhost:8888
* Trying 127.0.0.1:8888...
* Connected to localhost (127.0.0.1) port 8888 (#0)
> GET / HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 12
< ETag: W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE"
< Date: Mon, 26 Dec 2022 09:59:51 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
* Connection #0 to host localhost left intact
Hello World!
Hello World!
が返ってきました。成功です。
Discussion