优化 Docker 开发启动流程

This commit is contained in:
yml2213
2026-07-31 16:27:51 +08:00
parent 30362f14bd
commit a091806283
5 changed files with 86 additions and 45 deletions
+55 -40
View File
@@ -25,11 +25,15 @@ POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-affiliate_dev_password}"
POSTGRES_DB="${POSTGRES_DB:-affiliate_dash}"
POSTGRES_PORT="${POSTGRES_PORT:-5432}"
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}"
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 TZ
export COMPOSE_PROJECT_NAME
export POSTGRES_USER POSTGRES_PASSWORD POSTGRES_DB POSTGRES_PORT POSTGRES_IMAGE POSTGRES_DATA_VOLUME
# 结束指定端口上的进程(避免残留占用)
free_port() {
@@ -49,64 +53,75 @@ free_port() {
fi
}
postgres_container_exists() {
docker ps -a --format '{{.Names}}' | grep -qx "$DEV_DB_CONTAINER"
docker_compose_available() {
command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1
}
postgres_container_running() {
docker ps --format '{{.Names}}' | grep -qx "$DEV_DB_CONTAINER"
postgres_port_reachable() {
(echo >"/dev/tcp/127.0.0.1/${POSTGRES_PORT}") >/dev/null 2>&1
}
postgres_container_timezone_ready() {
local env cmd
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_exists() {
docker ps -a --format '{{.Names}}' | grep -qx "$LEGACY_DEV_DB_CONTAINER"
}
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() {
if command -v docker >/dev/null 2>&1 && postgres_container_exists; then
if ! postgres_container_timezone_ready; then
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}"
if ! docker_compose_available; then
log "未找到 Docker Compose,请确认本机 PostgreSQL 已可通过 DATABASE_URL 访问"
return 0
fi
if ! command -v docker >/dev/null 2>&1; then
log "未找到 Docker,请确认本机 PostgreSQL 已可通过 DATABASE_URL 访问"
return 0
fi
if postgres_container_running; then
log "PostgreSQL 开发容器已运行: ${DEV_DB_CONTAINER}"
elif postgres_container_exists; then
log "启动 PostgreSQL 开发容器: ${DEV_DB_CONTAINER}"
docker start "$DEV_DB_CONTAINER" >/dev/null
prepare_postgres_volume
stop_legacy_postgres_container
if compose_postgres_running; then
log "PostgreSQL Compose 服务已运行: ${COMPOSE_PROJECT_NAME}/postgres"
else
log "创建 PostgreSQL 开发容器: ${DEV_DB_CONTAINER}"
docker run -d \
--name "$DEV_DB_CONTAINER" \
-p "${POSTGRES_PORT}:5432" \
-e POSTGRES_USER="$POSTGRES_USER" \
-e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \
-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
if postgres_port_reachable; then
log "检测到本机 PostgreSQL 端口已可访问: ${POSTGRES_PORT},跳过 Compose 数据库启动"
return 0
fi
log "启动 PostgreSQL Compose 服务: ${COMPOSE_PROJECT_NAME}/postgres"
docker compose up -d postgres >/dev/null
fi
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 已就绪"
return 0
fi
sleep 0.5
done
echo "错误: PostgreSQL 启动超时"
docker logs "$DEV_DB_CONTAINER" 2>/dev/null || true
docker compose logs postgres 2>/dev/null || true
exit 1
}