#!/usr/bin/env bash # 生产部署脚本:启动前拉取最新代码 → 构建镜像 → 停止旧容器 → 启动新容器 # 环境:仅读取 .env.prod(不读 .env)。首次部署请 cp .env.prod.example .env.prod 并编辑后执行本脚本。 # 用法: ./run-docker.sh [-p PORT] [-b BACKEND_PORT] [-d HOST_DATA_DIR] # -p, --port PORT 前端宿主机端口,默认 3000 # -b, --backend-port PORT 后端 API 宿主机端口,默认 8000(容器内固定 8000) # -d, --data-dir DIR 数据目录挂载,默认 ./data cp .env.prod.example .env.prod set -e IMAGE_NAME="wechat-admin-backend" CONTAINER_NAME="wechat-admin-backend" PORT="${PORT:-3000}" BACKEND_PORT="${BACKEND_PORT:-8000}" HOST_DATA_DIR="${HOST_DATA_DIR:-$(pwd)/data}" while [[ $# -gt 0 ]]; do case $1 in -p|--port) PORT="$2"; shift 2 ;; -b|--backend-port) BACKEND_PORT="$2"; shift 2 ;; -d|--data-dir) HOST_DATA_DIR="$2"; shift 2 ;; -h|--help) echo "Usage: $0 [-p PORT] [-b BACKEND_PORT] [-d HOST_DATA_DIR]"; echo " -p, --port PORT frontend (default 3000)"; echo " -b, --backend-port PORT backend API (default 8000)"; echo " -d, --data-dir DIR data volume (default \$(pwd)/data)"; exit 0 ;; *) echo "Unknown option: $1 (use -h for help)"; exit 1 ;; esac done # 启动前自动获取最新代码(与远端 master 一致,丢弃本地修改) if git rev-parse --git-dir >/dev/null 2>&1; then echo "Fetching and reset to origin/master..." git fetch --all && git reset --hard origin/master else echo "Not a git repo, skip git fetch/reset." fi echo "Building Docker image: ${IMAGE_NAME}..." docker build -t "${IMAGE_NAME}" . echo "Stopping and removing existing container (if any)..." if [ "$(docker ps -aq -f name=${CONTAINER_NAME})" ]; then docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true fi mkdir -p "${HOST_DATA_DIR}" echo "Data dir (host): ${HOST_DATA_DIR} -> container /app/backend/data" # 生产仅读取 .env.prod(不读 .env,避免混用本地配置) ENV_FILE=".env.prod" if [ ! -f "${ENV_FILE}" ]; then if [ -f ".env.prod.example" ]; then echo "Creating ${ENV_FILE} from .env.prod.example ..." cp .env.prod.example "${ENV_FILE}" echo "Please edit ${ENV_FILE} with production values (e.g. CALLBACK_BASE_URL, API keys) and run $0 again." exit 1 else echo "Error: ${ENV_FILE} and .env.prod.example not found. Cannot start production container." exit 1 fi fi echo "Using env file: ${ENV_FILE}" echo "Running container ${CONTAINER_NAME} (frontend :${PORT}, backend :${BACKEND_PORT})..." docker run -d \ --name "${CONTAINER_NAME}" \ --env-file "${ENV_FILE}" \ -p "${PORT}:3000" \ -p "${BACKEND_PORT}:8000" \ -v "${HOST_DATA_DIR}:/app/backend/data" \ "${IMAGE_NAME}" echo "Container started. Data persisted on host: ${HOST_DATA_DIR}" echo "Frontend: http://localhost:${PORT} | Backend API: http://localhost:${BACKEND_PORT} | Health: curl http://localhost:${PORT}/health"