negiix 更换成 caddy
This commit is contained in:
+23
-8
@@ -3,10 +3,17 @@
|
||||
目标访问地址:
|
||||
|
||||
```text
|
||||
http://hfb.221329.cc.cd:7890
|
||||
https://hfb.221329.cc.cd
|
||||
```
|
||||
|
||||
生产部署只暴露宿主机 `7890` 端口,避免和服务器已有的 `80`、`443` 服务冲突。后端、MySQL、Redis、MinIO 均通过 Docker 内网通信。
|
||||
生产部署使用 Caddy 作为公网入口,只暴露宿主机 `80`、`443` 端口。Caddy 会自动申请和续签 HTTPS 证书,并直接托管前端静态资源(前端 `dist` 在构建 Caddy 镜像时打入);后端、MySQL、Redis、MinIO 均通过 Docker 内网通信。
|
||||
|
||||
部署前请确认:
|
||||
|
||||
- 域名 A 记录已解析到服务器公网 IP。
|
||||
- 服务器安全组或防火墙已放行 `80/tcp` 和 `443/tcp`。
|
||||
- 服务器上没有其他服务占用 `80`、`443`。
|
||||
- 国内服务器如需对外访问,请先确认域名备案和云厂商限制。
|
||||
|
||||
## 1. 准备环境变量
|
||||
|
||||
@@ -17,6 +24,8 @@ cp backend/.env.prod.example backend/.env
|
||||
编辑 `backend/.env`,至少替换以下占位值:
|
||||
|
||||
```text
|
||||
CADDY_DOMAIN
|
||||
CADDY_EMAIL
|
||||
MYSQL_ROOT_PASSWORD
|
||||
MYSQL_PASSWORD
|
||||
MYSQL_DSN
|
||||
@@ -39,9 +48,10 @@ STORAGE_SECRET_ACCESS_KEY
|
||||
|
||||
- 检查 `backend/.env` 是否仍指向 `127.0.0.1`、`localhost` 或占位值。
|
||||
- 构建并启动生产容器。
|
||||
- 通过 Caddy 自动申请或续签 HTTPS 证书。
|
||||
- 等待 MySQL、Redis、MinIO 就绪。
|
||||
- 按顺序执行尚未应用的数据库迁移。
|
||||
- 重启后端并检查 `http://127.0.0.1:7890/api/health`。
|
||||
- 重启后端并检查 `https://你的域名/api/health`。
|
||||
|
||||
如需部署完成后直接跟随查看后端日志:
|
||||
|
||||
@@ -64,9 +74,14 @@ backend/logs/app-YYYY-MM-DD.log
|
||||
## 3. 手动启动服务
|
||||
|
||||
```bash
|
||||
set -a
|
||||
source backend/.env
|
||||
set +a
|
||||
docker compose -f deploy/docker-compose.prod.yml up -d --build
|
||||
```
|
||||
|
||||
手动执行 `docker compose` 时需要先导出 `CADDY_DOMAIN` 和 `CADDY_EMAIL`,否则 Caddy 无法读取证书域名配置。优先推荐使用一键部署脚本,它会自动从 `backend/.env` 导出这两个变量。
|
||||
|
||||
## 4. 手动执行数据库迁移
|
||||
|
||||
通常直接使用一键部署脚本即可。确实需要手动迁移时,使用后端镜像内置的 goose:
|
||||
@@ -86,15 +101,15 @@ docker compose -f deploy/docker-compose.prod.yml run --rm --no-deps backend \
|
||||
## 5. 验证
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:7890/health
|
||||
curl http://127.0.0.1:7890/api/health
|
||||
curl https://你的域名/health
|
||||
curl https://你的域名/api/health
|
||||
```
|
||||
|
||||
浏览器访问:
|
||||
|
||||
```text
|
||||
http://hfb.221329.cc.cd:7890
|
||||
http://hfb.221329.cc.cd:7890/admin/login
|
||||
https://hfb.221329.cc.cd
|
||||
https://hfb.221329.cc.cd/admin/login
|
||||
```
|
||||
|
||||
服务器安全组或防火墙需要放行 `7890/tcp`。
|
||||
Caddy 证书和 ACME 账号数据保存在 Docker 卷 `caddy_data`、`caddy_config` 中。不要随意删除这两个卷,否则 Caddy 会重新申请证书,频繁重建可能触发证书签发频率限制。
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
email {$CADDY_EMAIL}
|
||||
}
|
||||
|
||||
# 反代到后端时,用 Caddy 实测到的对端地址覆盖 X-Real-IP,
|
||||
# 防止客户端伪造 X-Forwarded-For 影响限流、审计和支付下单的 client_ip。
|
||||
(backend_proxy) {
|
||||
header_up X-Real-IP {remote_host}
|
||||
}
|
||||
|
||||
{$CADDY_DOMAIN} {
|
||||
encode zstd gzip
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000"
|
||||
X-Content-Type-Options "nosniff"
|
||||
X-Frame-Options "DENY"
|
||||
Referrer-Policy "strict-origin-when-cross-origin"
|
||||
Permissions-Policy "camera=(), microphone=(), geolocation=()"
|
||||
}
|
||||
|
||||
# 聊天 SSE 长连接:关闭缓冲,逐条推送。
|
||||
@api_sse {
|
||||
path /api/chats/events /api/admin/chats/events
|
||||
}
|
||||
|
||||
handle @api_sse {
|
||||
reverse_proxy backend:8080 {
|
||||
flush_interval -1
|
||||
import backend_proxy
|
||||
}
|
||||
}
|
||||
|
||||
handle /api/* {
|
||||
# 后端上传上限 10MB,这里前置拦掉超大请求体(留 1MB 余量)。
|
||||
request_body {
|
||||
max_size 11MB
|
||||
}
|
||||
reverse_proxy backend:8080 {
|
||||
import backend_proxy
|
||||
}
|
||||
}
|
||||
|
||||
handle /health {
|
||||
reverse_proxy backend:8080 {
|
||||
import backend_proxy
|
||||
}
|
||||
}
|
||||
|
||||
# 其余流量返回前端静态资源,未命中的路径交给 SPA 处理。
|
||||
handle {
|
||||
root * /srv/dist
|
||||
try_files {path} /index.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
# 第一阶段:构建前端静态资源
|
||||
FROM node:24-alpine AS build
|
||||
|
||||
WORKDIR /src
|
||||
COPY frontend/package*.json ./
|
||||
RUN npm install
|
||||
COPY frontend/ .
|
||||
RUN npm run build
|
||||
|
||||
# 第二阶段:Caddy 作为公网入口,同时托管前端 dist
|
||||
FROM caddy:2.10-alpine
|
||||
|
||||
COPY --from=build /src/dist /srv/dist
|
||||
EXPOSE 80 443
|
||||
@@ -1,4 +1,31 @@
|
||||
services:
|
||||
caddy:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/caddy/Dockerfile
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
CADDY_DOMAIN: ${CADDY_DOMAIN:?请先导出 CADDY_DOMAIN,或使用 scripts/deploy-prod.sh 部署}
|
||||
CADDY_EMAIL: ${CADDY_EMAIL:?请先导出 CADDY_EMAIL,或使用 scripts/deploy-prod.sh 部署}
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
cpus: '0.5'
|
||||
reservations:
|
||||
memory: 128M
|
||||
cpus: '0.25'
|
||||
depends_on:
|
||||
- backend
|
||||
|
||||
mysql:
|
||||
image: mysql:8.4
|
||||
restart: unless-stopped
|
||||
@@ -95,25 +122,9 @@ services:
|
||||
expose:
|
||||
- "8080"
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: frontend/Dockerfile
|
||||
restart: unless-stopped
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
cpus: '0.5'
|
||||
reservations:
|
||||
memory: 128M
|
||||
cpus: '0.25'
|
||||
depends_on:
|
||||
- backend
|
||||
ports:
|
||||
- "7890:80"
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
minio_data:
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name hfb.221329.cc.cd;
|
||||
|
||||
client_max_body_size 20m;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://backend:8080/api/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
}
|
||||
|
||||
location /health {
|
||||
proxy_pass http://backend:8080/health;
|
||||
proxy_set_header Host $http_host;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user