LoginSignup
1
1

そうだ、Dockerを覚えよう(検証ログ)

Posted at

検証ログ。これを見てなにかの作業を行わないこと(手戻りも多々あるログです)。

覚えること(取り掛かる前の疑問)

  • dockerfile, docker-composeってなんだ
  • docker imageを開発メンバーで共有するためには?(docker hub?をローカルで作れる?)
  • docker-composePacemakerの絡み方
  • 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-composePacemakerの絡み方

参考URL集

なんかありそう。docker-composeベースでRA制御できんのかな。
でも毎回ビルドとかされちゃ敵わないな。

とりあえずやってみよう

dockerのインストール

参考URL集

インストールする方法は3種あるらしい。

  1. aptでいい感じに最新の物を入手
  2. .debを取得しておいてローカルインストール
  3. 自動インストールスクリプト

正直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

chmoda+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集

例題通りに脳みそ殺してバッドプラクティスを倣ってみる

index.js
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}`)
})
package.json
{
  "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
Dockerfile
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のバージョンは?

https://nodejs.org/ja
image.png

LTSの最新は18.17.1

image.png

2025-04-30までサポート。

docker HUB

image.png

slimがついているのは以下

  • 18.17.1-bookworm-slim
  • 18.17.1-slim
  • 18.17.1-bullseye-slim
  • 18.17.1-buster-slim

bookworm,bullseye,busterの違いは?

Docker imageの種類・選び方

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/tinialphinの場合らしい。我々は/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 $
1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1