/etc/nginx/sites-available/配下の設定ファイルを1行ずつ編集し、サービスをリロードした瞬間に真っ赤な構文エラーが表示される――これはWebサーバー管理者なら誰もが通る道でしょう。CertbotによるSSL更新のたびにcronジョブが正常に動くか気を揉んだり、インフラが拡大してサブドメインが15〜20個に達すると手動設定でのミスも多発しがちです。Nginx Proxy Manager(NPM)を使えば、これらの煩雑な作業を直感的なWeb UIに集約し、長大な設定ファイルの編集をシンプルな入力フォームへと置き換えることができます。
1. クイックスタート:5分で始めるNginx Proxy Managerのデプロイ
クリーンインストール直後のUbuntu 22.04または24.04 VPSにおいて、社内・内部Webアプリケーション向けのリバースプロキシゲートウェイとして最初に構築することが多い構成です。必要なコンポーネントはすべてDocker Composeにパッケージ化されています。
UbuntuにDockerエンジンとComposeプラグインをインストールします:
sudo apt update && sudo apt install -y docker.io docker-compose-v2
sudo systemctl enable --now docker
設定ファイルを配置するディレクトリを作成します:
mkdir -p ~/npm && cd ~/npm
nano docker-compose.yml
docker-compose.ymlに以下の内容を貼り付けます:
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
バックグラウンドでコンテナを起動します:
docker compose up -d
SQLiteデータベースの初期化が完了するまで30〜45秒ほど待ち、ブラウザからhttp://IP_SERVER:81にアクセスします。
初期ログイン情報:
- Email:
[email protected] - Password:
changeme
初回ログイン時にメールアドレスとパスワードの変更が求められます。ポート81がインターネットに公開されている状態のため、この変更作業はスキップせず必ず実施してください。
2. 詳細解説:Nginx Proxy Managerの動作メカニズム
従来のNginx運用で陥りがちな課題
従来の手法では、ドメインをNode.jsアプリ(ポート3000)やDockerコンテナ(ポート8080)へルーティングする際、仮想ホスト設定ファイルを個別に作成する必要がありました。その中にはupstreamやlocation /ブロックの定義、proxy_passの調整、X-Real-IPやX-Forwarded-Forなどの適切なヘッダー転送設定が含まれます。
さらにCertbotを実行してSSL証明書を取得する手順も伴います。数十個のアプリを運用する規模になると、1つのファイルでセミコロン;を忘れただけでNginx全体のリロードが失敗するリスクを抱えることになります。
Nginx Proxy Managerはどのように解決するか?
NPMはNginxをゼロから再実装したものではなく、コンテナ内部で稼働するNginxとCertbotを制御するWeb管理パネルとして機能します:
- Web UIでホストを作成するたびに、
./data/nginx/proxy_host/ディレクトリ配下に適切な形式の.confファイルが自動生成されます。 - コンテナ内のCertbotが自動的にHTTP-01またはDNS-01によるACMEチャレンジを実行し、Let’s Encryptから証明書を取得して
./letsencryptへ保存します。 - アクティブなHTTP接続を切断することなく、即座に
nginx -s reloadシグナルを発行して設定を反映します。
プロキシホスト作成のステップガイド
- メニューのHosts → Proxy Hostsを開き、Add Proxy Hostボタンをクリックします。
- Detailsタブ:
- Domain Names: ドメイン名(例:
api.itfromzero.com)を入力します。DNSのAレコードがVPSのIPアドレスを正しく指していることを事前に確認してください。 - Scheme: 内部アプリ側でSSLが未有効の場合は
httpのままにします。 - Forward Hostname / IP: サーバーのローカルIP、または同一ネットワーク内のDockerコンテナ名を入力します。
- Forward Port: アプリケーションのポート番号(例:
3000)を指定します。 - Websockets Supportをオンにします(Socket.io、NestJS、ライブリロードやチャット機能を持つNext.jsなどを利用する場合は必須です)。
- Block Common Exploitsを有効化し、基本的なSQLインジェクションやディレクトリトラバーサルなどの悪意あるペイロードをフィルタリングします。
- Domain Names: ドメイン名(例:
- SSLタブ:
- SSL Certificate: Request a new SSL Certificateを選択します。
- Force SSLをオンにし、HTTP(ポート80)への全アクセスをHTTPS(ポート443)へ強制リダイレクトします。
- HTTP/2 SupportとHSTS Enabledを有効化して、ページの読み込み速度向上とプロトコルダウングレード攻撃への対策を施します。
- I Agree to the Let’s Encrypt Terms of Serviceにチェックを入れ、Saveをクリックします。
3. 発展編:Access Listsと内部Docker Networkの活用
Access Listsによる管理画面のアクセス制限
Portainer、pgAdmin、社内バックアップツールなどのセンシティブなダッシュボードを誰でも閲覧可能な状態で公開するべきではありません。NPMのAccess Lists機能を用いれば、2段階のセキュリティレイヤーを実装できます:
- HTTP Basic Authentication: アプリケーション本来のログイン画面に到達する前に、ブラウザのダイアログでユーザー名とパスワードの認証を要求します。
- IP Whitelisting: 指定した固定IPレンジ(社内ネットワークのIP
14.241.x.x/32やWireGuard VPNのIPなど)からの接続のみを許可し、それ以外の外部アクセスには403 Forbiddenを返します。
Docker Networkを介したコンテナ間の直接接続
ports: ["8080:8080"]のようにポートをホスト外へ直接公開すると、自動スキャンボットの標的になりやすくなります。最も安全なアプローチは、NPMとバックエンドアプリを同一の内部ブリッジネットワークに所属させる構成です:
# 共通ブリッジネットワークを作成
docker network create proxy-net
このネットワークを利用するようにNginx Proxy Managerのdocker-compose.ymlを更新します:
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- proxy-net
networks:
proxy-net:
external: true
docker compose up -dを実行して変更を適用します。これにより、proxy-netに参加しているWebアプリであれば、NPM管理画面のForward HostnameにIPアドレスではなくコンテナ名(例: strapi-cmsやgrafana)を直接指定して通信できるようになります。
4. Ubuntu環境での実践・運用ノウハウ
既存VPSにおけるポート80/443の競合解消
セットアップ時によく遭遇するエラーがDockerのbind: address already in useです。これはホスト上で他のプロセスがすでにポート80または443を占有していることを意味します。以下のコマンドで原因となっているプロセスを特定してください:
sudo ss -tulpn | grep -E ':(80|443)'
Ubuntuにプリインストールされたapache2やnginxがポートを占有している場合は、サービスを停止して自動起動を無効化します:
sudo systemctl stop nginx apache2
sudo systemctl disable nginx apache2
管理ポート81のインターネット公開を防ぐ
ポート81をグローバルに開放したままにしておくと、管理者アカウントへのブルートフォース攻撃を受けるリスクが高まります。以下の2つの対策が推奨されます:
- docker-compose.ymlでバインドIPを制限する: ポートマッピングを
- '127.0.0.1:81:81'に変更します。設定画面を開く際は、ローカル端末からSSHトンネル(ssh -L 8181:localhost:81 user@IP_SERVER)を経由してhttp://localhost:8181へアクセスします。 - NPM自身へのProxy Hostを設定する: 内部用ドメイン(例:
npm.internal.yourdomain.com)を127.0.0.1:81に向けてプロキシ設定し、Access Listでアクセス可能IPを制限します。
安全なバックアップ手順
プロキシ設定およびSSL証明書は、すべて./dataと./letsencryptの2つのディレクトリ内に保持されています。データベース書き込み中のコピーによるSQLiteファイルの破損を防ぐため、アーカイブ作成前にコンテナを一時停止(pause)することをおすすめします:
cd ~/npm
docker compose pause
tar -czvf npm-backup-$(date +%F).tar.gz data/ letsencrypt/
docker compose unpause
コンテナの一時停止にかかる時間はわずか2秒程度であるため、実質的なダウンタイムを発生させることなく、確実で整合性のあるバックアップデータを取得できます。

