今回の環境
- 生成AIの登場によって、プログラミングの敷居が下がったことで、自分の作ったアプリを社内に公開して業務を改善したい、というニーズが増えてきた
- そこで、Dockerベースでアプリを作成し、所定のリポジトリにコードを格納したら自動的に公開できる仕組みを構築した
アーキテクチャ
- 事前に用意したECRのスロットに応じて、デプロイしたアプリは、
https://hoge.domain.com/app1/のようにパス別で配置され社内に公開される
本題
- 今回Next.jsでWebアプリを作成し、この環境で公開した
- この環境では、ALBはサブパスごとに接続するターゲット(コンテナ)を振り分けるわけだが、このサブパスで公開される点について、Next.jsではいろいろと考慮が必要だった(苦しんだ)ため、共有したい
ケース1:パス書き換えを行わないケース
- 最初のケースではALBのサブパスと、Dockerのサブパスを一致(パスの書き換えを行わない)ケースとなる。ALBは元々この方式しか採れなかった
- Next.jsアプリは
/service-01/上で公開すればいいので、これは普通にbasepathを追加した
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
basePath: "/service-01", // 追加
};
export default nextConfig;
- 正常に表示された、と思いきや、画像や
/publicフォルダに配置しているファイルへのLinkが切れてしまっていた - これらを最初アセットと捉え、assetPrefixも追加してみた
const nextConfig: NextConfig = {
basePath: "/service-01",
assetPrefix: "/service-01",
};
- としたところ、画像どころかアプリ本体のJSファイルまでLink切れになり、まともにアプリが動かない
- assetPrefixは今回のケースでは使えないことがわかった
- 苦肉の策として、以下のようにサブパスを明示的に差し込んで対応した
<Image
src="/service-01/images/flow.svg" // /images/flow.svg から変更
alt="アプリケーションのフロー図"
/>
ケース1の結論
- next.config.ts には
baesPathを設定する - 画像などのファイルへのLinkはサブパスを考慮し、参照先をソースコード側で書き換える
ケース2:パス書き換えのケース
- 2025年10月のUpdateで、ALBがパス書き換え可能となったため、一般的なリバースプロキシの方式で、ALBのサブパスをDockerのルートパスにマッピングする方式を導入した
- これならば、Next.js側(Docker側)はbasePathを考慮する必要がないので、ケース1のような書き換えが不要だと考え公開した
- が、動かない。本体のJSファイルを
https://hoge.domain.com/_next/xxxxxx.jsに参照しに行ってしまっている! - ここで
assetPrefixの出番、ということで追加した
const nextConfig: NextConfig = {
assetPrefix: "/service-02", // 追加
};
- これで動いた、と思いきや、画像やファイルへのLinkが切れている
- 結局こちらのケースでも画像やファイルへのLinkはサブパスを明示的に差し込んで対応した
ケース2の結論
- next.config.ts には
assetPrefixを設定する - 画像などのファイルへのLinkはサブパスを考慮し、参照先をソースコード側で書き換える
まとめ
- Next.jsはリバースプロキシ/ALBで公開されるパスを考慮し構築する必要がある。
| 対象 | 注意点 |
|---|---|
| basePath | Docker側でサブパス上でアプリを動かす場合に必要 |
| assetPrefix |
_next/配下で提供されるNext.jsのクライアントJSコードやCSSのサブパスをbasePathに対して変更する |
| 画像など |
next.config.tsで一括の変更はできないため、基本的には公開されるパスを意識してコーディング必要 |
余談
- もともと
インフラを意識しないでアプリを開発して気軽に公開というコンセプトで今回の環境を構築したわけだが、Next.js側でサブパスを意識しなきゃいけないのは失敗だった - サブパスではなく、サブドメインでアプリを振り分ける方式にすべきだと感じた


