部署默认端口改为 18080,支持与宿主机 Caddy 共存
避免与已有 80/443 服务冲突;补充端口检测、Caddyfile 示例与文档说明。
This commit is contained in:
@@ -109,16 +109,16 @@ kefu_cloud/ # 仓库目录名(本地可能仍为旧名,以
|
|||||||
|
|
||||||
## 生产部署(腾讯云 Docker)
|
## 生产部署(腾讯云 Docker)
|
||||||
|
|
||||||
单机一键部署(Nginx + API + PostgreSQL + MinIO):
|
单机一键部署(应用内 Nginx + API + PostgreSQL + MinIO)。默认宿主机端口 **18080**,便于与已有 **Caddy(80/443)** 共存:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 服务器安装 Docker 后
|
# 服务器安装 Docker 后
|
||||||
chmod +x deploy/scripts/*.sh
|
chmod +x deploy/scripts/*.sh
|
||||||
./deploy/scripts/deploy.sh # 首次会生成 deploy/.env.prod,请改公网地址
|
./deploy/scripts/deploy.sh # 首次会生成 deploy/.env.prod,请改域名与密钥
|
||||||
./deploy/scripts/deploy.sh --seed # 可选:导入演示账号
|
./deploy/scripts/deploy.sh --seed # 可选:导入演示账号
|
||||||
```
|
```
|
||||||
|
|
||||||
说明见 **[deploy/README.md](deploy/README.md)**(安全组、HTTPS、COS 替换 MinIO、备份升级)。
|
说明见 **[deploy/README.md](deploy/README.md)**(Caddy 共存、安全组、HTTPS、COS、备份升级)。Caddy 站点示例:`deploy/caddy/Caddyfile.example`。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,15 @@
|
|||||||
|
|
||||||
# ========== 访问入口(腾讯云 CVM 公网 IP 或域名)==========
|
# ========== 访问入口(腾讯云 CVM 公网 IP 或域名)==========
|
||||||
# 无域名示例:http://1.2.3.4
|
# 无域名示例:http://1.2.3.4
|
||||||
# 有域名 HTTPS(前置 CLB/CDN 或本机证书)示例:https://kefu.example.com
|
# 有域名 HTTPS(前置 Caddy / CLB / CDN)示例:https://kefu.example.com
|
||||||
|
# 注意:APP_BASE_URL 填浏览器实际访问地址(经 Caddy 时用 https 域名,不要写 :18080)
|
||||||
APP_BASE_URL=http://你的公网IP或域名
|
APP_BASE_URL=http://你的公网IP或域名
|
||||||
|
|
||||||
# Nginx 宿主机端口(默认 80;若 80 被占用可改为 8080)
|
# web(Nginx) 映射到宿主机的端口(容器内固定 80)
|
||||||
HTTP_PORT=80
|
# - 独占机器、无其它 80 服务:HTTP_PORT=80
|
||||||
|
# - 已有 Caddy/其它服务占用 80/443(常见):HTTP_PORT=18080,由 Caddy 反代到本端口
|
||||||
|
# 安全组不必对公网放行 18080,仅本机 Caddy 访问即可
|
||||||
|
HTTP_PORT=18080
|
||||||
|
|
||||||
# 浏览器访问图片前缀(一般 = APP_BASE_URL + /files)
|
# 浏览器访问图片前缀(一般 = APP_BASE_URL + /files)
|
||||||
STORAGE_PUBLIC_BASE_URL=http://你的公网IP或域名/files
|
STORAGE_PUBLIC_BASE_URL=http://你的公网IP或域名/files
|
||||||
|
|||||||
+86
-18
@@ -5,17 +5,29 @@
|
|||||||
## 架构
|
## 架构
|
||||||
|
|
||||||
```
|
```
|
||||||
Internet ──:80──▶ web(nginx)
|
Internet ──:80/443──▶ 边缘网关(Caddy 推荐 / 或 CLB)
|
||||||
├── / 前端 SPA
|
│
|
||||||
├── /api/* → api:8080(含 WebSocket)
|
▼
|
||||||
├── /health → api
|
web(nginx) :HTTP_PORT(默认 18080 → 容器 80)
|
||||||
└── /files/* → minio:9000/kefu(图片公共读)
|
├── / 前端 SPA
|
||||||
|
├── /api/* → api:8080(含 WebSocket)
|
||||||
|
├── /health → api
|
||||||
|
└── /files/* → minio:9000/kefu(图片公共读)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**两层分工(不要混为一谈):**
|
||||||
|
|
||||||
|
| 层级 | 组件 | 职责 |
|
||||||
|
|------|------|------|
|
||||||
|
| 边缘 | 宿主机 Caddy(或 CLB) | 占 80/443、多域名、自动 HTTPS |
|
||||||
|
| 应用内 | compose 里的 `web`(Nginx) | SPA + `/api` + `/files` 路径反代 |
|
||||||
|
|
||||||
|
若机器上已有 `caddy` 占用 80/443(例如旧站 `kefu_sys`),**不要**让本项目 `HTTP_PORT=80`,应改用 `18080` 并由 Caddy 反代。
|
||||||
|
|
||||||
## 服务器准备(腾讯云)
|
## 服务器准备(腾讯云)
|
||||||
|
|
||||||
1. 购买 **CVM / 轻量应用服务器**(建议 2 核 4G 起,系统 Ubuntu 22.04)
|
1. 购买 **CVM / 轻量应用服务器**(建议 2 核 4G 起,系统 Ubuntu 22.04)
|
||||||
2. **安全组**放行:`22`、`80`(有证书再放 `443`)
|
2. **安全组**放行:`22`、`80`(有证书再放 `443`)。应用内端口(如 `18080`)**不必**对公网开放
|
||||||
3. 安装 Docker:
|
3. 安装 Docker:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -33,6 +45,13 @@ git clone <你的仓库地址> kefu_cloud
|
|||||||
cd kefu_cloud
|
cd kefu_cloud
|
||||||
```
|
```
|
||||||
|
|
||||||
|
5. 部署前检查端口占用:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ss -tlnp | grep -E ':80|:443|:18080'
|
||||||
|
docker ps --format 'table {{.Names}}\t{{.Ports}}'
|
||||||
|
```
|
||||||
|
|
||||||
## 一键部署
|
## 一键部署
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -49,12 +68,12 @@ chmod +x deploy/scripts/*.sh
|
|||||||
|
|
||||||
| 变量 | 示例 | 说明 |
|
| 变量 | 示例 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| `APP_BASE_URL` | `http://1.2.3.4` 或 `https://kefu.xx.com` | 浏览器访问根地址 |
|
| `APP_BASE_URL` | `https://kefu.xx.com` | **浏览器**访问根地址(经 Caddy 时写 https 域名,不要写 `:18080`) |
|
||||||
| `STORAGE_PUBLIC_BASE_URL` | `http://1.2.3.4/files` | **必须**与 Nginx `/files` 一致 |
|
| `STORAGE_PUBLIC_BASE_URL` | `https://kefu.xx.com/files` | **必须**与应用内 Nginx `/files` 一致 |
|
||||||
| `HTTP_PORT` | `80` | 宿主机端口 |
|
| `HTTP_PORT` | `18080` | 宿主机映射端口;已有 Caddy 占 80 时用非 80 端口 |
|
||||||
| `DB_PASSWORD` / `JWT_SECRET` / `STORAGE_*` | 强随机 | 脚本可自动生成密钥 |
|
| `DB_PASSWORD` / `JWT_SECRET` / `STORAGE_*` | 强随机 | 脚本可自动生成密钥 |
|
||||||
|
|
||||||
脚本会校验占位符是否改掉。
|
脚本会校验占位符是否改掉,并在 `HTTP_PORT` 已被占用时告警/退出。
|
||||||
|
|
||||||
### 常用命令
|
### 常用命令
|
||||||
|
|
||||||
@@ -68,13 +87,59 @@ docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod logs -f ap
|
|||||||
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod logs -f web
|
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod logs -f web
|
||||||
```
|
```
|
||||||
|
|
||||||
## HTTPS 建议(腾讯云)
|
## 与现有 Caddy 共存(同机已有 kefu_sys 等)
|
||||||
|
|
||||||
任选其一:
|
典型现状:
|
||||||
|
|
||||||
1. **CLB / CDN** 终结 HTTPS,回源 CVM `80`(最简单)
|
```text
|
||||||
2. 本机 **Caddy / Nginx + Let’s Encrypt** 反代到本 compose 的 `80`
|
caddy 0.0.0.0:80→80, 0.0.0.0:443→443
|
||||||
3. 把 `web` 容器映射改到 `8080`,宿主机 Nginx 做 443 → 8080
|
kefu_sys 仅容器内 8080(由 Caddy 反代)
|
||||||
|
```
|
||||||
|
|
||||||
|
推荐拓扑:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Internet
|
||||||
|
└── Caddy :80/:443
|
||||||
|
├── 旧域名 → kefu_sys
|
||||||
|
└── 新域名 → 127.0.0.1:18080 → kefu-cloud-web(Nginx)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤
|
||||||
|
|
||||||
|
1. `.env.prod` 设置(示例):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
HTTP_PORT=18080
|
||||||
|
APP_BASE_URL=https://kefu.example.com
|
||||||
|
STORAGE_PUBLIC_BASE_URL=https://kefu.example.com/files
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 部署本项目:`./deploy/scripts/deploy.sh`(先确认本机 `curl http://127.0.0.1:18080/healthz` 返回 ok)
|
||||||
|
|
||||||
|
3. 将 `deploy/caddy/Caddyfile.example` 中的站点段合并进现有 Caddy 配置,把域名改成真实域名后 reload:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 示例(按你实际 Caddy 部署方式调整)
|
||||||
|
# docker exec caddy caddy validate --config /etc/caddy/Caddyfile
|
||||||
|
# docker exec caddy caddy reload --config /etc/caddy/Caddyfile
|
||||||
|
```
|
||||||
|
|
||||||
|
4. 浏览器访问 `https://kefu.example.com`,登录页 `/login`,健康检查 `/health`。
|
||||||
|
|
||||||
|
### 为何边缘用 Caddy、应用内仍用 Nginx
|
||||||
|
|
||||||
|
- **Caddy**:你已在用、自动 HTTPS、多站点配置简单,继续当 80/443 入口。
|
||||||
|
- **Nginx(web 容器)**:SPA、`/api` WebSocket、`/files`→MinIO 已写好,无需换成 Caddy。
|
||||||
|
- **不要**再在宿主机起一个 Nginx 抢 80/443,也**不要**让本 compose 默认绑 80。
|
||||||
|
|
||||||
|
## HTTPS 其它方式
|
||||||
|
|
||||||
|
任选其一(与上一节「Caddy 共存」二选一即可):
|
||||||
|
|
||||||
|
1. **CLB / CDN** 终结 HTTPS,回源 CVM `HTTP_PORT`(或仍回源 Caddy)
|
||||||
|
2. 本机 **Caddy** 反代到 `127.0.0.1:${HTTP_PORT}`(推荐,见上)
|
||||||
|
3. 独占机器时 `HTTP_PORT=80`,另用 Nginx + Let’s Encrypt 做 443
|
||||||
|
|
||||||
配置 HTTPS 后,请同步把 `APP_BASE_URL`、`STORAGE_PUBLIC_BASE_URL` 改成 `https://…`。
|
配置 HTTPS 后,请同步把 `APP_BASE_URL`、`STORAGE_PUBLIC_BASE_URL` 改成 `https://…`。
|
||||||
|
|
||||||
@@ -104,6 +169,7 @@ docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod logs -f we
|
|||||||
| `deploy/docker/Dockerfile.api` | Go API 镜像 |
|
| `deploy/docker/Dockerfile.api` | Go API 镜像 |
|
||||||
| `deploy/docker/Dockerfile.web` | 前端构建 + Nginx |
|
| `deploy/docker/Dockerfile.web` | 前端构建 + Nginx |
|
||||||
| `deploy/docker/nginx.conf` | 反代与 SPA |
|
| `deploy/docker/nginx.conf` | 反代与 SPA |
|
||||||
|
| `deploy/caddy/Caddyfile.example` | 边缘 Caddy 站点示例(与 80 共存) |
|
||||||
| `deploy/.env.prod.example` | 环境变量模板 |
|
| `deploy/.env.prod.example` | 环境变量模板 |
|
||||||
| `deploy/scripts/deploy.sh` | 一键部署 |
|
| `deploy/scripts/deploy.sh` | 一键部署 |
|
||||||
| `deploy/scripts/backup-db.sh` | 数据库备份 |
|
| `deploy/scripts/backup-db.sh` | 数据库备份 |
|
||||||
@@ -112,15 +178,17 @@ docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod logs -f we
|
|||||||
|
|
||||||
| 现象 | 处理 |
|
| 现象 | 处理 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 页面 502 | `docker compose … logs api`,检查 DB 是否 healthy |
|
| 端口被占用 / bind 失败 | `ss -tlnp` 查占用;改 `HTTP_PORT` 或停冲突容器 |
|
||||||
|
| 页面 502 | `docker compose … logs api`,检查 DB 是否 healthy;Caddy 是否指到正确端口 |
|
||||||
| 图片打不开 | 检查 `STORAGE_PUBLIC_BASE_URL` 是否为 `…/files`,MinIO 桶是否 public download |
|
| 图片打不开 | 检查 `STORAGE_PUBLIC_BASE_URL` 是否为 `…/files`,MinIO 桶是否 public download |
|
||||||
| WebSocket 断 | 确认走同源 `/api/ws`,CLB 需开启 WebSocket/长连接 |
|
| WebSocket 断 | 确认走同源 `/api/ws`;Caddy 用示例中的 `flush_interval`;CLB 需开启 WebSocket |
|
||||||
| 构建 Go 失败 | 服务器内存不足时加 swap,或本机 build 后 `docker save` 上传 |
|
| 构建 Go 失败 | 服务器内存不足时加 swap,或本机 build 后 `docker save` 上传 |
|
||||||
|
| 只能本机 18080 访问、域名不通 | Caddy 未 reload / 域名 DNS 未指向本机 / 安全组未放 80/443 |
|
||||||
|
|
||||||
## 升级
|
## 升级
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git pull
|
git pull
|
||||||
./deploy/scripts/deploy.sh # 重新 build 并滚动启动
|
|
||||||
./deploy/scripts/backup-db.sh # 升级前建议备份
|
./deploy/scripts/backup-db.sh # 升级前建议备份
|
||||||
|
./deploy/scripts/deploy.sh # 重新 build 并滚动启动
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# 与现有 Caddy 共存:把本段并入宿主机 Caddy 配置后 reload
|
||||||
|
# 前提:kefu_cloud 已部署,deploy/.env.prod 中 HTTP_PORT=18080(或你改的其它端口)
|
||||||
|
#
|
||||||
|
# 拓扑:
|
||||||
|
# Internet → Caddy :80/:443 → 127.0.0.1:18080 → kefu-cloud-web(Nginx)
|
||||||
|
# 旧站(如 kefu_sys)保持原有 site 块不变
|
||||||
|
|
||||||
|
# ---------- 方式 A:独立域名(推荐)----------
|
||||||
|
kefu.example.com {
|
||||||
|
# 自动 HTTPS(Let's Encrypt);内网调试可改用 :80 + reverse_proxy
|
||||||
|
encode gzip
|
||||||
|
reverse_proxy 127.0.0.1:18080 {
|
||||||
|
# WebSocket(/api/ws、/api/widget/ws)与长连接
|
||||||
|
flush_interval -1
|
||||||
|
transport http {
|
||||||
|
read_timeout 3600s
|
||||||
|
write_timeout 3600s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------- 方式 B:与旧站同机、仅 HTTP 调试(无证书)----------
|
||||||
|
# :18081 {
|
||||||
|
# reverse_proxy 127.0.0.1:18080
|
||||||
|
# }
|
||||||
|
|
||||||
|
# ---------- 方式 C:路径分流同一域名(少用,路径易与旧站冲突)----------
|
||||||
|
# example.com {
|
||||||
|
# handle_path /cloud/* {
|
||||||
|
# reverse_proxy 127.0.0.1:18080
|
||||||
|
# }
|
||||||
|
# handle {
|
||||||
|
# reverse_proxy kefu_sys:8080
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# 应用配置后:
|
||||||
|
# caddy validate --config /path/to/Caddyfile
|
||||||
|
# caddy reload --config /path/to/Caddyfile
|
||||||
|
# 或 docker:docker exec caddy caddy reload --config /etc/caddy/Caddyfile
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# 客服云 — 腾讯云 / 任意 Linux 一键生产部署
|
# 客服云 — 腾讯云 / 任意 Linux 一键生产部署
|
||||||
|
# 默认 HTTP_PORT=18080,避免与宿主机 Caddy(80/443) 冲突;见 deploy/caddy/Caddyfile.example
|
||||||
# 用法:
|
# 用法:
|
||||||
# ./deploy/scripts/deploy.sh # 构建并启动
|
# ./deploy/scripts/deploy.sh # 构建并启动
|
||||||
# ./deploy/scripts/deploy.sh --seed # 启动后导入演示账号数据
|
# ./deploy/scripts/deploy.sh --seed # 启动后导入演示账号数据
|
||||||
@@ -44,6 +45,58 @@ rand_hex() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 检测宿主机 TCP 端口是否已被占用(非本 compose 的 web 容器)
|
||||||
|
port_in_use() {
|
||||||
|
local port="$1"
|
||||||
|
if command -v ss >/dev/null 2>&1; then
|
||||||
|
ss -tlnH "sport = :${port}" 2>/dev/null | grep -q .
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
if command -v lsof >/dev/null 2>&1; then
|
||||||
|
lsof -iTCP:"${port}" -sTCP:LISTEN -n -P >/dev/null 2>&1
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
# 无 ss/lsof 时用 bash /dev/tcp 探测(仅作弱检测)
|
||||||
|
(echo >/dev/tcp/127.0.0.1/"${port}") >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 端口是否由本项目的 web 容器占用(升级/重部署时允许)
|
||||||
|
port_held_by_our_web() {
|
||||||
|
local port="$1"
|
||||||
|
docker ps --format '{{.Names}} {{.Ports}}' 2>/dev/null \
|
||||||
|
| grep -E 'kefu-cloud-web' \
|
||||||
|
| grep -qE "0\\.0\\.0\\.0:${port}->|:::${port}->"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_http_port() {
|
||||||
|
local port="${HTTP_PORT:-18080}"
|
||||||
|
if ! [[ "$port" =~ ^[0-9]+$ ]] || [[ "$port" -lt 1 || "$port" -gt 65535 ]]; then
|
||||||
|
err "HTTP_PORT 无效: ${port}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$port" == "80" ]] || [[ "$port" == "443" ]]; then
|
||||||
|
if port_in_use "$port" && ! port_held_by_our_web "$port"; then
|
||||||
|
err "HTTP_PORT=${port} 已被占用(常见:宿主机 Caddy/Nginx)"
|
||||||
|
err "请将 $ENV_FILE 中 HTTP_PORT 改为 18080,并由 Caddy 反代到该端口"
|
||||||
|
err "参考: deploy/caddy/Caddyfile.example 与 deploy/README.md「与现有 Caddy 共存」"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif port_in_use "$port" && ! port_held_by_our_web "$port"; then
|
||||||
|
err "HTTP_PORT=${port} 已被其它进程占用,请改 $ENV_FILE 中的 HTTP_PORT"
|
||||||
|
if command -v ss >/dev/null 2>&1; then
|
||||||
|
ss -tlnp 2>/dev/null | grep -E ":${port}\\s" || true
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 80/443 被占用但用户选了 18080 时给提示
|
||||||
|
if [[ "$port" != "80" ]] && port_in_use 80; then
|
||||||
|
log "检测到宿主机 :80 已被占用(多为 Caddy),将使用 HTTP_PORT=${port}"
|
||||||
|
log "部署后请把 Caddy 反代到 127.0.0.1:${port}(见 deploy/caddy/Caddyfile.example)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
ensure_env() {
|
ensure_env() {
|
||||||
if [[ ! -f "$ENV_FILE" ]]; then
|
if [[ ! -f "$ENV_FILE" ]]; then
|
||||||
if [[ ! -f "$ENV_EXAMPLE" ]]; then
|
if [[ ! -f "$ENV_EXAMPLE" ]]; then
|
||||||
@@ -71,8 +124,9 @@ ensure_env() {
|
|||||||
|
|
||||||
warn "已生成随机 JWT_SECRET / DB_PASSWORD / STORAGE_SECRET_KEY"
|
warn "已生成随机 JWT_SECRET / DB_PASSWORD / STORAGE_SECRET_KEY"
|
||||||
warn "请编辑 $ENV_FILE,至少设置:"
|
warn "请编辑 $ENV_FILE,至少设置:"
|
||||||
warn " APP_BASE_URL=http://你的公网IP或域名"
|
warn " APP_BASE_URL=https://你的域名 # 经 Caddy 时用 https 域名,勿写 :18080"
|
||||||
warn " STORAGE_PUBLIC_BASE_URL=http://你的公网IP或域名/files"
|
warn " STORAGE_PUBLIC_BASE_URL=https://你的域名/files"
|
||||||
|
warn " HTTP_PORT=18080 # 已有 Caddy 占 80 时保持默认;独占机可改 80"
|
||||||
echo
|
echo
|
||||||
read -r -p "设置完成后按回车继续(或 Ctrl+C 退出先改配置): " _
|
read -r -p "设置完成后按回车继续(或 Ctrl+C 退出先改配置): " _
|
||||||
fi
|
fi
|
||||||
@@ -83,6 +137,9 @@ ensure_env() {
|
|||||||
source <(sed 's/\r$//' "$ENV_FILE" | grep -v '^\s*#' | grep -v '^\s*$' || true)
|
source <(sed 's/\r$//' "$ENV_FILE" | grep -v '^\s*#' | grep -v '^\s*$' || true)
|
||||||
set +a
|
set +a
|
||||||
|
|
||||||
|
# 未显式设置时与 compose 默认一致
|
||||||
|
HTTP_PORT="${HTTP_PORT:-18080}"
|
||||||
|
|
||||||
if [[ -z "${JWT_SECRET:-}" || "${JWT_SECRET}" == *"请改"* ]]; then
|
if [[ -z "${JWT_SECRET:-}" || "${JWT_SECRET}" == *"请改"* ]]; then
|
||||||
err "请在 $ENV_FILE 中设置有效的 JWT_SECRET"
|
err "请在 $ENV_FILE 中设置有效的 JWT_SECRET"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -92,7 +149,7 @@ ensure_env() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [[ -z "${STORAGE_PUBLIC_BASE_URL:-}" || "${STORAGE_PUBLIC_BASE_URL}" == *"你的"* ]]; then
|
if [[ -z "${STORAGE_PUBLIC_BASE_URL:-}" || "${STORAGE_PUBLIC_BASE_URL}" == *"你的"* ]]; then
|
||||||
err "请在 $ENV_FILE 中设置 STORAGE_PUBLIC_BASE_URL(如 http://1.2.3.4/files)"
|
err "请在 $ENV_FILE 中设置 STORAGE_PUBLIC_BASE_URL(如 https://域名/files)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [[ -z "${STORAGE_ACCESS_KEY:-}" || -z "${STORAGE_SECRET_KEY:-}" ]]; then
|
if [[ -z "${STORAGE_ACCESS_KEY:-}" || -z "${STORAGE_SECRET_KEY:-}" ]]; then
|
||||||
@@ -103,10 +160,12 @@ ensure_env() {
|
|||||||
err "STORAGE_SECRET_KEY 长度至少 8 位(MinIO 要求)"
|
err "STORAGE_SECRET_KEY 长度至少 8 位(MinIO 要求)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
check_http_port
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_healthy() {
|
wait_healthy() {
|
||||||
local url="${1:-http://127.0.0.1:${HTTP_PORT:-80}/health}"
|
local url="${1:-http://127.0.0.1:${HTTP_PORT:-18080}/health}"
|
||||||
local i
|
local i
|
||||||
log "等待服务就绪: $url"
|
log "等待服务就绪: $url"
|
||||||
for i in $(seq 1 60); do
|
for i in $(seq 1 60); do
|
||||||
@@ -121,7 +180,8 @@ wait_healthy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_summary() {
|
print_summary() {
|
||||||
local base="${APP_BASE_URL:-http://127.0.0.1:${HTTP_PORT:-80}}"
|
local port="${HTTP_PORT:-18080}"
|
||||||
|
local base="${APP_BASE_URL:-http://127.0.0.1:${port}}"
|
||||||
echo
|
echo
|
||||||
log "========== 部署完成 =========="
|
log "========== 部署完成 =========="
|
||||||
echo " 访问地址: ${base}"
|
echo " 访问地址: ${base}"
|
||||||
@@ -129,14 +189,22 @@ print_summary() {
|
|||||||
echo " 健康检查: ${base}/health"
|
echo " 健康检查: ${base}/health"
|
||||||
echo " Widget 预览: ${base}/widget/preview"
|
echo " Widget 预览: ${base}/widget/preview"
|
||||||
echo " 图片前缀: ${STORAGE_PUBLIC_BASE_URL}"
|
echo " 图片前缀: ${STORAGE_PUBLIC_BASE_URL}"
|
||||||
|
echo " 本机探测: http://127.0.0.1:${port}/healthz (web 容器映射端口)"
|
||||||
echo
|
echo
|
||||||
|
if [[ "$port" != "80" && "$port" != "443" ]]; then
|
||||||
|
echo " Caddy 共存:"
|
||||||
|
echo " 1) 确认本机: curl -fsS http://127.0.0.1:${port}/healthz"
|
||||||
|
echo " 2) 合并 deploy/caddy/Caddyfile.example 到现有 Caddy,反代 127.0.0.1:${port}"
|
||||||
|
echo " 3) APP_BASE_URL / STORAGE_PUBLIC_BASE_URL 使用 https 域名(不要写 :${port})"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
echo " 常用命令:"
|
echo " 常用命令:"
|
||||||
echo " 查看状态 ./deploy/scripts/deploy.sh --status"
|
echo " 查看状态 ./deploy/scripts/deploy.sh --status"
|
||||||
echo " 查看日志 docker compose -f $COMPOSE_FILE --env-file $ENV_FILE logs -f"
|
echo " 查看日志 docker compose -f $COMPOSE_FILE --env-file $ENV_FILE logs -f"
|
||||||
echo " 导入种子 ./deploy/scripts/deploy.sh --seed-only"
|
echo " 导入种子 ./deploy/scripts/deploy.sh --seed-only"
|
||||||
echo " 停止服务 ./deploy/scripts/deploy.sh --down"
|
echo " 停止服务 ./deploy/scripts/deploy.sh --down"
|
||||||
echo
|
echo
|
||||||
echo " 安全提示: 安全组仅放行 80/443;改默认密码;生产务必使用 HTTPS。"
|
echo " 安全提示: 安全组仅放行 22/80/443(不必公网放行 ${port});改默认密码;生产用 HTTPS。"
|
||||||
echo "=============================="
|
echo "=============================="
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,8 +239,8 @@ cmd_up() {
|
|||||||
compose up -d --remove-orphans
|
compose up -d --remove-orphans
|
||||||
fi
|
fi
|
||||||
|
|
||||||
wait_healthy "http://127.0.0.1:${HTTP_PORT:-80}/health" || true
|
wait_healthy "http://127.0.0.1:${HTTP_PORT:-18080}/health" || true
|
||||||
wait_healthy "http://127.0.0.1:${HTTP_PORT:-80}/healthz" || true
|
wait_healthy "http://127.0.0.1:${HTTP_PORT:-18080}/healthz" || true
|
||||||
|
|
||||||
if [[ "$seed" -eq 1 ]]; then
|
if [[ "$seed" -eq 1 ]]; then
|
||||||
log "导入演示种子数据…"
|
log "导入演示种子数据…"
|
||||||
@@ -204,7 +272,7 @@ cmd_status() {
|
|||||||
if [[ -f "$ENV_FILE" ]]; then
|
if [[ -f "$ENV_FILE" ]]; then
|
||||||
compose ps
|
compose ps
|
||||||
echo
|
echo
|
||||||
curl -fsS "http://127.0.0.1:${HTTP_PORT:-80}/health" && echo || warn "health 不可达"
|
curl -fsS "http://127.0.0.1:${HTTP_PORT:-18080}/health" && echo || warn "health 不可达"
|
||||||
else
|
else
|
||||||
err "缺少 $ENV_FILE"
|
err "缺少 $ENV_FILE"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -115,8 +115,10 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
minio:
|
minio:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
|
# 默认 18080:避免与宿主机已有 Caddy/其它服务抢 80
|
||||||
|
# 独占机器可在 .env.prod 设 HTTP_PORT=80;有 Caddy 时保持 18080 并由其反代
|
||||||
ports:
|
ports:
|
||||||
- "${HTTP_PORT:-80}:80"
|
- "${HTTP_PORT:-18080}:80"
|
||||||
networks:
|
networks:
|
||||||
- kefu_cloud_net
|
- kefu_cloud_net
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user