Files
bisheng/docker/docker-compose.yml
T
2026-08-27 20:15:39 +08:00

357 lines
14 KiB
YAML
Raw 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.
services:
mysql:
container_name: bisheng-mysql
image: mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "1234" # 数据库密码,如果修改需要同步修改bisheng/congfig/config.yaml配置database_url的mysql连接密码
MYSQL_DATABASE: bisheng
TZ: Asia/Shanghai
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/mysql/conf/my.cnf:/etc/mysql/my.cnf
- ${DOCKER_VOLUME_DIRECTORY:-.}/mysql/data:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "mysql -u root -p$$MYSQL_ROOT_PASSWORD -e 'CREATE DATABASE IF NOT EXISTS openfga;'"]
start_period: 30s
interval: 20s
timeout: 10s
retries: 4
restart: on-failure
openfga-migrate:
container_name: bisheng-openfga-migrate
# Formal deployments set OPENFGA_IMAGE to the reviewed v1.15.1 tag@digest.
# The default remains version-pinned for local development; ``latest`` is forbidden.
image: ${OPENFGA_IMAGE:-openfga/openfga:v1.15.1}
command: migrate
environment:
OPENFGA_DATASTORE_ENGINE: mysql
OPENFGA_DATASTORE_URI: "root:1234@tcp(mysql:3306)/openfga?parseTime=true"
depends_on:
mysql:
condition: service_healthy
openfga:
container_name: bisheng-openfga
image: ${OPENFGA_IMAGE:-openfga/openfga:v1.15.1}
command: run
environment:
OPENFGA_DATASTORE_METRICS_ENABLED: "true"
OPENFGA_DATASTORE_ENGINE: mysql
OPENFGA_DATASTORE_URI: "root:1234@tcp(mysql:3306)/openfga?parseTime=true"
OPENFGA_LOG_FORMAT: json
OPENFGA_PLAYGROUND_ENABLED: "true"
OPENFGA_CHECK_QUERY_CACHE_ENABLED: "true"
OPENFGA_CHECK_QUERY_CACHE_TTL: 30s
OPENFGA_CHECK_ITERATOR_CACHE_ENABLED: "true"
OPENFGA_CHECK_ITERATOR_CACHE_TTL: 30s
OPENFGA_CHECK_ITERATOR_CACHE_MAX_RESULTS: 10000
OPENFGA_CACHE_CONTROLLER_ENABLED: "true"
OPENFGA_CACHE_CONTROLLER_TTL: 10s
OPENFGA_DATASTORE_MAX_OPEN_CONNS: 80
OPENFGA_DATASTORE_MAX_IDLE_CONNS: 40
OPENFGA_METRICS_ENABLE_RPC_HISTOGRAMS: "true"
OPENFGA_RESOLVE_NODE_LIMIT: "${OPENFGA_RESOLVE_NODE_LIMIT:-25}"
OPENFGA_LIST_OBJECTS_MAX_RESULTS: 1000
ports:
- "8080:8080"
- "8081:8081"
- "2112:2112"
depends_on:
openfga-migrate:
condition: service_completed_successfully
# 不在 compose 里写 HEALTHCHECKopenfga 官方镜像为 distroless,无 /bin/sh、无 wget
# CMD-SHELL 会永久 unhealthy。未定义时 Compose 将 ``service_healthy`` 视为已启动即可。
restart: unless-stopped
redis:
container_name: bisheng-redis
image: redis:7.0.4
ports:
- "6379:6379"
environment:
TZ: Asia/Shanghai
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data/redis:/data
- ${DOCKER_VOLUME_DIRECTORY:-.}/redis/redis.conf:/etc/redis.conf
command: redis-server /etc/redis.conf
healthcheck:
test: ["CMD-SHELL", 'redis-cli ping|grep -e "PONG\|NOAUTH"']
interval: 10s
timeout: 5s
retries: 3
restart: on-failure
backend:
container_name: bisheng-backend
image: dataelement/bisheng-backend:v3.0.0-beta1
ports:
- "7860:7860"
environment:
TZ: Asia/Shanghai
BS_SSO_SYNC__GATEWAY_HMAC_SECRET: "bisheng-local-hmac-20260422"
BS_MILVUS_CONNECTION_ARGS: '{"host":"milvus","port":"19530","user":"","password":"","secure":false}'
BS_MILVUS_IS_PARTITION: 'true'
BS_MILVUS_PARTITION_SUFFIX: '1'
BS_ELASTICSEARCH_URL: 'http://elasticsearch:9200'
BS_ELASTICSEARCH_SSL_VERIFY: '{}' # 可根据自己部署的密码进行配置 '{"basic_auth": ("elastic", "elastic")}'
BS_MINIO_SCHEMA: 'false'
BS_MINIO_CERT_CHECK: 'false'
BS_MINIO_ENDPOINT: 'minio:9000'
BS_MINIO_SHAREPOINT: 'minio:9000'
BS_MINIO_ACCESS_KEY: 'minioadmin'
BS_MINIO_SECRET_KEY: 'minioadmin'
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/bisheng/config/config.yaml:/app/bisheng/config.yaml
- ${DOCKER_VOLUME_DIRECTORY:-.}/bisheng/entrypoint.sh:/app/entrypoint.sh
- ${DOCKER_VOLUME_DIRECTORY:-.}/data/bisheng:/app/data
security_opt:
- seccomp:unconfined
command: sh entrypoint.sh api # 启动api服务
restart: on-failure
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7860/health"]
start_period: 30s
interval: 90s
timeout: 30s
retries: 3
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
# openfga 官方镜像无 HEALTHCHECKCompose v5 无法用 service_healthy
openfga:
condition: service_started
backend_worker:
container_name: bisheng-backend-worker
image: dataelement/bisheng-backend:v3.0.0-beta1
environment:
TZ: Asia/Shanghai
BS_SSO_SYNC__GATEWAY_HMAC_SECRET: "bisheng-local-hmac-20260422"
BS_MILVUS_CONNECTION_ARGS: '{"host":"milvus","port":"19530","user":"","password":"","secure":false}'
BS_MILVUS_IS_PARTITION: 'true'
BS_MILVUS_PARTITION_SUFFIX: '1'
BS_ELASTICSEARCH_URL: 'http://elasticsearch:9200'
BS_ELASTICSEARCH_SSL_VERIFY: '{}' # 可根据自己部署的密码进行配置 '{"basic_auth": ("elastic", "elastic")}'
BS_MINIO_SCHEMA: 'false'
BS_MINIO_CERT_CHECK: 'false'
BS_MINIO_ENDPOINT: 'minio:9000'
BS_MINIO_SHAREPOINT: 'minio:9000'
BS_MINIO_ACCESS_KEY: 'minioadmin'
BS_MINIO_SECRET_KEY: 'minioadmin'
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/bisheng/config/config.yaml:/app/bisheng/config.yaml
- ${DOCKER_VOLUME_DIRECTORY:-.}/bisheng/entrypoint.sh:/app/entrypoint.sh
- ${DOCKER_VOLUME_DIRECTORY:-.}/data/bisheng:/app/data
security_opt:
- seccomp:unconfined
command: sh entrypoint.sh worker # 启动celery的异步worker服务,用来处理一些耗时的任务
restart: on-failure
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
openfga:
condition: service_started
frontend:
container_name: bisheng-frontend
image: dataelement/bisheng-frontend:v3.0.0-beta1
ports:
- "3001:3001"
environment:
TZ: Asia/Shanghai
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/nginx/nginx.conf:/etc/nginx/nginx.conf
- ${DOCKER_VOLUME_DIRECTORY:-.}/nginx/conf.d:/etc/nginx/conf.d
restart: on-failure
depends_on:
- backend
elasticsearch:
container_name: bisheng-es
image: docker.io/bitnamilegacy/elasticsearch:8.12.0
user: root
ports:
- "9200:9200"
- "9300:9300"
environment:
TZ: Asia/Shanghai
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data/es:/bitnami/elasticsearch/data
restart: on-failure
etcd:
container_name: bisheng-milvus-etcd
image: quay.io/coreos/etcd:v3.5.5
environment:
ETCD_AUTO_COMPACTION_MODE: revision
ETCD_AUTO_COMPACTION_RETENTION: "1000"
ETCD_QUOTA_BACKEND_BYTES: "4294967296"
ETCD_SNAPSHOT_COUNT: "50000"
TZ: Asia/Shanghai
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data/milvus-etcd:/etcd
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
restart: on-failure
healthcheck:
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 30s
timeout: 20s
retries: 3
minio:
container_name: bisheng-milvus-minio
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
ports:
- "9100:9000"
- "9101:9001"
volumes:
- /etc/localtime:/etc/localtime:ro
- ${DOCKER_VOLUME_DIRECTORY:-.}/data/milvus-minio:/minio_data
command: minio server /minio_data --console-address ":9001"
restart: on-failure
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
milvus:
container_name: bisheng-milvus-standalone
image: milvusdb/milvus:v2.5.10
command: ["milvus", "run", "standalone"]
security_opt:
- seccomp:unconfined
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
volumes:
- /etc/localtime:/etc/localtime:ro
- ${DOCKER_VOLUME_DIRECTORY:-.}/data/milvus:/var/lib/milvus
restart: on-failure
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
start_period: 90s
interval: 30s
timeout: 20s
retries: 3
ports:
- "19530:19530"
- "9091:9091"
depends_on:
- etcd
- minio
# ── 应用工场运行时层(F054 T074)────────────────────────────────────
# 两个 service 都挂在 `app-runtime` profile 后面:**「整层不装」是产品明确
# 支持的形态**GOV-10 / AC-59)。不带 --profile app-runtime 启动时它们根本
# 不创建,平台其余部分零变化——这正是 nginx 的 `location /apps/` 必须用
# 变量式 upstream 的原因(静态主机名解析不了会让 nginx 整个起不来)。
#
# 两者都**不 publish 端口**:外部流量一律经 frontend 的 nginx 进来。
runtime-manager:
container_name: bisheng-runtime-manager
profiles: [app-runtime]
build:
context: ../src/runtime-manager
environment:
TZ: Asia/Shanghai
RTM_HOST: '0.0.0.0'
RTM_PORT: '8091'
# 必须与 backend 的 app_runtime.manager_hmac_secret 一致。不一致的症状是
# 所有编排意图被回 401,而 backend 会把它折叠成 16121「编排器不可用」——
# 排查时容易误判成 dockerd 挂了。
RTM_HMAC_SECRET: ${BISHENG_RTM_HMAC_SECRET:-}
# ⚠️ 这两个变量指的是**同一个目录的两种视角**,必须同时给。
# RTM_DATA_ROOT = 本容器内看到的路径(进程自己 mkdir/chown/读写用)
# RTM_HOST_DATA_ROOT = 宿主上看到的路径(交给宿主 dockerd 做 bind 用)
# runtime-manager 通过 docker.sock 让**宿主 dockerd** 创建应用容器,
# HostConfig.Binds 由宿主解释;只给 RTM_DATA_ROOT 的话宿主会在
# /app-data/... 凭空建一个空目录,应用照样起、探活照样过,只是它的
# SQLite 落在谁也不看的地方。systemd 形态两者相同,所以那边可以不设。
RTM_DATA_ROOT: /app-data
RTM_HOST_DATA_ROOT: ${BISHENG_APP_DATA_ROOT:-/opt/bisheng/app-data}
volumes:
- /etc/localtime:/etc/localtime:ro
# 这是全平台唯一被允许挂 docker socket 的地方(arch-guard RULE-10 的另一
# 半:backend 编译期与运行期都不得持有编排访问面)。D2-B 的
# docker-socket-proxy 变体是 Wave 4 的事,届时只改 RTM_DOCKER_HOST。
- /var/run/docker.sock:/var/run/docker.sock
# 源路径写成与 RTM_HOST_DATA_ROOT **逐字相同的表达式**,这样两者不可能漂移。
# 不能沿用 ${DOCKER_VOLUME_DIRECTORY:-.}:它默认是相对路径 `.`compose 自己
# 会相对本文件解析,但作为环境变量原样传进去后 dockerd 只接受绝对路径。
- ${BISHENG_APP_DATA_ROOT:-/opt/bisheng/app-data}:/app-data
networks:
# defaultbackend / app-proxy 靠服务名找它。
# bisheng-apps:启动探活是 manager 进程**直接 HTTP 访问应用容器在该网络上的
# bridge IP**probe.py:95),不在这张网上就永远探不通。
- default
- bisheng-apps
restart: on-failure
app-proxy:
container_name: bisheng-app-proxy
profiles: [app-runtime]
build:
context: ../src/app-proxy
environment:
TZ: Asia/Shanghai
APP_PROXY_HOST: '0.0.0.0'
APP_PROXY_PORT: '8090'
# ⚠️ 变量名以 app_proxy/config.py 顶部的契约表为准,**不要照猜**。曾经写成
# APP_PROXY_BACKEND_BASE_URL / APP_PROXY_HMAC_SECRET:进程照常启动、容器
# healthy,但两个 base 都停在 127.0.0.1 默认值、两个密钥都是空串(fail
# closed),于是**每个请求都渲染「暂时无法访问」**。同样的坑 systemd 那份
# 单元文件(features/v3.0.0/054-app-domain-runtime/deploy/)里逐字记着。
APP_PROXY_BACKEND_BASE: 'http://backend:7860'
APP_PROXY_MANAGER_BASE: 'http://runtime-manager:8091'
# 与 backend 的 app_runtime.proxy_hmac_secret 一致。
APP_PROXY_BACKEND_SECRET: ${BISHENG_APP_PROXY_HMAC_SECRET:-}
# 与 backend 的 app_runtime.manager_hmac_secret 一致 = runtime-manager 的
# RTM_HMAC_SECRET,同一把密钥,别再生成第二个。
APP_PROXY_MANAGER_SECRET: ${BISHENG_RTM_HMAC_SECRET:-}
volumes:
- /etc/localtime:/etc/localtime:ro
networks:
# defaultnginx 用 `app-proxy` 这个服务名做变量式 upstream 解析
#docker/nginx/conf.d/default.conf:65-67),backend 也在这张网上。
# bisheng-apps:它拿到的 upstream 是应用容器的 bridge IPdesign D5.1),
# 跨 bridge 网络会被 docker 的隔离规则丢包,必须同网。
- default
- bisheng-apps
# 每个请求都要向 backend 问一次入口判定(3s 缓存 × 30s 宽限)。
# runtime-manager 是路由表的唯一真相(design D5.1),一起排序。
depends_on:
- backend
- runtime-manager
restart: on-failure
# 刻意**不挂** docker socket:它只做解析路由 / 剥头 / 注入身份 / 转发,
# 给它编排权限是纯粹的权限扩散。
# ── 托管应用专用网络 ────────────────────────────────────────────────────
# runtime-manager 只**读**这张网(docker_backend.py:161-166「网络由部署方创建」),
# 它绝不自己建——一个会偷偷建网的编排器会把"新机器上第一次发布必挂"这件事藏起来。
# 那么 compose 形态下的"部署方"就是这个文件。
#
# `name:` 必须显式写死:compose 默认会加项目名前缀(docker_bisheng-apps),而
# runtime-manager 是用裸 Docker API 建应用容器的,NetworkMode 取的是
# RTM_NETWORK / DEFAULT_NETWORK = `bisheng-apps` 这个真名,对不上就 404 network
# not found,每次 deploy 都失败。
#
# 两个 service 都显式列了 `networks:`,这是有意的:一旦给 service 写了 networks
# 它就**不再自动接 default**,而 nginx→app-proxy、backend→runtime-manager 都靠
# default 上的服务名解析,所以两张网都得列上。
networks:
bisheng-apps:
name: bisheng-apps
driver: bridge