VPSでWebアプリを本番公開するなら、Docker Composeで「nginx+certbot+アプリ」の3サービス構成が定番です。Let’s Encryptで無料のSSL証明書を取得し、自動更新まで設定。最大の難所は「鶏と卵問題」(証明書取得にHTTPが必要)ですが、初期化スクリプトを使えば手順通りで30分〜1時間で公開できます。
「ローカルでは動くアプリを、独自ドメイン+HTTPSで公開したい」——VPSとDockerを使えば、再現性が高く壊れにくい本番環境を自分で組めます。本記事ではインフラエンジニアの視点で、構成・手順・つまずきどころを最短ルートで解説します。
この記事で作る構成
作るのは、1台のVPS上にDockerで3つのコンテナを立てる構成です。Nginxがリバースプロキシとして全リクエストを受け、HTTPSを終端してアプリへ転送。certbotがSSL証明書を取得・更新します。
ポイントはNginxを「玄関」にすること。外部からの通信はすべてNginxが受け、内部のアプリ(8000番など)はexposeのみで外に晒しません。これでアプリのフレームワーク(FastAPI・Django・Node.jsなど)を問わず、同じ型で公開できます。
Step1:VPSの初期設定
まずはVPSにDockerを入れ、ファイアウォールで必要なポートだけを開けます。公開に使うのは22(SSH)・80(HTTP)・443(HTTPS)の3つです。
# ファイアウォールで必要なポートを開放
sudo ufw allow 22,80,443/tcp
sudo ufw enable
# Docker と Compose プラグインを導入
sudo apt update && sudo apt install -y docker.io docker-compose-plugin
sudo systemctl enable --now docker
続いてドメインのDNS Aレコードを、VPSのIPアドレスに向けておきます(反映はdig ドメイン名で確認)。本番公開にはVPSが1台必要なので、まだ用意していなければ初期費用0円で試せるConoHa VPSあたりが始めやすいです。
Step2:Docker Composeで3サービスを定義
nginx・certbot・appの3サービスを1つのdocker-compose.ymlにまとめます。証明書のボリュームをnginxとcertbotで共有するのがコツです。
services:
nginx:
image: nginx:alpine
ports: ["80:80", "443:443"]
volumes:
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
app:
build: .
expose: ["8000"]
certbotのentrypointは「12時間ごとに証明書の更新を試みる」ループです。Let’s Encryptの証明書は90日で期限切れになるため、この自動更新を入れておけば放置で運用できます。
Step3:SSL証明書を取得する(鶏と卵問題)
最大の難所がここです。HTTPSを有効にするには証明書が必要ですが、Let’s Encryptは証明書を発行する前にHTTPでドメイン所有を確認します。「証明書がないとNginxが起動しない、でも起動しないと証明書が取れない」という循環が起きます。
解決策は、初回だけダミー証明書でNginxを起動→本物の証明書を取得→差し替えという手順を踏む初期化スクリプト(init-letsencrypt.sh)を使うこと。多くの公開テンプレートが用意されているので、ドメイン名とメールアドレスを書き換えて実行すればOKです。
ACMEチャレンジの仕組み
Let’s Encryptは、指定パス(/.well-known/acme-challenge/)に置いたファイルにHTTPでアクセスして「このドメインを本当に管理しているか」を確認します(HTTP-01チャレンジ)。だからNginxは先に80番で起動している必要があるのです。
Step4:本番起動と動作確認
構成ができたら起動して確認します。ブラウザで鍵マークが表示され、HTTPでアクセスしてもHTTPSにリダイレクトされれば成功です。
# コンテナを起動
docker compose up -d
# 動作確認(HTTPS応答とリダイレクト)
curl -I https://あなたのドメイン
docker compose logs -f nginx
よくあるトラブルと対処
公開時のつまずきは原因がだいたい決まっています。証明書エラーの大半は、DNS未反映かポート未開放です。
| 症状 | 主な原因と対処 |
|---|---|
| 証明書取得に失敗 | DNS Aレコードが未反映、または80番が塞がっている。digで反映確認・UFWを確認 |
| 502 Bad Gateway | Nginxのproxy_passの向き先(アプリのコンテナ名・ポート)が誤り |
| 更新されず期限切れ | certbotコンテナが停止している。docker compose psで稼働を確認 |
本番公開まで自動化したいなら、コードのpushで自動デプロイするGitHub Actionsでの自動デプロイに発展させるのもおすすめです。
まとめ:型を覚えれば公開は怖くない
VPS+Docker+Nginx+Let’s Encryptの構成は、一度型を覚えればどんなWebアプリでも同じ手順で本番公開できます。鍵は「Nginxを玄関にする」「鶏と卵問題は初期化スクリプトで解く」「証明書は自動更新」の3点。VPS選びで迷うならVPS3社比較やXServer VPSの実測ベンチも参考にしてください。Docker自体をしっかり学びたいなら、ハンズオン講座が近道です。

コメント