Files
backend_v2/scripts/pgvector/setup_pg_docker.sh
toom1996 6c31b18e0f update
2026-09-17 00:38:01 +08:00

162 lines
6.6 KiB
Bash
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
#
# setup_pg_docker.sh — 用 Docker 起 PostgreSQL 16 + pgvector 本地开发环境
#
# 用法(在 WSL 终端里,不要用 Windows 的 CMD/PowerShell):
# sudo bash setup_pg_docker.sh
#
# 行为:
# 1) 先卸载上次用 apt 装失败的 PostgreSQL 残留(清理 pgdg 源 / 坏 key / 包),幂等。
# 2) 确保 docker 可用(缺失则尝试 apt 装 docker.io 并起守护进程;仍不行则给出 Docker Desktop 指引)。
# 3) docker compose up -d 起 pgvector 容器(幂等:已存在则不变)。
# 4) 等就绪后验证 version() 与 vector 扩展版本。
#
# 仅用于本地开发 / 迁移验证。生产请改强密码并单独评审配置。
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPOSE_FILE="$SCRIPT_DIR/docker-compose.yml"
DB_USER=fashion
DB_PASS="fashion_dev_2026"
DB_NAME=fashion
log() { echo -e "\033[32m==>\033[0m $*"; }
warn() { echo -e "\033[33m⚠️ \033[0m $*"; }
if [ "$(id -u)" -ne 0 ]; then
echo "请以 root 运行: sudo bash $0"; exit 1
fi
# ---------- 1) 卸载上次 apt 版 PostgreSQL 的残留 ----------
if command -v psql >/dev/null 2>&1 || [ -f /etc/apt/sources.list.d/pgdg.list ]; then
log "卸载上次 apt 版 PostgreSQL 残留(清理失败残留,幂等)"
pg_ctlcluster "$(ls /etc/postgresql 2>/dev/null | head -1)" main stop 2>/dev/null \
|| service postgresql stop 2>/dev/null \
|| true
apt-get remove --purge -y 'postgresql-*' 2>/dev/null || true
rm -f /etc/apt/sources.list.d/pgdg.list
rm -f /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
/usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg
apt-get autoremove -y 2>/dev/null || true
log "apt 版 PostgreSQL 残留已清理"
else
log "未发现 apt 版 PostgreSQL,跳过卸载"
fi
# ---------- 2) 确保 docker 可用 ----------
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
log "docker 可用"
else
if command -v docker >/dev/null 2>&1; then
warn "docker 已安装但守护进程未起,尝试启动"
service docker start 2>/dev/null || (dockerd >/var/log/docker.log 2>&1 &) || true
sleep 3
fi
if ! command -v docker >/dev/null 2>&1 || ! docker info >/dev/null 2>&1; then
warn "docker 不可用,尝试 apt 安装 docker.io"
apt-get update -y
if apt-get install -y docker.io; then
service docker start 2>/dev/null || (dockerd >/var/log/docker.log 2>&1 &) || true
sleep 3
fi
fi
if ! command -v docker >/dev/null 2>&1 || ! docker info >/dev/null 2>&1; then
echo "❌ 仍无法使用 docker。请二选一:"
echo " A) 装 Docker Desktop (Windows),安装时勾选 'Use WSL 2',"
echo " 装好后在其 Settings > Resources > WSL Integration 里启用你的 WSL 发行版,重启 WSL 后重试;"
echo " B) 或在本 WSL 内: sudo apt-get install -y docker.io && sudo service docker start"
exit 1
fi
fi
# 选 docker compose 命令(v2 插件优先,回退 v1)
if docker compose version >/dev/null 2>&1; then
DC=(docker compose)
elif command -v docker-compose >/dev/null 2>&1; then
DC=(docker-compose)
else
echo "❌ 未找到 docker compose / docker-compose,请安装 Docker Compose 后重试"; exit 1
fi
# ---------- 2.5) 配置国内镜像源加速(避免直连 Docker Hub 慢) ----------
MIRRORS='["https://docker.m.daocloud.io","https://hub-mirror.c.163.com","https://mirror.baidubce.com"]'
if docker context ls 2>/dev/null | grep -qw "desktop-linux" || [[ "${DOCKER_HOST:-}" == *"npipe"* ]]; then
# Docker Desktop(守护进程在 Windows 侧):WSL 内的 daemon.json 不生效,必须在 GUI 配
warn "检测到 Docker Desktop:WSL 内的 daemon.json 不影响 Windows 侧守护进程。"
echo " 请在 Windows 的 Docker Desktop > Settings > Docker Engine 的 JSON 中加入:"
echo " \"registry-mirrors\": $MIRRORS"
echo " 然后点 Apply & Restart;重启后再直接跑: docker compose -f $COMPOSE_FILE up -d"
echo " (本脚本不再自动拉起,避免与 Docker Desktop 守护进程冲突)"
exit 1
elif ! docker info 2>/dev/null | grep -q "docker.m.daocloud.io"; then
# docker.io 跑在 WSL 内:直接写 daemon.json 并重启守护进程
if [ ! -f /etc/docker/daemon.json ] || ! grep -q registry-mirrors /etc/docker/daemon.json; then
log "配置国内镜像源加速(写入 /etc/docker/daemon.json 并重启 docker 守护进程)"
cat > /etc/docker/daemon.json <<JSON
{
"registry-mirrors": $MIRRORS
}
JSON
service docker restart 2>/dev/null || systemctl restart docker 2>/dev/null \
|| (dockerd --registry-mirror=https://docker.m.daocloud.io >/var/log/docker.log 2>&1 &) || true
sleep 3
else
log "daemon.json 已含 registry-mirrors,跳过"
fi
# 等守护进程重新就绪
for i in $(seq 1 15); do
docker info >/dev/null 2>&1 && break
sleep 1
done
fi
# ---------- 3) 起容器(幂等) ----------
log "启动 PostgreSQL + pgvector 容器(docker compose up -d)"
"${DC[@]}" -f "$COMPOSE_FILE" up -d
# ---------- 4) 等就绪 ----------
log "等待数据库就绪(最多 30s)"
ready=0
for i in $(seq 1 30); do
if docker exec pgvector pg_isready -U "$DB_USER" -d "$DB_NAME" >/dev/null 2>&1; then
ready=1; break
fi
sleep 1
done
if [ "$ready" -ne 1 ]; then
echo "❌ 数据库未就绪,查看日志: docker logs pgvector"; exit 1
fi
# ---------- 5) 验证 ----------
log "验证安装"
docker exec -i pgvector psql -U "$DB_USER" -d "$DB_NAME" \
-c "SELECT version();" \
-c "SELECT extname, extversion FROM pg_extension WHERE extname='vector';"
cat <<EOF
✅ PostgreSQL 16 + pgvector 就绪(Docker,容器名 pgvector)
连接串 : postgres://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME
命令行 : docker exec -it pgvector psql -U $DB_USER -d $DB_NAME
启停 : docker compose -f $COMPOSE_FILE up -d / stop
清数据 : docker compose -f $COMPOSE_FILE down -v
(可选)CLIP / DINOv2 embedding 表示例:
CREATE TABLE image_embedding (
id BIGSERIAL PRIMARY KEY,
image_uid VARCHAR(32) NOT NULL, -- 对应你现有的 hashid uid
kind SMALLINT NOT NULL, -- 0=runway 1=street
embedding vector(512), -- 512 维特征(CLIP ViT-B/32 或 DINOv2)
created_at INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX image_embedding_vec_idx
ON image_embedding USING hnsw (embedding vector_cosine_ops);
-- 去重查询:找最近邻
SELECT image_uid, 1 - (embedding <=> '[...]'::vector) AS sim
FROM image_embedding
WHERE kind = 0
ORDER BY embedding <=> '[...]'::vector
LIMIT 20;
EOF