# ============================================================ # 红动未来 - 第三方中间件 # ============================================================ # 启动: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: - "5432:5432" environment: # 仅首次初始化空数据卷时生效;库内超级用户已被 ALTER ROLE 改名、口令已改, # 这里写成与新库一致的名字/口令(占位符,需你自行替换成实际值)。 POSTGRES_USER: 259278618@qq.com POSTGRES_PASSWORD: Tongli686^*^ POSTGRES_DB: postgres volumes: - /data/pgsql:/var/lib/postgresql/data command: ["postgres", "-c", "wal_level=replica", "-c", "max_wal_senders=10", "-c", "max_replication_slots=10", "-c", "hot_standby=on"] networks: - redfuture-net healthcheck: # 真实连接探测(容器内本地 socket 是 trust 认证免密),角色/库名引用环境变量; # 不用 pg_isready:它不带 -U 时以 OS 用户 root 握手,服务器每 10s 记一条 FATAL: role "root" does not exist test: ["CMD-SHELL", "psql -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\" -c 'select 1'"] 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/pgsql/backup:/backup environment: TZ: Asia/Shanghai # 使下面的 02:00 与备份文件名时间都按北京时间计算 PGUSER: 259278618@qq.com # ← 改为你 ALTER ROLE 后的新超级用户名 PGPASSWORD: Tongli686^*^ # ← 改为新超级用户口令 PGHOST: postgres PGPORT: 5432 BACKUP_DIR: /backup RETENTION_DAYS: 7 networks: - redfuture-net entrypoint: ["/bin/sh", "-c"] command: - | set -e mkdir -p "/backup" echo "[$(date '+%F %T %Z')] postgres-backup started. Will run once per day at 02:00." while true; do # 睡到下一个 02:00(容器 TZ=Asia/Shanghai → 即北京时间凌晨2点) now=$$(date +%s) target=$$(date -d "today 02:00" +%s) [ "$${target}" -le "$${now}" ] && target=$$(date -d "tomorrow 02:00" +%s) echo "[$(date '+%F %T')] next backup scheduled at $(date -d "@$${target}" '+%F %T')" sleep $(( target - now )) f="backup_$(date +%Y%m%d_%H%M%S).sql.gz" tmp="/backup/$${f}.tmp" echo "[$(date '+%F %T')] Starting backup: $${f}" # 连接身份取自上面环境变量 PGUSER/PGPASSWORD(无需在命令里再写 -U) if pg_dumpall -h postgres > "$${tmp}" && gzip -f "$${tmp}" && mv "$${tmp}.gz" "/backup/$${f}"; then echo "[$(date '+%F %T')] Backup complete" else echo "[$(date '+%F %T')] Backup FAILED, removing partial file" rm -f "$${tmp}" "$${tmp}.gz" fi find /backup -name "backup_*.sql.gz" -mtime +7 -delete 2>/dev/null || true done # ---- Redis ---- redis: image: docker.m.daocloud.io/redis:7.4.8 container_name: redis restart: unless-stopped ports: - "6379:6379" command: redis-server --requirepass Tongli686^*^ 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.40.0 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 # ---- Jaeger (All-in-One 分布式追踪) ---- jaeger: image: docker.m.daocloud.io/jaegertracing/all-in-one:latest container_name: jaeger restart: unless-stopped ports: - "16686:16686" - "4317:4317" - "4318:4318" - "14250:14250" environment: COLLECTOR_OTLP_ENABLED: "true" COLLECTOR_ZIPKIN_ENABLED: "false" LOG_LEVEL: "info" networks: - redfuture-net # ---- Gitea (Git 代码托管) ---- gitea: image: docker.m.daocloud.io/gitea/gitea:latest container_name: gitea restart: unless-stopped ports: - "3000:3000" - "2222:2222" environment: USER_UID: 1000 USER_GID: 1000 GITEA__server__SSH_PORT: "2222" volumes: - /data/gitea:/data networks: - redfuture-net healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"] interval: 30s timeout: 5s retries: 3 # ---- Gitea CI/CD Runner (act_runner) ---- # host 模式:job 在 runner 容器内直接执行(kubectl/docker 可直接用) # k3s 在 121.37.117.181,经宿主机 systemd 服务 k3s-ssh-tunnel.service # (ssh -L 16443:127.0.0.1:6443) 隧道访问,故 runner 必须与隧道同网络命名空间 gitea-runner: build: context: ./gitea-runner dockerfile: Dockerfile image: redfuture-runner:latest container_name: gitea-runner restart: unless-stopped network_mode: host depends_on: gitea: condition: service_healthy environment: GITEA_INSTANCE_URL: http://127.0.0.1:3000 GITEA_RUNNER_REGISTRATION_TOKEN: 9lGvGJxk7M781IYBWDV0ZuZpXV5RkGKlIpkhRVNs GITEA_RUNNER_NAME: gitea-runner # host 标签:job 直接在 runner 容器内执行,才能使用挂载的 kubectl/kubeconfig GITEA_RUNNER_LABELS: "ubuntu-latest:host" volumes: - /var/run/docker.sock:/var/run/docker.sock - /data/gitea-runner:/data - /data/gitea-runner/bin/kubectl:/usr/local/bin/kubectl - /data/gitea-runner/bin/docker:/usr/local/bin/docker - /data/gitea-runner/.kube/config:/root/.kube/config # dev 宿主机本地 k3s (127.0.0.1:6443),与 181 集群(16443)分开 - /etc/rancher/k3s/k3s.yaml:/root/.kube/k3s-dev.yaml healthcheck: test: ["CMD-SHELL", "test -f /data/.runner"] interval: 30s timeout: 5s retries: 5 # ---- 本地镜像仓库 (CI 构建产物中转,k3s containerd 拉取) ---- # 仅绑定 127.0.0.1,供本机 runner push / k3s containerd pull registry: image: docker.m.daocloud.io/registry:2 container_name: registry restart: unless-stopped ports: - "127.0.0.1:5000:5000" volumes: - /data/registry:/var/lib/registry networks: - redfuture-net # ---- Nginx 反向代理 ---- nginx: build: context: ./nginx-proxy dockerfile: Dockerfile container_name: nginx restart: unless-stopped ports: - "80:80" - "443:443" networks: - redfuture-net # ---- media 运行时基础镜像(ffmpeg/python/node/chromium/hyperframes) ---- media-deps: build: context: ../ dockerfile: deploy/media-deps/Dockerfile image: redfuture-media-deps:latest container_name: media-deps restart: "no" networks: - redfuture-net