#!/usr/bin/env bash set -euo pipefail PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$PROJECT_DIR" # .env 存放于项目目录,供 docker compose env_file 读取 #(act_runner 容器内无法访问 /opt/camtalk,需放在项目目录下) ENV_FILE="$PROJECT_DIR/.env" # 颜色输出 GREEN='\033[0;32m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } # .env 检查:首次部署时从 .env.example 复制模板,提示用户填写 check_env() { if [ -f "$ENV_FILE" ]; then return 0 fi # 如果项目目录没有 .env,尝试从 /opt/camtalk/.env 复制(兼容旧部署) local legacy_env="/opt/camtalk/.env" if [ -f "$legacy_env" ]; then cp "$legacy_env" "$ENV_FILE" info "已从 $legacy_env 复制环境变量文件" return 0 fi echo "==============================================" echo " 错误: 未找到环境变量文件" echo "" echo " 请在以下任一位置创建 .env 文件:" echo " 1. $ENV_FILE" echo " 2. $legacy_env(运行本脚本时会自动复制)" echo "" echo " 模板参考: backend/.env.example" echo "==============================================" exit 1 } 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