初始化

This commit is contained in:
2026-06-25 09:41:16 +08:00
commit 34001a4296
10 changed files with 689 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
/.idea/*
+37
View File
@@ -0,0 +1,37 @@
#!/bin/bash
set -e
# PostgreSQL standby bootstrap entrypoint
# If data dir is empty, pull base backup from primary, then hand off to postgres entrypoint
PRIMARY_HOST="${PG_PRIMARY_HOST:-host1}"
PRIMARY_PORT="${PG_PRIMARY_PORT:-5432}"
REPL_PASSWORD="${REPL_PASSWORD:-Bjang09@686-Repl}"
PGDATA="/var/lib/postgresql/data"
if [ ! -s "$PGDATA/PG_VERSION" ]; then
echo "[standby] Data directory empty, bootstrapping from primary $PRIMARY_HOST:$PRIMARY_PORT"
# Wait for primary to accept connections
for i in $(seq 1 30); do
if PGPASSWORD="$REPL_PASSWORD" pg_isready -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" -U replicator >/dev/null 2>&1; then
break
fi
echo "[standby] Waiting for primary to be ready (attempt $i/30)..."
sleep 2
done
# Pull base backup from primary
echo "[standby] Running pg_basebackup..."
PGPASSWORD="$REPL_PASSWORD" pg_basebackup -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" \
-U replicator -D "$PGDATA" -P -R \
-S replication_slot_slave --checkpoint=fast --wal-method=stream
# Ensure standby signal file exists
touch "$PGDATA/standby.signal"
echo "[standby] Bootstrap complete, starting standby..."
fi
# Hand off to the standard postgres entrypoint
exec /usr/local/bin/docker-entrypoint.sh "$@"
+313
View File
@@ -0,0 +1,313 @@
# ============================================================
# 红动未来 - Go 微服务
# ============================================================
# 配合中间件启动:
# docker compose -f deploy/docker-compose-infra-main.yml -f deploy/docker-compose-app.yml up -d
# 仅应用(需要 infra 网络已存在):
# docker compose -f deploy/docker-compose-app.yml up -d
# 构建后启动:
# docker compose -f deploy/docker-compose-app.yml build
# docker compose -f deploy/docker-compose-infra-main.yml -f deploy/docker-compose-app.yml up -d
# ============================================================
name: redfuture
networks:
redfuture-net:
driver: bridge
services:
gateway:
build:
context: ../gateway
dockerfile: Dockerfile
container_name: gateway
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- ../gateway/config.yml:/build/config.yml
depends_on:
redis:
condition: service_healthy
consul:
condition: service_started
networks:
- redfuture-net
admin-go:
build:
context: ../admin-go
dockerfile: Dockerfile
container_name: admin-go
restart: unless-stopped
ports:
- "8808:8808"
volumes:
- ../admin-go/config.yaml:/build/manifest/config/config.yaml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
ai-agent:
build:
context: ../ai-agent
dockerfile: Dockerfile
container_name: ai-agent
restart: unless-stopped
volumes:
- ../ai-agent/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
assets:
build:
context: ../assets
dockerfile: Dockerfile
container_name: assets
restart: unless-stopped
ports:
- "3003:3003"
volumes:
- ../assets/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
nats:
condition: service_started
networks:
- redfuture-net
cid:
build:
context: ../cid
dockerfile: Dockerfile
container_name: cid
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- ../cid/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
customer-server:
build:
context: ../customer-server
dockerfile: Dockerfile
container_name: customer-server
restart: unless-stopped
ports:
- "3012:3012"
volumes:
- ../customer-server/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
mongodb:
condition: service_started
nats:
condition: service_started
rabbitmq:
condition: service_started
networks:
- redfuture-net
data-engine:
build:
context: ../data-engine
dockerfile: Dockerfile
container_name: data-engine
restart: unless-stopped
ports:
- "3013:3013"
volumes:
- ../data-engine/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
erp:
build:
context: ../erp
dockerfile: Dockerfile
container_name: erp
restart: unless-stopped
ports:
- "3011:3011"
volumes:
- ../erp/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
media:
build:
context: ../media
dockerfile: Dockerfile
container_name: media
restart: unless-stopped
ports:
- "3010:3010"
volumes:
- ../media/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
model-gateway:
build:
context: ../model-gateway
dockerfile: Dockerfile
container_name: model-gateway
restart: unless-stopped
ports:
- "3004:3004"
volumes:
- ../model-gateway/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
order:
build:
context: ../order
dockerfile: Dockerfile
container_name: order
restart: unless-stopped
ports:
- "3002:3002"
volumes:
- ../order/config.yml:/build/config.yml
depends_on:
redis:
condition: service_healthy
mongodb:
condition: service_started
networks:
- redfuture-net
oss:
build:
context: ../oss
dockerfile: Dockerfile
container_name: oss
restart: unless-stopped
ports:
- "3008:3008"
volumes:
- ../oss/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
minio:
condition: service_started
networks:
- redfuture-net
prompts-core:
build:
context: ../prompts-core
dockerfile: Dockerfile
container_name: prompts-core
restart: unless-stopped
ports:
- "3009:3009"
volumes:
- ../prompts-core/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
rag:
build:
context: ../rag
dockerfile: Dockerfile
container_name: rag
restart: unless-stopped
ports:
- "3006:3006"
volumes:
- ../rag/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
meilisearch:
condition: service_started
networks:
- redfuture-net
shop-user-trade:
build:
context: ../shop-user-trade
dockerfile: Dockerfile
container_name: shop-user-trade
restart: unless-stopped
ports:
- "3007:3007"
volumes:
- ../shop-user-trade/config.yml:/build/config.yml
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- redfuture-net
video-factory:
build:
context: ../video-factory
dockerfile: Dockerfile
container_name: video-factory
restart: unless-stopped
ports:
- "3015:3006"
volumes:
- ../video-factory/config.yml:/build/config.yml
- ../data/video-factory:/build/data
networks:
- redfuture-net
+141
View File
@@ -0,0 +1,141 @@
# ============================================================
# 红动未来 - 第三方中间件
# ============================================================
# 启动:docker compose -f deploy/docker-compose-infra-main.yml up -d
# 停止:docker compose -f deploy/docker-compose-infra-main.yml down
# ============================================================
name: redfuture
networks:
redfuture-net:
driver: bridge
services:
# ---- PostgreSQL (pgvector) ----
postgres:
image: docker.m.daocloud.io/pgvector/pgvector:pg16
container_name: postgres
restart: unless-stopped
ports:
- "15432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: Bjang09@686^*^
POSTGRES_DB: postgres
volumes:
- ../data/postgres:/var/lib/postgresql/data
- ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql
- ./sql/init-replication.sql:/docker-entrypoint-initdb.d/init-replication.sql
- ./sql/init-pg-hba.sh:/docker-entrypoint-initdb.d/init-pg-hba.sh
command: ["postgres", "-c", "wal_level=replica", "-c", "max_wal_senders=10", "-c", "max_replication_slots=10", "-c", "hot_standby=on"]
networks:
- redfuture-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# ---- PostgreSQL 自动备份 (每日凌晨 2:00) ----
postgres-backup:
image: docker.m.daocloud.io/pgvector/pgvector:pg16
container_name: postgres-backup
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
volumes:
- ../data/postgres-backup:/backup
- ./scripts/postgres-backup.sh:/usr/local/bin/backup.sh
environment:
PGUSER: postgres
PGPASSWORD: Bjang09@686^*^
PGHOST: postgres
PGPORT: 5432
BACKUP_DIR: /backup
RETENTION_DAYS: 7
command: sh /usr/local/bin/backup.sh
networks:
- redfuture-net
# ---- Redis ----
redis:
image: docker.m.daocloud.io/redis:7.4.8
container_name: redis
restart: unless-stopped
ports:
- "6379:6379"
command: redis-server --requirepass Bjang09@686^*^
volumes:
- ../data/redis:/data
networks:
- redfuture-net
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 10s
timeout: 5s
retries: 5
# ---- Consul ----
consul:
image: docker.m.daocloud.io/consul:1.15.4
container_name: consul
restart: unless-stopped
ports:
- "8500:8500"
init: true
command: agent -server -bootstrap -ui -data-dir=/consul/data -bind=0.0.0.0 -client=0.0.0.0
volumes:
- ../data/consul:/consul/data
networks:
- redfuture-net
# ---- MinIO ----
minio:
image: docker.m.daocloud.io/minio/minio
container_name: minio
restart: unless-stopped
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: Bjang09@686^*^
command: server /data --console-address ":9001"
volumes:
- ../data/minio:/data
networks:
- redfuture-net
# ---- MeiliSearch ----
meilisearch:
image: docker.m.daocloud.io/getmeili/meilisearch:v1.3
container_name: meilisearch
restart: unless-stopped
ports:
- "7700:7700"
environment:
MEILI_MASTER_KEY: wMW7BPM3CLwnEGpPbaoci-HvB8R37wV-5tGIizsDQSQ
volumes:
- ../data/meilisearch:/meili_data
networks:
- redfuture-net
# ---- NATS (with JetStream) ----
nats:
image: docker.m.daocloud.io/nats:latest
container_name: nats
restart: unless-stopped
ports:
- "4222:4222"
- "8222:8222"
command: -js -sd /data -m 8222
volumes:
- ../data/nats:/data
depends_on:
redis:
condition: service_healthy
networks:
- redfuture-net
+91
View File
@@ -0,0 +1,91 @@
# ============================================================
# 红动未来 - 从机集群(Host2)
# 主从/集群配置:Redis 从库、PostgreSQL 从库、K3s Agent
# ============================================================
# 前置条件:Host1 已启动 deploy/docker-compose-infra-main.yml
# ============================================================
# 启动:docker compose -f deploy/docker-compose-infra-slave.yml up -d
# 停止:docker compose -f deploy/docker-compose-infra-slave.yml down
# ============================================================
name: redfuture-slave
# ---- 共享变量(部署前修改 Host1 IP) ----
x-vars: &vars
MASTER_IP: 192.168.0.169
PG_USER: postgres
PG_PASSWORD: Bjang09@686^*^
PG_PRIMARY_PORT: 15432
services:
# ---- PostgreSQL 从库 (Streaming Replication) ----
postgres-standby:
image: docker.m.daocloud.io/pgvector/pgvector:pg16
container_name: postgres-standby
restart: unless-stopped
ports:
- "15432:5432"
environment:
<<: *vars
POSTGRES_USER: postgres
POSTGRES_PASSWORD: Bjang09@686^*^
POSTGRES_DB: postgres
volumes:
- ../data/postgres-standby:/var/lib/postgresql/data
entrypoint: ["/bin/sh", "-c"]
command:
- |
set -e
PGDATA="/var/lib/postgresql/data"
if [ ! -s "$${PGDATA}/PG_VERSION" ]; then
echo "[standby] Data empty, running pg_basebackup from $${MASTER_IP}:$${PG_PRIMARY_PORT}..."
PGPASSWORD="$${PG_PASSWORD}" pg_basebackup \
-h "$${MASTER_IP}" -p "$${PG_PRIMARY_PORT}" \
-U $${PG_USER} -D "$${PGDATA}" -P -R \
-S replication_slot_slave --checkpoint=fast --wal-method=stream
touch "$${PGDATA}/standby.signal"
echo "[standby] Bootstrap complete."
fi
exec docker-entrypoint.sh \
postgres \
-c wal_level=replica \
-c hot_standby=on \
-c hot_standby_feedback=on \
-c "primary_conninfo=host=$${MASTER_IP} port=$${PG_PRIMARY_PORT} user=$${PG_USER} password=$${PG_PASSWORD} application_name=standby1"
networks:
- redfuture-slave-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# ---- Redis 从库 (Replication) ----
redis-replica:
image: docker.m.daocloud.io/redis:7.4.8
container_name: redis-replica
restart: unless-stopped
ports:
- "6379:6379"
command:
- redis-server
- --replicaof
- 192.168.0.169
- "6379"
- --requirepass
- Bjang09@686^*^
- --masterauth
- Bjang09@686^*^
volumes:
- ../data/redis-replica:/data
networks:
- redfuture-slave-net
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
redfuture-slave-net:
driver: bridge
+36
View File
@@ -0,0 +1,36 @@
#!/bin/sh
set -e
CREDENTIALS="-h ${PGHOST:-postgres} -U ${PGUSER:-postgres}"
BACKUP_DIR=${BACKUP_DIR:-/backup}
RETENTION_DAYS=${RETENTION_DAYS:-7}
backup() {
local filename="backup_$(date +%Y%m%d_%H%M%S).sql.gz"
echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Starting backup: $filename"
pg_dumpall $CREDENTIALS | gzip > "$BACKUP_DIR/$filename"
echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Backup complete: $(du -h "$BACKUP_DIR/$filename" | cut -f1)"
}
cleanup() {
local count=$(find "$BACKUP_DIR" -name "backup_*.sql.gz" -mtime +$RETENTION_DAYS | wc -l)
if [ "$count" -gt 0 ]; then
find "$BACKUP_DIR" -name "backup_*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Cleaned up $count backup(s) older than $RETENTION_DAYS days"
fi
}
# Run immediately on startup
backup
cleanup
# Schedule: calculate seconds until next 2:00 AM, then run every 24h
while true; do
now=$(date +%s)
target=$(date -d "tomorrow 02:00" +%s)
sleep_seconds=$((target - now))
echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Next backup scheduled at $(date -d @$target '+%Y-%m-%d %H:%M:%S')"
sleep $sleep_seconds
backup
cleanup
done
+21
View File
@@ -0,0 +1,21 @@
#!/bin/sh
set -e
# 红动未来 - PostgreSQL 主从复制初始化
# 在 Host1(主库)上执行一次,为从库复制做准备
# 用法:sh deploy/scripts/setup-replication.sh
POSTGRES_CONTAINER="${POSTGRES_CONTAINER:-postgres}"
echo "=== 1. 添加 pg_hba 复制规则 ==="
docker exec "$POSTGRES_CONTAINER" sh -c 'echo "host replication all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf'
echo "=== 2. 重载 PostgreSQL 配置 ==="
docker exec "$POSTGRES_CONTAINER" psql -U postgres -c "SELECT pg_reload_conf();"
echo "=== 3. 创建物理复制槽 ==="
docker exec "$POSTGRES_CONTAINER" psql -U postgres -c "SELECT pg_create_physical_replication_slot('replication_slot_slave') WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'replication_slot_slave');"
echo "=== 完成 ==="
echo "现在可以在从库(Host2)上启动 PostgreSQL 从库:"
echo " docker compose -f deploy/docker-compose-infra-slave.yml up -d postgres-standby"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
# 添加 pg_hba 复制访问规则(在 docker-entrypoint 初始化后执行)
echo "host replication all 0.0.0.0/0 md5" >> "$PGDATA/pg_hba.conf"
+12
View File
@@ -0,0 +1,12 @@
-- 创建复制用户(在 Host1 主库上运行)
DO $$
BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'replicator') THEN
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'Bjang09@686^*^';
END IF;
END
$$;
-- 创建复制槽(用于主从复制)
SELECT pg_create_physical_replication_slot('replication_slot_slave')
WHERE NOT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'replication_slot_slave');
+34
View File
@@ -0,0 +1,34 @@
-- 红动未来 - 初始化数据库和扩展
CREATE EXTENSION IF NOT EXISTS vector;
-- 为各微服务创建数据库
SELECT 'CREATE DATABASE admin_go'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'admin_go')\gexec
SELECT 'CREATE DATABASE ai_agent'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'ai_agent')\gexec
SELECT 'CREATE DATABASE assets'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'assets')\gexec
SELECT 'CREATE DATABASE cid'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'cid')\gexec
SELECT 'CREATE DATABASE customer_server'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'customer_server')\gexec
SELECT 'CREATE DATABASE data_engine'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'data_engine')\gexec
SELECT 'CREATE DATABASE erp'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'erp')\gexec
SELECT 'CREATE DATABASE media'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'media')\gexec
SELECT 'CREATE DATABASE model_gateway'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'model_gateway')\gexec
SELECT 'CREATE DATABASE orders'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'orders')\gexec
SELECT 'CREATE DATABASE oss'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'oss')\gexec
SELECT 'CREATE DATABASE prompts_core'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'prompts_core')\gexec
SELECT 'CREATE DATABASE rag'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'rag')\gexec
SELECT 'CREATE DATABASE shop_user_trade'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'shop_user_trade')\gexec
SELECT 'CREATE DATABASE video_factory'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'video_factory')\gexec