mirror of
https://github.com/dataelement/bisheng.git
synced 2026-09-01 04:47:53 +08:00
357 lines
14 KiB
YAML
357 lines
14 KiB
YAML
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 里写 HEALTHCHECK:openfga 官方镜像为 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 官方镜像无 HEALTHCHECK,Compose 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:
|
||
# default:backend / 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:
|
||
# default:nginx 用 `app-proxy` 这个服务名做变量式 upstream 解析
|
||
#(docker/nginx/conf.d/default.conf:65-67),backend 也在这张网上。
|
||
# bisheng-apps:它拿到的 upstream 是应用容器的 bridge IP(design 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
|