Open9

Dockerのチュートリアルをやっていく

taichi fukumototaichi fukumoto

Docker Desktop のインストール

まずはマシンに「Docker Desktop」をインストールしていく。(マシンは M1 Mac mini)

https://www.docker.com/products/docker-desktop

M1 Mac なので「Mac with Apple Chip」を選択した。

Docker.dmgがインストールされるので、開いてインストールを進める。

taichi fukumototaichi fukumoto

Docker Desktop を開く

インストールした Docker Desktop を開いてみる。
アプリを開くと、チュートリアルが開始した。

指示に従い、コマンドを実行していく。
指示は以下の通り。

# Clone
# Getting Started のプロジェクトを GitHub リポジトリからクローン
# イメージを作成してコンテナとして実行するために必要なものが含まれている
$ git clone https://github.com/docker/getting-started.git

# Build
# イメージを作成
$ cd getting-started
$ docker build -t docker101tutorial .

# Run
# コンテナを実行
# 作成したイメージをもとにしてコンテナを起動
$ docker run -d -p 80:80 --name docker-tutorial docker101tutorial

# Share
# イメージを保存して共有
$ docker tag docker101tutorial michinosuke/docker101tutorial
$ docker push michinosuke/docker101tutorial

イメージを保存して共有するところで、Docker Hub にサインインするように求められた。アカウントを持っていなかったのでサインアップすると、初期設定を完了させることができた。

ダッシュボードを確認すると、コンテナが1つ起動していた。

taichi fukumototaichi fukumoto

ソースコードをダウンロードする

チュートリアル用のソースコードをダウンロードした。
ソースコードの入手は、ZIPファイルをダウンロードして解凍するだけ。

ダウンロードしたコードは自分のプロジェクトフォルダに移動させた方が良いと思う。

解凍したフォルダをVSCodeで開くと、以下のようなフォルダ構造になっていた。

app
├── spec
├── src
├── package.json
└── yarn.lock
taichi fukumototaichi fukumoto

コンテナイメージの作成

コンテナイメージを作成するために、Dockerfileを作成する。
Dockerfileは、appディレクトリ直下に作成する。

Terminal
$ touch Dockerfile

Dockerfile 作成後のディレクトリ構造はこのようになる。

app
├── spec
├── src
├── Dockerfile
├── package.json
└── yarn.lock

Dockerfile を作成したら、以下の内容を記述する。

Dockerfile
FROM node:12-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]

これで、イメージをビルドしてみる。

Terminal
$ docker build -t getting-started .

ここでエラーが出た。

Output
=> ERROR [4/4] RUN yarn install --production                                                                                                                                                                                                                                                                       7.9s
︙
全てのログ

文字数制限に引っかかったので、次のスクラップに貼っています。

https://zenn.dev/link/comments/520520f212dc13

ログを順に追うと、#8 7.682 gyp ERR! find Python と最初のエラーがあったので、とりあえずググってみるとQiitaの記事がヒットした。

https://qiita.com/yutake27/items/2b147547a5fd6cebf251

上記の記事によると、Dockerfileを以下のように書き換えたら良いらしい。

Dockerfile
  FROM node:12-alpine
+ RUN apk add --no-cache python make g++
  WORKDIR /app
  COPY . .
  RUN yarn install --production
  CMD ["node", "src/index.js"]

ということで、イメージの再ビルドに挑戦。

Terminal
$ docker build -t getting-started .
Output
[+] Building 66.4s (11/11) FINISHED 
︙

今度はうまく行った。よかった。

全てのログ
Output
[+] Building 66.4s (11/11) FINISHED                                                                                                                                                                                                                                                                                      
 => [internal] load build definition from Dockerfile                                                                                                                                                                                                                                                                0.0s
 => => transferring dockerfile: 183B                                                                                                                                                                                                                                                                                0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                                                                                                   0.0s
 => => transferring context: 2B                                                                                                                                                                                                                                                                                     0.0s
 => [internal] load metadata for docker.io/library/node:12-alpine                                                                                                                                                                                                                                                   2.2s
 => [auth] library/node:pull token for registry-1.docker.io                                                                                                                                                                                                                                                         0.0s
 => [internal] load build context                                                                                                                                                                                                                                                                                   0.0s
 => => transferring context: 6.73kB                                                                                                                                                                                                                                                                                 0.0s
 => CACHED [1/5] FROM docker.io/library/node:12-alpine@sha256:1ea5900145028957ec0e7b7e590ac677797fa8962ccec4e73188092f7bc14da5                                                                                                                                                                                      0.0s
 => [2/5] RUN apk add --no-cache python make g++                                                                                                                                                                                                                                                                    3.8s
 => [3/5] WORKDIR /app                                                                                                                                                                                                                                                                                              0.0s
 => [4/5] COPY . .                                                                                                                                                                                                                                                                                                  0.0s 
 => [5/5] RUN yarn install --production                                                                                                                                                                                                                                                                            58.7s 
 => exporting to image                                                                                                                                                                                                                                                                                              1.6s 
 => => exporting layers                                                                                                                                                                                                                                                                                             1.6s 
 => => writing image sha256:a014a6abde1fddd2ce814b4ab95532b51f08df69a9b7a35891f4e3407e836a72                                                                                                                                                                                                                        0.0s 
 => => naming to docker.io/library/getting-started                                                                                                                                                                                                                                                                  0.0s 
                                                                                                                                                                                                                                                                                                                         
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
taichi fukumototaichi fukumoto
エラーのログ
Output
[+] Building 14.3s (8/8) FINISHED                                                                                                                                                                                                                                                                                        
 => [internal] load build definition from Dockerfile                                                                                                                                                                                                                                                                0.0s
 => => transferring dockerfile: 142B                                                                                                                                                                                                                                                                                0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                                                                                                   0.0s
 => => transferring context: 2B                                                                                                                                                                                                                                                                                     0.0s
 => [internal] load metadata for docker.io/library/node:14-alpine                                                                                                                                                                                                                                                   2.1s
 => [1/4] FROM docker.io/library/node:14-alpine@sha256:6e52e0b3bedfb494496488514d18bee7fd503fd4e44289ea012ad02f8f41a312                                                                                                                                                                                             4.2s
 => => resolve docker.io/library/node:14-alpine@sha256:6e52e0b3bedfb494496488514d18bee7fd503fd4e44289ea012ad02f8f41a312                                                                                                                                                                                             0.0s
 => => sha256:9a60ff9faa70d044923a7ce899ffbab2d64161e2f53fe0ee54503671bd23d83e 36.47MB / 36.47MB                                                                                                                                                                                                                    2.9s
 => => sha256:6a74aa62eb957c480d8cdf5b7b3a9a24060354a04f878ee72966de090c7298a3 2.30MB / 2.30MB                                                                                                                                                                                                                      1.3s
 => => sha256:0095d421503975705451b6feee356bbe939b1ba79a72fad42678b90358deec1b 278B / 278B                                                                                                                                                                                                                          0.5s
 => => sha256:6e52e0b3bedfb494496488514d18bee7fd503fd4e44289ea012ad02f8f41a312 1.43kB / 1.43kB                                                                                                                                                                                                                      0.0s
 => => sha256:685d29d6f60ffaa1860996fd7f6f43d2b467be62eced44e5bbe1021bf3b18e36 1.16kB / 1.16kB                                                                                                                                                                                                                      0.0s
 => => sha256:a4408bae817645bebb8db8b6c78d3257a789737031720c21e357e32c4911c7f8 6.54kB / 6.54kB                                                                                                                                                                                                                      0.0s
 => => extracting sha256:9a60ff9faa70d044923a7ce899ffbab2d64161e2f53fe0ee54503671bd23d83e                                                                                                                                                                                                                           0.9s
 => => extracting sha256:6a74aa62eb957c480d8cdf5b7b3a9a24060354a04f878ee72966de090c7298a3                                                                                                                                                                                                                           0.1s
 => => extracting sha256:0095d421503975705451b6feee356bbe939b1ba79a72fad42678b90358deec1b                                                                                                                                                                                                                           0.0s
 => [internal] load build context                                                                                                                                                                                                                                                                                   0.0s
 => => transferring context: 6.69kB                                                                                                                                                                                                                                                                                 0.0s
 => [2/4] WORKDIR /app                                                                                                                                                                                                                                                                                              0.0s
 => [3/4] COPY . .                                                                                                                                                                                                                                                                                                  0.0s
 => ERROR [4/4] RUN yarn install --production                                                                                                                                                                                                                                                                       7.9s
------
 > [4/4] RUN yarn install --production:
#8 0.206 yarn install v1.22.5
#8 0.244 [1/4] Resolving packages...
#8 0.355 [2/4] Fetching packages...
#8 6.286 info fsevents@1.2.9: The platform "linux" is incompatible with this module.
#8 6.286 info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation.
#8 6.289 [3/4] Linking dependencies...
#8 6.643 [4/4] Building fresh packages...
#8 7.682 error /app/node_modules/sqlite3: Command failed.
#8 7.682 Exit code: 1
#8 7.682 Command: node-pre-gyp install --fallback-to-build
#8 7.682 Arguments: 
#8 7.682 Directory: /app/node_modules/sqlite3
#8 7.682 Output:
#8 7.682 node-pre-gyp info it worked if it ends with ok
#8 7.682 node-pre-gyp info using node-pre-gyp@0.11.0
#8 7.682 node-pre-gyp info using node@14.18.0 | linux | arm64
#8 7.682 node-pre-gyp WARN Using request for node-pre-gyp https download 
#8 7.682 node-pre-gyp info check checked for "/app/node_modules/sqlite3/lib/binding/node-v83-linux-arm64/node_sqlite3.node" (not found)
#8 7.682 node-pre-gyp http GET https://mapbox-node-binary.s3.amazonaws.com/sqlite3/v4.1.0/node-v83-linux-arm64.tar.gz
#8 7.682 node-pre-gyp http 403 https://mapbox-node-binary.s3.amazonaws.com/sqlite3/v4.1.0/node-v83-linux-arm64.tar.gz
#8 7.682 node-pre-gyp WARN Tried to download(403): https://mapbox-node-binary.s3.amazonaws.com/sqlite3/v4.1.0/node-v83-linux-arm64.tar.gz 
#8 7.682 node-pre-gyp WARN Pre-built binaries not found for sqlite3@4.1.0 and node@14.18.0 (node-v83 ABI, musl) (falling back to source compile with node-gyp) 
#8 7.682 node-pre-gyp http 403 status code downloading tarball https://mapbox-node-binary.s3.amazonaws.com/sqlite3/v4.1.0/node-v83-linux-arm64.tar.gz 
#8 7.682 gyp info it worked if it ends with ok
#8 7.682 gyp info using node-gyp@5.1.0
#8 7.682 gyp info using node@14.18.0 | linux | arm64
#8 7.682 gyp info ok 
#8 7.682 gyp info it worked if it ends with ok
#8 7.682 gyp info using node-gyp@5.1.0
#8 7.682 gyp info using node@14.18.0 | linux | arm64
#8 7.682 gyp ERR! find Python 
#8 7.682 gyp ERR! find Python Python is not set from command line or npm configuration
#8 7.682 gyp ERR! find Python Python is not set from environment variable PYTHON
#8 7.682 gyp ERR! find Python checking if "python" can be used
#8 7.682 gyp ERR! find Python - "python" is not in PATH or produced an error
#8 7.682 gyp ERR! find Python checking if "python2" can be used
#8 7.682 gyp ERR! find Python - "python2" is not in PATH or produced an error
#8 7.682 gyp ERR! find Python checking if "python3" can be used
#8 7.682 gyp ERR! find Python - "python3" is not in PATH or produced an error
#8 7.682 gyp ERR! find Python 
#8 7.682 gyp ERR! find Python **********************************************************
#8 7.682 gyp ERR! find Python You need to install the latest version of Python.
#8 7.682 gyp ERR! find Python Node-gyp should be able to find and use Python. If not,
#8 7.682 gyp ERR! find Python you can try one of the following options:
#8 7.682 gyp ERR! find Python - Use the switch --python="/path/to/pythonexecutable"
#8 7.682 gyp ERR! find Python   (accepted by both node-gyp and npm)
#8 7.682 gyp ERR! find Python - Set the environment variable PYTHON
#8 7.682 gyp ERR! find Python - Set the npm configuration variable python:
#8 7.682 gyp ERR! find Python   npm config set python "/path/to/pythonexecutable"
#8 7.682 gyp ERR! find Python For more information consult the documentation at:
#8 7.682 gyp ERR! find Python https://github.com/nodejs/node-gyp#installation
#8 7.682 gyp ERR! find Python **********************************************************
#8 7.682 gyp ERR! find Python 
#8 7.682 gyp ERR! configure error 
#8 7.682 gyp ERR! stack Error: Could not find any Python installation to use
#8 7.682 gyp ERR! stack     at PythonFinder.fail (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/find-python.js:307:47)
#8 7.682 gyp ERR! stack     at PythonFinder.runChecks (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/find-python.js:136:21)
#8 7.682 gyp ERR! stack     at PythonFinder.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/find-python.js:179:16)
#8 7.682 gyp ERR! stack     at PythonFinder.execFileCallback (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/find-python.js:271:16)
#8 7.682 gyp ERR! stack     at exithandler (child_process.js:390:5)
#8 7.682 gyp ERR! stack     at ChildProcess.errorhandler (child_process.js:402:5)
#8 7.682 gyp ERR! stack     at ChildProcess.emit (events.js:400:28)
#8 7.682 gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:280:12)
#8 7.682 gyp ERR! stack     at onErrorNT (internal/child_process.js:469:16)
#8 7.682 gyp ERR! stack     at processTicksAndRejections (internal/process/task_queues.js:82:21)
#8 7.682 gyp ERR! System Linux 5.10.47-linuxkit
#8 7.682 gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/app/node_modules/sqlite3/lib/binding/node-v83-linux-arm64/node_sqlite3.node" "--module_name=node_sqlite3" "--module_path=/app/node_modules/sqlite3/lib/binding/node-v83-linux-arm64" "--napi_version=8" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v83"
#8 7.682 gyp ERR! cwd /app/node_modules/sqlite3
#8 7.682 gyp ERR! node -v v14.18.0
#8 7.682 gyp ERR! node-gyp -v v5.1.0
#8 7.682 gyp ERR! not ok 
#8 7.682 node-pre-gyp ERR! build error 
#8 7.682 node-pre-gyp ERR! stack Error: Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/app/node_modules/sqlite3/lib/binding/node-v83-linux-arm64/node_sqlite3.node --module_name=node_sqlite3 --module_path=/app/node_modules/sqlite3/lib/binding/node-v83-linux-arm64 --napi_version=8 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v83' (1)
#8 7.682 node-pre-gyp ERR! stack     at ChildProcess.<anonymous> (/app/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
#8 7.682 node-pre-gyp ERR! stack     at ChildProcess.emit (events.js:400:28)
#8 7.682 node-pre-gyp ERR! stack     at maybeClose (internal/child_process.js:1058:16)
#8 7.682 node-pre-gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:293:5)
#8 7.682 node-pre-gyp ERR! System Linux 5.10.47-linuxkit
#8 7.682 node-pre-gyp ERR! command "/usr/local/bin/node" "/app/node_modules/sqlite3/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
#8 7.682 node-pre-gyp ERR! cwd /app/node_modules/sqlite3
#8 7.682 node-pre-gyp ERR! node -v v14.18.0
#8 7.682 node-pre-gyp ERR! node-pre-gyp -v v0.11.0
#8 7.682 node-pre-gyp ERR! not ok 
#8 7.682 Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/app/node_modules/sqlite3/lib/binding/node-v83-linux-arm64/node_sqlite3.node --module_name=node_sqlite3 --module_path=/app/node_modules/sqlite3/lib/binding/node-v83-linux-arm64 --napi_version=8 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v83' (1)
#8 7.682 info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
------
executor failed running [/bin/sh -c yarn install --production]: exit code: 1
taichi fukumototaichi fukumoto

コンテナの起動

イメージのビルドが完了し、コンテナを起動させる準備ができたので、以下のコマンドでコンテナを起動する。

Terminal
docker run -dp 3000:3000 getting-started
Output
856e213db60e75d16c870ca194fdb7adff800c461e795cf00327b8d63c136d42

http://localhost:3000/ にアクセスしてみて、アプリが表示されればOK。

Docker Desktop のダッシュボードを確認すると、チュートリアルのコンテナとは別に今起動したアプリのコンテナが追加され、2つのコンテナが起動していた。

taichi fukumototaichi fukumoto

ソースコードの更新

src/static/js/app.jsの56行目を以下のように編集する。

src/static/js/app.js
 - <p className="text-center">No items yet! Add one above!</p>
+ <p className="text-center">You have no todo items yet! Add one above!</p>
 

再度、イメージをビルドし、コンテナを起動してみる。

Terminal
# イメージのビルド
$ docker build -t getting-started .

# コンテナの起動
$ docker run -dp 3000:3000 getting-started

すると、エラーが出る。

Output
3c8570555a53c7bd3e423b8c861b9e21f85fdbf764d08964ef99ba45f56e09fa
docker: Error response from daemon: driver failed programming external connectivity on endpoint recursing_gould (7c90aa5ed3378a86c9e8a0bb98eb5163c843877f4493cce4f672a234b9229a8d): Bind for 0.0.0.0:3000 failed: port is already allocated.

さっき起動したコンテナですでに localhost の 3000 番を使用していたがためのエラーのようだ。

そこで古いコンテナを停止して削除する。

やり方は2通りある。

CLI でコンテナを削除する場合

以下のコマンドを順に実行していく。

まず、起動中のコンテナを確認。

Terminal
#  起動中のコンテナを一覧表示
$ docker ps
Output
CONTAINER ID   IMAGE                    COMMAND                  CREATED             STATUS             PORTS                    NAMES
856e213db60e   a014a6abde1f             "docker-entrypoint.s…"   About an hour ago   Up About an hour   0.0.0.0:3000->3000/tcp   sharp_lamport
8ef62f9ef075   docker/getting-started   "/docker-entrypoint.…"   23 hours ago        Up 19 hours        0.0.0.0:80->80/tcp       loving_knuth

次に、コンテナを停止する。

Terminal
# コンテナを停止
# docker stop <the-container-id>
# <the-container-id> は、`docker ps` で確認した CONTAINER ID 
$ docker stop 856e213db60e

最後にコンテナを削除する。

Terminal
# コンテナを削除
# docker rm <the-container-id>
# <the-container-id> は、`docker ps` で確認した CONTAINER ID 
$ docker rm 856e213db60e

GUI でコンテナを削除する場合

Docker Desktop のダッシュボードからも削除は可能。
コンテナにカーソルを合わせると、右側にアイコンが現れる。ゴミ箱マークをクリックするとコンテナが削除される。

古いコンテナを削除したら、更新したアプリを起動する。

Terminal
$ docker run -dp 3000:3000 getting-started

http://localhost:3000/ にアクセスしてみて、アプリが表示されればOK。