diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..90542d1 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,3 @@ +colcaroli-playchat.duckdns.org { + reverse_proxy frontend:80 +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index d976a23..7d3ae3a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,9 +20,24 @@ services: restart: unless-stopped depends_on: - backend + expose: + - "80" + + caddy: + image: caddy:latest + restart: unless-stopped ports: - "80:80" + - "443:443" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + - caddy_data:/data + - caddy_config:/config + depends_on: + - frontend volumes: backend_data: backend_knowledge_base: + caddy_data: + caddy_config: diff --git a/docs/deploy-lightsail.md b/docs/deploy-lightsail.md index 9f8c128..5fae3ca 100644 --- a/docs/deploy-lightsail.md +++ b/docs/deploy-lightsail.md @@ -10,6 +10,9 @@ Lightsail Containers(マネージドコンテナサービス)よりも、状 Internet │ :80 / :443 ▼ +[caddy コンテナ] Let's Encrypt証明書の自動取得・更新、HTTP→HTTPSリダイレクト + │ :80(コンテナ間通信のみ、ホストには公開しない) + ▼ [frontend コンテナ] nginx ├─ 静的ファイル (Vue ビルド成果物) を配信 └─ /chat, /api, /memory, /logs, /health を backend にリバースプロキシ @@ -26,7 +29,7 @@ Internet - [backend/Dockerfile](../backend/Dockerfile) - [frontend/Dockerfile](../frontend/Dockerfile) / [frontend/nginx.conf](../frontend/nginx.conf) -- [docker-compose.yml](../docker-compose.yml) +- [docker-compose.yml](../docker-compose.yml) / [Caddyfile](../Caddyfile) ## 1. Lightsail インスタンスの作成 @@ -39,7 +42,7 @@ Internet 作成後、インスタンス詳細ページの「ネットワーキング」タブで: - **静的 IP をアタッチ**(再起動してもIPが変わらないようにする。ドメインを使う場合は必須) -- ファイアウォールで **80 (HTTP)** と、HTTPS を使うなら **443** を許可(22/SSH はデフォルトで開いている) +- ファイアウォールで **80 (HTTP)** と **443 (HTTPS)** を許可(Caddyの証明書取得とHTTPS配信に両方必要。22/SSH はデフォルトで開いている) ## 2. SSH 接続 & Docker のインストール @@ -117,7 +120,7 @@ nano backend/.env # APIキーやモデル名など本番用の値を設定 SQLite(`AppSetting`テーブル、`backend_data`ボリュームで永続化)に保存され、`.env`の値より優先される。 **注意:** このパスワード保護は簡易的なものであり、HTTP平文通信の場合はBasic認証の資格情報がネットワーク上に -そのまま流れてしまう。この機能を使うなら[6. HTTPS化](#6-https-化ドメインがある場合)と合わせて運用すること。 +そのまま流れてしまう。この機能を使うなら[6. HTTPS化](#6-https-化caddy)と合わせて運用すること。 ## 4. ビルド & 起動 @@ -127,7 +130,9 @@ docker compose up -d docker compose logs -f backend # 起動ログ確認(Ctrl+C で抜ける。プロセスは動き続ける) ``` -ブラウザで `http://<静的IP>/` にアクセスして動作確認する。 +`docker-compose.yml`にはCaddyが含まれており、80/443番ポートはCaddyが受け持つ(`frontend`は直接公開しない)。 +Caddyfileにはドメイン名を設定する前提のため、動作確認は静的IPへの直接アクセスではなく +[6. HTTPS化](#6-https-化caddy)の手順でドメイン経由で行うこと。 停止・再起動・更新の運用コマンド: @@ -153,21 +158,49 @@ docker cp $(docker compose ps -q backend):/app/data/backup.db ./playchat-backup- インスタンスごとのバックアップとしては、Lightsail の「スナップショット」機能(自動スナップショット設定可)も併用すると安心。 -## 6. HTTPS 化(ドメインがある場合) +## 6. HTTPS 化(Caddy) -ドメインの A レコードを Lightsail の静的 IP に向けた上で、ホスト側で certbot を使い証明書を取得し、 -`frontend` コンテナへ読み取り専用でマウントする。 +[Caddy](https://caddyserver.com/) をリバースプロキシとして`frontend`の手前に置き、証明書の取得・更新を +自動化する(Let's Encrypt、ACME HTTP-01 チャレンジ)。手動でのcertbot操作は不要。 -```bash -sudo apt install -y certbot -docker compose stop frontend # 80番ポートを一時的に空ける -sudo certbot certonly --standalone -d your-domain.example.com -docker compose start frontend +構成: + +``` +Internet + │ :80 / :443 + ▼ +[caddy コンテナ] ← Let's Encrypt証明書の自動取得・更新、HTTP→HTTPSリダイレクト + │ :80 (コンテナ間通信、ホストには公開しない) + ▼ +[frontend コンテナ] nginx(静的配信 + backendへのAPIプロキシ) + ▼ +[backend コンテナ] ``` -`frontend/nginx.conf` に 443 用のサーバーブロックを追記し、`docker-compose.yml` の `frontend` サービスに -`443:443` のポートマッピングと `/etc/letsencrypt` のボリュームマウントを追加する(証明書更新時は `docker compose restart frontend` が必要。 -`certbot renew` の `--deploy-hook` に登録しておくと自動化できる)。この構成に変更したい場合は改めて対応する。 +`frontend`はもう80番ポートをホストに公開せず(`expose`のみ)、代わりに`caddy`が80/443を受けて +`frontend`へ内部転送する。ルートの [Caddyfile](../Caddyfile) にドメインを設定する: + +``` +your-domain.example.com { + reverse_proxy frontend:80 +} +``` + +前提条件: + +- ドメインの A レコード(IPv4)を Lightsail の静的 IP に向けておく(DuckDNS等の無料動的DNSでも可) +- Lightsail ファイアウォールで **443 (HTTPS)** を許可([1. Lightsail インスタンスの作成](#1-lightsail-インスタンスの作成)で追加済みのはず) + +起動すると、Caddyがドメイン名を見て自動的にACMEチャレンジ(ポート80経由)で証明書を取得し、 +以後は自動更新される。証明書は`caddy_data`ボリュームに永続化されるので、`docker compose down` +(`-v`無し)では消えない。 + +```bash +docker compose up -d +docker compose logs -f caddy # 証明書取得ログを確認("certificate obtained successfully" 等) +``` + +`https://your-domain.example.com/` にアクセスして確認する。 ## 7. 常駐タスクについて