Distribution で Docker イメージを管理する
以下のような Docker イメージを管理できる環境を構築してみる。

Distribution とは
Distribution は Docker イメージを管理するツールである。これを使うとセルフホスティングで Docker イメージを管理できる。
昔は Registry という名前だったが、別の機関に移管され、名前が変わったらしい。
Distribution の Docker イメージ名がregistryだったり所々にその名残りが見受けられるが、Distribution のことなんだなと思えば良い。
Distribution をデプロイする
Docker Compose で Distribution をデプロイしてみる。
以下のようなdocker-compose.ymlを作成する。
| docker-compose.yml |
|---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | services:
registry:
image: registry:latest
ports:
- 8090:5000
volumes:
- ./distribution/registry:/var/lib/registry
restart: always
registry-ui:
image: joxit/docker-registry-ui:main
restart: always
ports:
- 8091:80
environment:
- SINGLE_REGISTRY=true
- REGISTRY_TITLE=Docker Registry UI
- DELETE_IMAGES=true
- SHOW_CONTENT_DIGEST=true
- NGINX_PROXY_PASS_URL=http://registry:5000
- SHOW_CATALOG_NB_TAGS=true
- CATALOG_MIN_BRANCHES=1
- CATALOG_MAX_BRANCHES=1
- TAGLIST_PAGE_SIZE=100
- REGISTRY_SECURED=false
- CATALOG_ELEMENTS_LIMIT=1000
|
Distribution は画面を持たず動作確認が大変なので、Docker Registry User Interface も同時に導入している。
GitHub - Joxit/docker-registry-ui: The simplest and most complete UI for your private docker registry v2 and v3
ポートは 8090 と 8091 に割り当てているが、好きに変えて良い。
以下のコマンドを実行し、コンテナを起動する。
Docker Registry UI (http://localhost:8091)にアクセスして、以下のような画面が表示されていれば良い。

Docker イメージを作成する
Distribution に登録する Docker イメージを作成する。既に手元に登録したい Docker イメージがある場合、この手順を無視して良い。
Docker で動く Next.js アプリケーションを作ってみる。
| $ npx create-next-app@latest
|
適当に答える。
| ✔ What is your project named? … nextjs-example
✔ Would you like to use TypeScript? … No / Yes
✔ Which linter would you like to use? › ESLint
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack? (recommended) … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /path/to/nextjs-example.
|
以下のコマンドを実行し、アプリケーションが動作することを確認する。

プロジェクトにDockerfileと.dockerignoreを追加する。
1
2
3
4
5
6
7
8
9
10
11
12 | .
├── .dockerignore
├── Dockerfile
├── README.md
├── eslint.config.mjs
├── next-env.d.ts
├── next.config.ts
├── package-lock.json
├── package.json
├── public
├── src
└── tsconfig.json
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 | # ビルド環境に必要なパッケージを用意したステージ
FROM node:22.19.0 AS development-dependencies-env
# ファイルをコピーする
WORKDIR /app
COPY . /app
# パッケージをインストールする
RUN npm ci
# ビルドする
RUN npm run build
# プロダクション環境に必要なパッケージだけを用意したステージ
FROM node:22.19.0 AS production-dependencies-env
WORKDIR /app
COPY ./package.json ./package-lock.json /app
RUN npm ci --omit=dev
# プロダクションステージ
FROM node:22.19.0-slim AS production
WORKDIR /app
# npm run startを実行するためにpackage.jsonをコピーする
COPY --chown=node:node --from=production-dependencies-env /app/package.json /app/package-lock.json /app
# アプリケーションの実行に必要なパッケージをコピーする
COPY --chown=node:node --from=production-dependencies-env /app/node_modules /app/node_modules
# Next.jsアプリケーションのビルド結果をコピーする
COPY --chown=node:node --from=development-dependencies-env /app/.next /app/.next
# リソースをコピーする
COPY --chown=node:node --from=development-dependencies-env /app/public /app/public
# ポートを公開する
EXPOSE 3000
# 実行する
WORKDIR /app
USER node
CMD ["npm", "run", "start"]
|
| .dockerignore |
|---|
| .dockerignore
.env
.git/
.gitignore
.next/
Dockerfile
README.md
node_modules/
|
以下のコマンドを実行して Docker イメージを作成する。
| $ docker build -t nextjs-example:0.1.0 .
|
以下のコマンドを実行して、一覧にnextjs-exampleが存在すれば Docker イメージの作成に成功している。
| $ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nextjs-example 0.1.0 281ecaea52cb 51 seconds ago 700MB
|
Docker イメージを Distribution にプッシュする
以降 Distribution をデプロイしているホストの IP アドレスと Distribution のポート番号をxxx.xxx.xxx.xxx:xxxxと表現する。
タグを作成する。
| $ docker tag nextjs-example:0.1.0 xxx.xxx.xxx.xxx:xxxx/nextjs-example:0.1.0
|
Distribution にプッシュする。
| $ docker push xxx.xxx.xxx.xxx:xxxx/nextjs-example:0.1.0
|
docker push時にhttp: server gave HTTP response to HTTPS clientというエラーが出る場合
docker push時に以下のエラーが発生することがある。
| $ docker push xxx.xxx.xxx.xxx:xxxx/nextjs-example:0.1.0
The push refers to repository [xxx.xxx.xxx.xxx:xxxx/nextjs-example]
Get "https://xxx.xxx.xxx.xxx:xxxx/v2/": http: server gave HTTP response to HTTPS client
|
これを解決するにはDocker イメージをプッシュする側の/etc/docker/daemon.jsonにて以下の設定を行う。ファイルがない場合は作成する。
| /etc/docker/daemon.json |
|---|
| {
"insecure-registries": ["xxx.xxx.xxx.xxx:xxxx"]
}
|
以下のコマンドを実行し、Docker を再起動する。
| $ sudo systemctl restart docker.service docker.socket
|
Rootless モードの場合、以下になる。
| $ mkdir -p ~/.config/docker
|
| ~/.config/docker/daemon.json |
|---|
| {
"insecure-registries": ["xxx.xxx.xxx.xxx:xxxx"]
}
|
| $ systemctl --user restart docker.service
|
再度プッシュを試す。
Distribution に Docker イメージが登録されていることを確認する
Docker Registry UI にアクセスして、プッシュした Docker イメージが存在することを確認する。


Distribution に登録した Docker イメージを起動する
Distrubution から Docker イメージをプルし、起動する。
ローカルに Docker イメージがある場合、以下のコマンドで消しておく。
| $ docker rmi -f xxx.xxx.xxx.xxx:xxxx/nextjs-example:0.1.0
|
以下のコマンドを実行する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | $ docker run -p 8082:3000 xxx.xxx.xxx.xxx:xxxx/nextjs-example:0.1.0
Unable to find image 'xxx.xxx.xxx.xxx:xxxx/nextjs-example:0.1.0' locally
0.1.0: Pulling from nextjs-example
Digest: sha256:895c9b761a593f98979b806e2ca0128c6f86d7c9dd7c78b3818bf6f8e349f08f
Status: Downloaded newer image for xxx.xxx.xxx.xxx:xxxx/nextjs-example:0.1.0
> nextjs-example@0.1.0 start
> next start
▲ Next.js 15.5.3
- Local: http://localhost:3000
- Network: http://yyy.yyy.yyy.yyy:3000
✓ Starting...
✓ Ready in 250ms
|
上の例だとポート 3000 を 8082 に割り当てているので、http://localhost:8082にアクセスし、以下の画面が表示されれば Distribution に登録した Docker イメージの起動に成功したと言える。

その他
Distribution の状態は以下の API でも把握できる。
| # イメージの一覧
http://xxx.xxx.xxx.xxx:xxxx/v2/_catalog
# タグの一覧
http://xxx.xxx.xxx.xxx:xxxx/v2/image-name/tags/list
|