0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Distribution で Docker イメージを管理する

Posted at

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

構成図

Distribution とは

Distribution は Docker イメージを管理するツールである。これを使うとセルフホスティングで Docker イメージを管理できる。

昔は Registry という名前だったが、別の機関に移管され、名前が変わったらしい。

Distribution の Docker イメージ名がregistryだったり所々にその名残りが見受けられるが、Distribution のことなんだなと思えば良い。

Distribution をデプロイする

Docker Compose で Distribution をデプロイしてみる。

以下のようなdocker-compose.ymlを作成する。

docker-compose.yml
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 も同時に導入している。

ポートは 8090 と 8091 に割り当てているが、好きに変えて良い。

以下のコマンドを実行し、コンテナを起動する。

$ docker compose up

Docker Registry UI (http://localhost:8091)にアクセスして、以下のような画面が表示されていれば良い。

Docker Registry UI

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.

以下のコマンドを実行し、アプリケーションが動作することを確認する。

$ npm run dev

Next.js

プロジェクトにDockerfile.dockerignoreを追加する。

 .
+├── .dockerignore
+├── Dockerfile
 ├── README.md
 ├── eslint.config.mjs
 ├── next-env.d.ts
 ├── next.config.ts
 ├── package-lock.json
 ├── package.json
 ├── public
 ├── src
 └── tsconfig.json
Dockerfile
# ビルド環境に必要なパッケージを用意したステージ
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 service docker restart

再度プッシュを試す。

Distribution に Docker イメージが登録されていることを確認する

Docker Registry UI にアクセスして、プッシュした Docker イメージが存在することを確認する。

Docker Registry UI

Docker Registry UI

Distribution に登録した Docker イメージを起動する

Distrubution から Docker イメージをプルし、起動する。

ローカルに Docker イメージがある場合、以下のコマンドで消しておく。

$ docker rmi -f xxx.xxx.xxx.xxx:xxxx/nextjs-example:0.1.0

以下のコマンドを実行する。

$ 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 イメージの起動に成功したと言える。

Next.js

その他

Distribution の状態は以下の API でも把握できる。

# イメージの一覧
http://xxx.xxx.xxx.xxx:xxxx/v2/_catalog

# タグの一覧
http://xxx.xxx.xxx.xxx:xxxx/v2/image-name/tags/list
0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?