优化 Docker 开发启动流程
This commit is contained in:
@@ -4,8 +4,13 @@ DATA_ENCRYPTION_KEY=your_32_plus_char_data_encryption_key_change_me
|
|||||||
POSTGRES_USER=affiliate
|
POSTGRES_USER=affiliate
|
||||||
POSTGRES_PASSWORD=affiliate_dev_password
|
POSTGRES_PASSWORD=affiliate_dev_password
|
||||||
POSTGRES_DB=affiliate_dash
|
POSTGRES_DB=affiliate_dash
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
COMPOSE_PROJECT_NAME=affiliate_dash
|
||||||
|
POSTGRES_DATA_VOLUME=affiliate_dash_postgres_data
|
||||||
TZ=Asia/Shanghai
|
TZ=Asia/Shanghai
|
||||||
DATABASE_URL="postgres://affiliate:affiliate_dev_password@127.0.0.1:5432/affiliate_dash?sslmode=disable&TimeZone=Asia/Shanghai"
|
DATABASE_URL="postgres://affiliate:affiliate_dev_password@127.0.0.1:5432/affiliate_dash?sslmode=disable&TimeZone=Asia/Shanghai"
|
||||||
|
# Docker 后端容器内连接串通常不需要改;需要外部数据库时再覆盖。
|
||||||
|
# DOCKER_DATABASE_URL="postgres://affiliate:affiliate_dev_password@postgres:5432/affiliate_dash?sslmode=disable&TimeZone=Asia/Shanghai"
|
||||||
GIN_MODE=release
|
GIN_MODE=release
|
||||||
OPEN_API_KEY=sk_source_dev_key_change_me
|
OPEN_API_KEY=sk_source_dev_key_change_me
|
||||||
OPEN_API_SECRET=sk_source_dev_secret_change_me
|
OPEN_API_SECRET=sk_source_dev_secret_change_me
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# admin off
|
# admin off
|
||||||
}
|
}
|
||||||
|
|
||||||
skin.khhao.com {
|
(app_routes) {
|
||||||
encode gzip zstd
|
encode gzip zstd
|
||||||
|
|
||||||
# /api-debug 是前端 SPA 路由,不要代理到后端
|
# /api-debug 是前端 SPA 路由,不要代理到后端
|
||||||
@@ -25,3 +25,11 @@ skin.khhao.com {
|
|||||||
file_server
|
file_server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:80 {
|
||||||
|
import app_routes
|
||||||
|
}
|
||||||
|
|
||||||
|
skin.khhao.com {
|
||||||
|
import app_routes
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
- Go 1.26+
|
- Go 1.26+
|
||||||
- Node.js 22+
|
- Node.js 22+
|
||||||
- Docker(用于自动启动 PostgreSQL 开发容器)
|
- Docker / Docker Compose(用于自动启动 PostgreSQL 开发服务)
|
||||||
|
|
||||||
### 快速启动
|
### 快速启动
|
||||||
|
|
||||||
@@ -33,6 +33,8 @@ make dev
|
|||||||
./start.sh
|
./start.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`make dev` 会通过 Docker Compose 启动 `affiliate_dash/postgres`,后端和前端仍在宿主机运行,方便热更新。首次从旧版 `affiliate_dash_postgres_dev` 开发容器迁移时,脚本会停止旧容器并优先复用旧数据卷。
|
||||||
|
|
||||||
启动后:
|
启动后:
|
||||||
- 前端:`http://localhost:5173`
|
- 前端:`http://localhost:5173`
|
||||||
- 后端:`http://localhost:8080`
|
- 后端:`http://localhost:8080`
|
||||||
@@ -61,10 +63,11 @@ cp .env.example .env
|
|||||||
# JWT_SECRET — 生产环境务必修改
|
# JWT_SECRET — 生产环境务必修改
|
||||||
# OPEN_API_KEY — 皮肤源头对接 API Key
|
# OPEN_API_KEY — 皮肤源头对接 API Key
|
||||||
# OPEN_API_SECRET — 签名密钥
|
# OPEN_API_SECRET — 签名密钥
|
||||||
# DATABASE_URL — PostgreSQL 连接,容器内主机名为 postgres
|
# POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB — PostgreSQL 初始化配置
|
||||||
```
|
```
|
||||||
|
|
||||||
> 国内服务器可在 `.env` 中取消 `GOPROXY`、`ALPINE_MIRROR`、`NPM_REGISTRY` 等镜像加速源的注释。
|
> 国内服务器可在 `.env` 中取消 `GOPROXY`、`ALPINE_MIRROR`、`NPM_REGISTRY` 等镜像加速源的注释。
|
||||||
|
> Docker 后端容器默认使用 `postgres` 作为数据库主机;只有连接外部数据库时才需要设置 `DOCKER_DATABASE_URL`。
|
||||||
|
|
||||||
### 启动服务
|
### 启动服务
|
||||||
|
|
||||||
@@ -78,6 +81,7 @@ docker compose up -d --build
|
|||||||
服务端口:
|
服务端口:
|
||||||
- `:80` — 前端页面 + API(Caddy 统一入口)
|
- `:80` — 前端页面 + API(Caddy 统一入口)
|
||||||
- `:8080` — 后端 API(直接访问,调试用)
|
- `:8080` — 后端 API(直接访问,调试用)
|
||||||
|
- `:5432` — PostgreSQL(本地开发/调试用,可通过 `POSTGRES_PORT` 调整)
|
||||||
|
|
||||||
### 常用命令
|
### 常用命令
|
||||||
|
|
||||||
@@ -89,7 +93,7 @@ make docker-down # 停止并移除
|
|||||||
|
|
||||||
### 自定义域名
|
### 自定义域名
|
||||||
|
|
||||||
修改 `Caddyfile` 中的域名 `skin.khhao.com` 为你的域名,重新构建即可。
|
`Caddyfile` 默认同时支持本地 `:80` 和示例域名 `skin.khhao.com`。生产部署时把 `skin.khhao.com` 改为你的域名,重新构建即可。
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
@@ -98,6 +102,10 @@ make docker-down # 停止并移除
|
|||||||
| `PORT` | 后端端口 | `8080` |
|
| `PORT` | 后端端口 | `8080` |
|
||||||
| `JWT_SECRET` | JWT 签名密钥 | 开发默认值 |
|
| `JWT_SECRET` | JWT 签名密钥 | 开发默认值 |
|
||||||
| `DATABASE_URL` | PostgreSQL 连接串 | 本地开发默认值 |
|
| `DATABASE_URL` | PostgreSQL 连接串 | 本地开发默认值 |
|
||||||
|
| `DOCKER_DATABASE_URL` | Docker 后端容器内 PostgreSQL 连接串,通常无需设置 | Compose 内置默认值 |
|
||||||
|
| `POSTGRES_PORT` | PostgreSQL 映射到宿主机的端口 | `5432` |
|
||||||
|
| `COMPOSE_PROJECT_NAME` | Docker Compose 项目名 | `affiliate_dash` |
|
||||||
|
| `POSTGRES_DATA_VOLUME` | PostgreSQL 数据卷名 | `affiliate_dash_postgres_data` |
|
||||||
| `GIN_MODE` | Gin 运行模式 | `debug` |
|
| `GIN_MODE` | Gin 运行模式 | `debug` |
|
||||||
| `OPEN_API_KEY` | 开放接口 ApiKey | 需修改 |
|
| `OPEN_API_KEY` | 开放接口 ApiKey | 需修改 |
|
||||||
| `OPEN_API_SECRET` | 开放接口签名密钥 | 需修改 |
|
| `OPEN_API_SECRET` | 开放接口签名密钥 | 需修改 |
|
||||||
|
|||||||
+6
-1
@@ -1,3 +1,5 @@
|
|||||||
|
name: ${COMPOSE_PROJECT_NAME:-affiliate_dash}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: ${POSTGRES_IMAGE:-docker.m.daocloud.io/library/postgres:16-alpine}
|
image: ${POSTGRES_IMAGE:-docker.m.daocloud.io/library/postgres:16-alpine}
|
||||||
@@ -8,6 +10,8 @@ services:
|
|||||||
- TZ=${TZ:-Asia/Shanghai}
|
- TZ=${TZ:-Asia/Shanghai}
|
||||||
- PGTZ=${TZ:-Asia/Shanghai}
|
- PGTZ=${TZ:-Asia/Shanghai}
|
||||||
command: ["postgres", "-c", "timezone=${TZ:-Asia/Shanghai}"]
|
command: ["postgres", "-c", "timezone=${TZ:-Asia/Shanghai}"]
|
||||||
|
ports:
|
||||||
|
- "${POSTGRES_PORT:-5432}:5432"
|
||||||
volumes:
|
volumes:
|
||||||
- postgres-data:/var/lib/postgresql/data
|
- postgres-data:/var/lib/postgresql/data
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -34,7 +38,7 @@ services:
|
|||||||
- PORT=8080
|
- PORT=8080
|
||||||
- TZ=${TZ:-Asia/Shanghai}
|
- TZ=${TZ:-Asia/Shanghai}
|
||||||
- JWT_SECRET=${JWT_SECRET}
|
- JWT_SECRET=${JWT_SECRET}
|
||||||
- "DATABASE_URL=postgres://${POSTGRES_USER:-affiliate}:${POSTGRES_PASSWORD:-affiliate_dev_password}@postgres:5432/${POSTGRES_DB:-affiliate_dash}?sslmode=disable&TimeZone=${TZ:-Asia/Shanghai}"
|
- "DATABASE_URL=${DOCKER_DATABASE_URL:-postgres://${POSTGRES_USER:-affiliate}:${POSTGRES_PASSWORD:-affiliate_dev_password}@postgres:5432/${POSTGRES_DB:-affiliate_dash}?sslmode=disable&TimeZone=${TZ:-Asia/Shanghai}}"
|
||||||
- GIN_MODE=${GIN_MODE:-release}
|
- GIN_MODE=${GIN_MODE:-release}
|
||||||
- OPEN_API_KEY=${OPEN_API_KEY}
|
- OPEN_API_KEY=${OPEN_API_KEY}
|
||||||
- OPEN_API_SECRET=${OPEN_API_SECRET}
|
- OPEN_API_SECRET=${OPEN_API_SECRET}
|
||||||
@@ -79,6 +83,7 @@ services:
|
|||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres-data:
|
postgres-data:
|
||||||
|
name: ${POSTGRES_DATA_VOLUME:-affiliate_dash_postgres_data}
|
||||||
backend-data:
|
backend-data:
|
||||||
caddy-data:
|
caddy-data:
|
||||||
caddy-config:
|
caddy-config:
|
||||||
|
|||||||
@@ -25,11 +25,15 @@ POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-affiliate_dev_password}"
|
|||||||
POSTGRES_DB="${POSTGRES_DB:-affiliate_dash}"
|
POSTGRES_DB="${POSTGRES_DB:-affiliate_dash}"
|
||||||
POSTGRES_PORT="${POSTGRES_PORT:-5432}"
|
POSTGRES_PORT="${POSTGRES_PORT:-5432}"
|
||||||
POSTGRES_IMAGE="${POSTGRES_IMAGE:-docker.m.daocloud.io/library/postgres:16-alpine}"
|
POSTGRES_IMAGE="${POSTGRES_IMAGE:-docker.m.daocloud.io/library/postgres:16-alpine}"
|
||||||
DEV_DB_CONTAINER="${DEV_DB_CONTAINER:-affiliate_dash_postgres_dev}"
|
COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-affiliate_dash}"
|
||||||
|
POSTGRES_DATA_VOLUME="${POSTGRES_DATA_VOLUME:-affiliate_dash_postgres_data}"
|
||||||
|
LEGACY_DEV_DB_CONTAINER="${DEV_DB_CONTAINER:-affiliate_dash_postgres_dev}"
|
||||||
TZ="${TZ:-Asia/Shanghai}"
|
TZ="${TZ:-Asia/Shanghai}"
|
||||||
DATABASE_URL="${DATABASE_URL:-postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@127.0.0.1:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable&TimeZone=${TZ}}"
|
DATABASE_URL="${DATABASE_URL:-postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@127.0.0.1:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable&TimeZone=${TZ}}"
|
||||||
export DATABASE_URL
|
export DATABASE_URL
|
||||||
export TZ
|
export TZ
|
||||||
|
export COMPOSE_PROJECT_NAME
|
||||||
|
export POSTGRES_USER POSTGRES_PASSWORD POSTGRES_DB POSTGRES_PORT POSTGRES_IMAGE POSTGRES_DATA_VOLUME
|
||||||
|
|
||||||
# 结束指定端口上的进程(避免残留占用)
|
# 结束指定端口上的进程(避免残留占用)
|
||||||
free_port() {
|
free_port() {
|
||||||
@@ -49,64 +53,75 @@ free_port() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
postgres_container_exists() {
|
docker_compose_available() {
|
||||||
docker ps -a --format '{{.Names}}' | grep -qx "$DEV_DB_CONTAINER"
|
command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
postgres_container_running() {
|
postgres_port_reachable() {
|
||||||
docker ps --format '{{.Names}}' | grep -qx "$DEV_DB_CONTAINER"
|
(echo >"/dev/tcp/127.0.0.1/${POSTGRES_PORT}") >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
postgres_container_timezone_ready() {
|
legacy_postgres_container_exists() {
|
||||||
local env cmd
|
docker ps -a --format '{{.Names}}' | grep -qx "$LEGACY_DEV_DB_CONTAINER"
|
||||||
env="$(docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' "$DEV_DB_CONTAINER" 2>/dev/null || true)"
|
}
|
||||||
cmd="$(docker inspect -f '{{json .Config.Cmd}}' "$DEV_DB_CONTAINER" 2>/dev/null || true)"
|
|
||||||
grep -qx "TZ=${TZ}" <<<"$env" && grep -qx "PGTZ=${TZ}" <<<"$env" && [[ "$cmd" == *"timezone=${TZ}"* ]]
|
legacy_postgres_container_running() {
|
||||||
|
docker ps --format '{{.Names}}' | grep -qx "$LEGACY_DEV_DB_CONTAINER"
|
||||||
|
}
|
||||||
|
|
||||||
|
compose_postgres_running() {
|
||||||
|
docker compose ps --services --status running 2>/dev/null | grep -qx "postgres"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_postgres_volume() {
|
||||||
|
local legacy_volume="${LEGACY_DEV_DB_CONTAINER}-data"
|
||||||
|
if [[ "${POSTGRES_DATA_VOLUME}" == "affiliate_dash_postgres_data" ]] && docker volume inspect "$legacy_volume" >/dev/null 2>&1; then
|
||||||
|
POSTGRES_DATA_VOLUME="$legacy_volume"
|
||||||
|
export POSTGRES_DATA_VOLUME
|
||||||
|
log "检测到旧开发库数据卷,Compose 将继续复用: ${POSTGRES_DATA_VOLUME}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_legacy_postgres_container() {
|
||||||
|
if legacy_postgres_container_exists; then
|
||||||
|
if legacy_postgres_container_running; then
|
||||||
|
log "检测到旧 PostgreSQL 开发容器,停止后交由 Docker Compose 管理: ${LEGACY_DEV_DB_CONTAINER}"
|
||||||
|
docker stop "$LEGACY_DEV_DB_CONTAINER" >/dev/null
|
||||||
|
else
|
||||||
|
log "检测到旧 PostgreSQL 开发容器已停止,保留容器和数据卷: ${LEGACY_DEV_DB_CONTAINER}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_postgres() {
|
ensure_postgres() {
|
||||||
if command -v docker >/dev/null 2>&1 && postgres_container_exists; then
|
if ! docker_compose_available; then
|
||||||
if ! postgres_container_timezone_ready; then
|
log "未找到 Docker Compose,请确认本机 PostgreSQL 已可通过 DATABASE_URL 访问"
|
||||||
log "检测到旧 PostgreSQL 开发容器缺少时区配置,重建容器并保留数据卷: ${DEV_DB_CONTAINER}"
|
|
||||||
docker rm -f "$DEV_DB_CONTAINER" >/dev/null
|
|
||||||
fi
|
|
||||||
elif (echo >"/dev/tcp/127.0.0.1/${POSTGRES_PORT}") >/dev/null 2>&1; then
|
|
||||||
log "检测到本机 PostgreSQL 端口已可访问: ${POSTGRES_PORT}"
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
if ! command -v docker >/dev/null 2>&1; then
|
|
||||||
log "未找到 Docker,请确认本机 PostgreSQL 已可通过 DATABASE_URL 访问"
|
prepare_postgres_volume
|
||||||
return 0
|
stop_legacy_postgres_container
|
||||||
fi
|
|
||||||
if postgres_container_running; then
|
if compose_postgres_running; then
|
||||||
log "PostgreSQL 开发容器已运行: ${DEV_DB_CONTAINER}"
|
log "PostgreSQL Compose 服务已运行: ${COMPOSE_PROJECT_NAME}/postgres"
|
||||||
elif postgres_container_exists; then
|
|
||||||
log "启动 PostgreSQL 开发容器: ${DEV_DB_CONTAINER}"
|
|
||||||
docker start "$DEV_DB_CONTAINER" >/dev/null
|
|
||||||
else
|
else
|
||||||
log "创建 PostgreSQL 开发容器: ${DEV_DB_CONTAINER}"
|
if postgres_port_reachable; then
|
||||||
docker run -d \
|
log "检测到本机 PostgreSQL 端口已可访问: ${POSTGRES_PORT},跳过 Compose 数据库启动"
|
||||||
--name "$DEV_DB_CONTAINER" \
|
return 0
|
||||||
-p "${POSTGRES_PORT}:5432" \
|
fi
|
||||||
-e POSTGRES_USER="$POSTGRES_USER" \
|
log "启动 PostgreSQL Compose 服务: ${COMPOSE_PROJECT_NAME}/postgres"
|
||||||
-e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \
|
docker compose up -d postgres >/dev/null
|
||||||
-e POSTGRES_DB="$POSTGRES_DB" \
|
|
||||||
-e TZ="$TZ" \
|
|
||||||
-e PGTZ="$TZ" \
|
|
||||||
-v "${DEV_DB_CONTAINER}-data:/var/lib/postgresql/data" \
|
|
||||||
"$POSTGRES_IMAGE" \
|
|
||||||
-c timezone="$TZ" >/dev/null
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for i in $(seq 1 40); do
|
for i in $(seq 1 40); do
|
||||||
if docker exec "$DEV_DB_CONTAINER" pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB" >/dev/null 2>&1; then
|
if docker compose exec -T postgres pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB" >/dev/null 2>&1; then
|
||||||
log "PostgreSQL 已就绪"
|
log "PostgreSQL 已就绪"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
sleep 0.5
|
sleep 0.5
|
||||||
done
|
done
|
||||||
echo "错误: PostgreSQL 启动超时"
|
echo "错误: PostgreSQL 启动超时"
|
||||||
docker logs "$DEV_DB_CONTAINER" 2>/dev/null || true
|
docker compose logs postgres 2>/dev/null || true
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user