update
This commit is contained in:
161
scripts/pgvector/setup_pg_docker.sh
Normal file
161
scripts/pgvector/setup_pg_docker.sh
Normal file
@ -0,0 +1,161 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user