Dockerのチュートリアルをやっていく
Dockerの公式チュートリアルをやっていく
Docker Desktop のインストール
まずはマシンに「Docker Desktop」をインストールしていく。(マシンは M1 Mac mini)
M1 Mac なので「Mac with Apple Chip」を選択した。
Docker.dmg
がインストールされるので、開いてインストールを進める。
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つ起動していた。
Docker Tutorial
Docker Desktop を始めて開いた時に行なったチュートリアルで作成したコンテナにアクセスすることで、より詳しい Docker Tutorial を始めることができる。
http://localhost にアクセスする。
このチュートリアルについては、Qiita に和訳記事があった。
ソースコードをダウンロードする
チュートリアル用のソースコードをダウンロードした。
ソースコードの入手は、ZIPファイルをダウンロードして解凍するだけ。
ダウンロードしたコードは自分のプロジェクトフォルダに移動させた方が良いと思う。
解凍したフォルダをVSCodeで開くと、以下のようなフォルダ構造になっていた。
app
├── spec
├── src
├── package.json
└── yarn.lock
コンテナイメージの作成
コンテナイメージを作成するために、Dockerfile
を作成する。
Dockerfile
は、app
ディレクトリ直下に作成する。
$ touch Dockerfile
Dockerfile
作成後のディレクトリ構造はこのようになる。
app
├── spec
├── src
├── Dockerfile
├── package.json
└── yarn.lock
Dockerfile
を作成したら、以下の内容を記述する。
FROM node:12-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
これで、イメージをビルドしてみる。
$ docker build -t getting-started .
ここでエラーが出た。
︙
=> ERROR [4/4] RUN yarn install --production 7.9s
︙
全てのログ
文字数制限に引っかかったので、次のスクラップに貼っています。
ログを順に追うと、#8 7.682 gyp ERR! find Python
と最初のエラーがあったので、とりあえずググってみるとQiitaの記事がヒットした。
上記の記事によると、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"]
ということで、イメージの再ビルドに挑戦。
$ docker build -t getting-started .
[+] Building 66.4s (11/11) FINISHED
︙
今度はうまく行った。よかった。
全てのログ
[+] 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
エラーのログ
[+] 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
コンテナの起動
イメージのビルドが完了し、コンテナを起動させる準備ができたので、以下のコマンドでコンテナを起動する。
docker run -dp 3000:3000 getting-started
856e213db60e75d16c870ca194fdb7adff800c461e795cf00327b8d63c136d42
http://localhost:3000/ にアクセスしてみて、アプリが表示されればOK。
Docker Desktop のダッシュボードを確認すると、チュートリアルのコンテナとは別に今起動したアプリのコンテナが追加され、2つのコンテナが起動していた。
ソースコードの更新
src/static/js/app.js
の56行目を以下のように編集する。
︙
- <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>
︙
再度、イメージをビルドし、コンテナを起動してみる。
# イメージのビルド
$ docker build -t getting-started .
# コンテナの起動
$ docker run -dp 3000:3000 getting-started
すると、エラーが出る。
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 でコンテナを削除する場合
以下のコマンドを順に実行していく。
まず、起動中のコンテナを確認。
# 起動中のコンテナを一覧表示
$ docker ps
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
次に、コンテナを停止する。
# コンテナを停止
# docker stop <the-container-id>
# <the-container-id> は、`docker ps` で確認した CONTAINER ID
$ docker stop 856e213db60e
最後にコンテナを削除する。
# コンテナを削除
# docker rm <the-container-id>
# <the-container-id> は、`docker ps` で確認した CONTAINER ID
$ docker rm 856e213db60e
GUI でコンテナを削除する場合
Docker Desktop のダッシュボードからも削除は可能。
コンテナにカーソルを合わせると、右側にアイコンが現れる。ゴミ箱マークをクリックするとコンテナが削除される。
古いコンテナを削除したら、更新したアプリを起動する。
$ docker run -dp 3000:3000 getting-started
http://localhost:3000/ にアクセスしてみて、アプリが表示されればOK。