Files
ttstd-infinite-canvas/scripts/install-server.sh

152 lines
5.3 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -Eeuo pipefail
REPOSITORY_URL="${REPOSITORY_URL:-https://github.com/ddcat-ai/open-ai-canvas.git}"
REPOSITORY_REF="${REPOSITORY_REF:-main}"
INSTALL_DIR="${INSTALL_DIR:-/opt/open-ai-canvas}"
CANVAS_HTTP_PORT="${CANVAS_HTTP_PORT:-3000}"
COMPOSE_FILE="docker-compose.deploy.yml"
BUILD_COMPOSE_FILE="docker-compose.build.yml"
step() {
printf '\n==> %s\n' "$1"
}
fail() {
printf '\n安装失败:%s\n' "$1" >&2
exit 1
}
require_root() {
if [[ "${EUID}" -ne 0 ]]; then
fail "请使用 README 中带 sudo 的一键安装命令"
fi
[[ "$(uname -s)" == "Linux" ]] || fail "一键部署脚本仅支持 Linux 服务器"
[[ "$CANVAS_HTTP_PORT" =~ ^[0-9]+$ ]] || fail "CANVAS_HTTP_PORT 必须是 1 到 65535 的数字"
((CANVAS_HTTP_PORT >= 1 && CANVAS_HTTP_PORT <= 65535)) || fail "CANVAS_HTTP_PORT 必须是 1 到 65535 的数字"
}
install_packages() {
local packages=(ca-certificates curl git openssl)
if command -v apt-get >/dev/null 2>&1; then
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}"
elif command -v dnf >/dev/null 2>&1; then
dnf install -y "${packages[@]}"
elif command -v yum >/dev/null 2>&1; then
yum install -y "${packages[@]}"
else
fail "暂不支持当前 Linux 发行版,请先手动安装 Docker、Git、curl 和 OpenSSL"
fi
}
install_docker() {
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
return
fi
step "安装 Docker 和 Docker Compose"
local installer
installer="$(mktemp)"
curl -fsSL https://get.docker.com -o "$installer"
sh "$installer"
rm -f "$installer"
if command -v systemctl >/dev/null 2>&1; then
systemctl enable --now docker
elif command -v service >/dev/null 2>&1; then
service docker start
fi
docker compose version >/dev/null 2>&1 || fail "Docker Compose 安装失败"
}
sync_source() {
step "下载影策源码"
if [[ -d "$INSTALL_DIR/.git" ]]; then
cd "$INSTALL_DIR"
[[ -z "$(git status --porcelain --untracked-files=no)" ]] || fail "$INSTALL_DIR 存在本地代码改动,请先处理后再更新"
git pull --ff-only origin "$REPOSITORY_REF"
return
fi
if [[ -e "$INSTALL_DIR" && -n "$(find "$INSTALL_DIR" -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null)" ]]; then
fail "$INSTALL_DIR 已存在且不是本脚本安装的仓库,为避免覆盖文件已停止"
fi
mkdir -p "$(dirname "$INSTALL_DIR")"
git clone --depth 1 --branch "$REPOSITORY_REF" "$REPOSITORY_URL" "$INSTALL_DIR"
cd "$INSTALL_DIR"
}
prepare_environment() {
if [[ -f .env ]]; then
grep -Eq '^POSTGRES_PASSWORD=.+$' .env || fail "现有 .env 缺少 POSTGRES_PASSWORD"
grep -Eq '^DATABASE_URL=.+$' .env || fail "现有 .env 缺少 DATABASE_URL"
local configured_http_port
configured_http_port="$(sed -n 's/^CANVAS_HTTP_PORT=//p' .env | tail -n 1)"
if [[ -n "$configured_http_port" ]]; then
[[ "$configured_http_port" =~ ^[0-9]+$ ]] || fail ".env 中的 CANVAS_HTTP_PORT 无效"
((configured_http_port >= 1 && configured_http_port <= 65535)) || fail ".env 中的 CANVAS_HTTP_PORT 无效"
CANVAS_HTTP_PORT="$configured_http_port"
fi
return
fi
step "生成 PostgreSQL 随机密码和部署配置"
local database_password
database_password="$(openssl rand -hex 32)"
umask 077
cat >.env <<EOF
POSTGRES_DB=open_ai_canvas
POSTGRES_USER=open_ai_canvas
POSTGRES_PASSWORD=${database_password}
DATABASE_URL=postgresql://open_ai_canvas:${database_password}@postgres:5432/open_ai_canvas?sslmode=disable
CANVAS_HTTP_PORT=${CANVAS_HTTP_PORT}
CANVAS_IMAGE_TAG=source
CANVAS_BACKEND_IMAGE=open-ai-canvas-backend:server
CANVAS_WEB_IMAGE=open-ai-canvas-web:server
CANVAS_YINGCE_AGENT_IMAGE=open-ai-canvas-yingce-agent:server
YINGCE_AGENT_TOKEN=$(openssl rand -hex 32)
CANVAS_REGISTRATION_ENABLED=false
CANVAS_ALLOW_PRIVATE_UPSTREAMS=false
CANVAS_ALLOWED_PRIVATE_UPSTREAM_HOSTS=
CANVAS_CORS_ORIGINS=
EOF
}
start_services() {
step "从源码构建网页、后端和 Agent 镜像"
# 标准一键部署已下载完整仓库,直接本地构建可避免公开项目被 GHCR 包可见性阻断。
docker compose --env-file .env -f "$COMPOSE_FILE" -f "$BUILD_COMPOSE_FILE" build migrate backend web yingce-agent
step "启动 PostgreSQL、Redis、后端和网页服务"
docker compose --env-file .env -f "$COMPOSE_FILE" -f "$BUILD_COMPOSE_FILE" up -d --remove-orphans --wait --wait-timeout 600
}
print_result() {
local local_ip
local_ip="$(hostname -I 2>/dev/null | awk '{print $1}')"
[[ -n "$local_ip" ]] || local_ip="服务器IP"
printf '\n部署完成。\n'
printf '访问地址:http://%s:%s\n' "$local_ip" "$CANVAS_HTTP_PORT"
printf '安装目录:%s\n' "$INSTALL_DIR"
printf '查看状态:cd %q && docker compose --env-file .env -f %s -f %s ps\n' "$INSTALL_DIR" "$COMPOSE_FILE" "$BUILD_COMPOSE_FILE"
printf '\n首次打开后注册的第一个账号会自动成为管理员。公网长期使用前请配置 HTTPS。\n'
}
main() {
require_root
step "安装服务器基础工具"
install_packages
install_docker
sync_source
prepare_environment
start_services
print_result
}
main "$@"