#!/usr/bin/env bash set -euo pipefail PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$PROJECT_DIR" # .env 固定路径(独立于项目目录,保证持久性) ENV_FILE="/opt/camtalk/.env" # 颜色输出 GREEN='\033[0;32m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } # .env 检查:首次部署时从 .env.example 复制模板,提示用户填写 check_env() { local env_example="$PROJECT_DIR/backend/.env.example" if [ ! -f "$ENV_FILE" ]; then mkdir -p "$(dirname "$ENV_FILE")" if [ -f "$env_example" ]; then cp "$env_example" "$ENV_FILE" info "未找到 $ENV_FILE,已从 .env.example 复制模板" echo " 请编辑 $ENV_FILE 填入实际配置后重新运行本脚本" exit 0 else echo "错误: $ENV_FILE 和 .env.example 均不存在,请手动创建" exit 1 fi fi } check_env # 所有 docker compose 命令统一使用 --env-file,用于解析 ${POSTGRES_USER} 等变量 DC="docker compose --env-file $ENV_FILE" cmd_build() { info "构建 Docker 镜像..." DOCKER_BUILDKIT=1 $DC build --parallel info "构建完成" } cmd_up() { info "启动服务..." $DC up -d info "服务已启动" PUBLIC_IP=$(curl -s --connect-timeout 3 https://ifconfig.me 2>/dev/null || \ curl -s --connect-timeout 3 https://api.ipify.org 2>/dev/null || \ echo "YOUR_SERVER_IP") info "前端: http://$PUBLIC_IP:9000" info "健康检查: http://$PUBLIC_IP:9000/api/health" } cmd_down() { info "停止服务..." $DC down info "服务已停止" } cmd_restart() { info "重启服务..." cmd_down cmd_up } cmd_logs() { $DC logs -f "${@}" } cmd_status() { $DC ps } usage() { cat < 命令: build 构建 Docker 镜像 up 启动服务(后台运行) down 停止服务 restart 重启服务 logs 查看日志(可加服务名,如: $0 logs backend) status 查看服务状态 .env 路径: $ENV_FILE EOF } case "${1:-}" in build) cmd_build ;; up) cmd_up ;; down) cmd_down ;; restart) cmd_restart ;; logs) shift; cmd_logs "$@" ;; status) cmd_status ;; *) usage; exit 1 ;; esac