検証ログ。これを見てなにかの作業を行わないこと(手戻りも多々あるログです)。
覚えること(取り掛かる前の疑問)
-
dockerfile
,docker-compose
ってなんだ -
docker image
を開発メンバーで共有するためには?(docker hub
?をローカルで作れる?) -
docker-compose
とPacemaker
の絡み方 -
Node.js
のAppをコンテナ化する時にImage
にファイルを入れるのか、Volume
で常にホストをマウントするのか(前者だと思ってるけどネタがなさすぎる)
dockerfile
, docker-compose
ってなんだ
Docker周りで用語が多すぎる。ざっくり理解する。
参考URL集
用語 | 内容 |
---|---|
dockerfile | 1つのコンテナのレシピ |
docker-compose.yml | 複数のコンテナを組み合わせたアプリのレシピ |
docker Engine | docker操作用のUI。CLIベース。Ubuntuでやるならだいたいこっち |
docker Desktop | docker操作用のUI。GUIベース。Windows, Macはこっちだった。仮想マシンを作って操作する |
docker-compose
とPacemaker
の絡み方
参考URL集
なんかありそう。docker-compose
ベースでRA制御できんのかな。
でも毎回ビルドとかされちゃ敵わないな。
とりあえずやってみよう
dockerのインストール
参考URL集
インストールする方法は3種あるらしい。
-
apt
でいい感じに最新の物を入手 -
.deb
を取得しておいてローカルインストール - 自動インストールスクリプト
正直3つ目はなんのこっちゃ。
構成管理マンとしては「2.」が好きだけど一旦「1.」で試しておく。
まずapt
リポジトリを最新化し、docker
関連のapt
リポジトリを入手するために必要なパッケージを取得
# aptリポジトリを最新化
$ sudo apt update
# docker関連のaptリポジトリを追加するために必要なパッケージを取得
$ sudo apt install ca-certificates curl gnupg lsb-release
DockerのGPGの鍵をaptに登録する。
参考:GPGとは
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
chmod
にa+r
ってなんだ?って思ったけど「all + r」のことか。普段chmod +x
とか略しちゃっているけど明記するとa+x
になるんだな。
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
tee
ってなんだっけ。
teeコマンドとは? 「tee」は標準入力から受け取った内容を、標準出力とファイルに書き出すコマンドです。 ファイルへの保存と標準出力への出力を同時に行ったり、複数のファイルに出力したりすることができます。
いや、じゃあ/dev/null
に出すならtee
じゃなくていいじゃん…駄目?
$ sudo apt update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
参考にしている2つのサイトで最後に上記で差分が出た。docker-compose-plugin
の有無。これずっと昔に一瞬docker
触った時に覚えてる。ゆくゆく必要になるから先に入れておいたほうが良いって。
と思ったけど、指定しなくても入ってた。他のいずれかと一緒にインストールされてたみたい。
$ docker -v
Docker version 24.0.6, build ed223bc
一般ユーザでもdockerを実行できるようにする
$ getent group | grep docker
docker:x:999:
$ sudo usermod -aG docker $USER
$ getent group | grep docker
docker:x:999:udon
一旦ログインし直してid
コマンドで所属を確認する。
$ id
uid=1000(udon) gid=1000(udon) groups=1000(udon),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd),999(docker)
動作確認
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
dockerfile書いてみる
Node.js
をコンテナで起動するお作法を学ぶ。
参考URL集
例題通りに脳みそ殺してバッドプラクティスを倣ってみる
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
{
"name": "nodejs-docker",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "conop",
"license": "MIT",
"dependencies": {
"express": "^4.18.1"
}
}
$ ls -ltR ../opt
../opt:
total 8
-rw-rw-r-- 1 udon udon 214 Sep 18 14:42 pakcage.json
-rw-rw-r-- 1 udon udon 219 Sep 18 14:41 index.js
FROM node
WORKDIR /app
COPY . .
RUN yarn install
CMD "yarn" "start"
$ docker build -t nodejs-docker .
:
[+] Building 55.9s (9/9) FINISHED docker:default
:
docker run -p 3000:3000 nodejs-docker
>> yarn run v1.22.18
>> $ node index.js
>> sample app listening on port 3000
$ docker image ls nodejs-docker
REPOSITORY TAG IMAGE ID CREATED SIZE
nodejs-docker latest cce892b92beb 17 minutes ago 1.1GB
node.jsのバージョンは?
LTSの最新は18.17.1
。
2025-04-30までサポート。
slim
がついているのは以下
- 18.17.1-bookworm-slim
- 18.17.1-slim
- 18.17.1-bullseye-slim
- 18.17.1-buster-slim
bookworm
,bullseye
,buster
の違いは?
Debianのバージョンらしい。実績の多いbullseye
を使いたい反面、セキュリティ面でも最新のbookworm
を選ぶか悩むところ…
$ cat Dockerfile
FROM node:18.17.1-bookworm-slim
WORKDIR /app
COPY . .
RUN yarn install
CMD "yarn" "start"
$ docker build -t nodejs-docker .
$ docker image ls nodejs-docker
REPOSITORY TAG IMAGE ID CREATED SIZE
nodejs-docker latest df64eef74043 2 seconds ago 249MB
うぉー!めっちゃ減った。感動。
$ cat Dockerfile
FROM node:18.17.1-bookworm-slim
WORKDIR /app
COPY . .
RUN yarn install --prod --frozen-lockfile
CMD "yarn" "start"
$ cat Dockerfile
FROM node:18.17.1-bookworm-slim
WORKDIR /app
COPY package.json ./
RUN yarn install --prod --frozen-lockfile
COPY . .
CMD "yarn" "start"
yarn
でパッケージ管理したことがないのでyarn.lock
が無く、一旦外している。
tini
を噛ますことで諸々解決するみたい
$ cat Dockerfile
FROM node:18.17.1-bookworm-slim
WORKDIR /app
RUN apk add --no-cache tini
COPY package.json ./
RUN yarn install --prod --frozen-lockfile
COPY . .
ENTRYPOINT ["/sbin/tini", "--" ]
CMD "node", "index.js"
$ cat Dockerfile
FROM node:18.17.1-bookworm-slim
ENV NODE_ENV production
WORKDIR /app
RUN apt-get update
RUN apt-get install -y tini
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/sbin/tini", "--" ]
COPY --chown=node:node package.json ./
RUN yarn install --prod --frozen-lockfile
COPY --chown=node:node . .
USER node
CMD "node", "index.js"
$ docker image ls nodejs-docker
REPOSITORY TAG IMAGE ID CREATED SIZE
nodejs-docker latest ac301270a047 53 seconds ago 270MB
$ docker run -p 3000:3000 nodejs-docker
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/sbin/tini": stat /sbin/tini: no such file or directory: unknown.
ERRO[0000] error waiting for container:
あれ、/sbin/tini
が見つからない。
調べたら/sbin/tini
はalphin
の場合らしい。我々は/usr/sbin/tini
でやる。
$ cat Dockerfile
FROM node:18.17.1-bookworm-slim
ENV NODE_ENV production
WORKDIR /app
RUN apt-get update
RUN apt-get install -y tini
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini", "--" ]
COPY --chown=node:node package.json ./
RUN yarn install --prod --frozen-lockfile
COPY --chown=node:node . .
USER node
CMD which tini
CMD "node", "index.js"
$ docker run -p 3000:3000 nodejs-docker
/bin/sh: 1: node,: not found
ムキー!!!
$ cat Dockerfile
FROM node:18.17.1-bookworm-slim
ENV NODE_ENV production
WORKDIR /app
RUN apt-get update
RUN apt-get install -y tini
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini", "--" ]
COPY --chown=node:node package.json ./
RUN yarn install --prod --frozen-lockfile
COPY --chown=node:node . .
USER node
CMD ["node", "index.js"]
最後、CMD
をJson書きにしてなかったわ。
$ docker run -p 3000:3000 nodejs-docker
Example app listening on port 3000
^C $