Flagsmith Docker Compose 部署实战
Flagsmith v2.287.0 Docker Compose 自托管部署实战:flags-only 三服务编排、数据库迁移、控制台初始化、组织/项目/环境与开关切换、SDK 端点验证、超管创建与备份,附官方 Helm Chart 的 Kubernetes 部署形态与九条排障实录,2026-10-28 实测。
Flagsmith Docker Compose 部署实战
目标:在一台 Ubuntu 22.04 服务器上用 Docker Compose 从零部署 Flagsmith v2.287.0 自托管平台(flags-only 形态:统一服务 + 任务处理器 + PostgreSQL),完成数据库迁移、管理控制台初始化、组织/项目/环境创建、特性开关切换与 SDK 端点连通验证、Django 超管创建与数据备份。全部步骤与回显均在 2026-10-28 实测通过;文末附官方 Helm Chart 的 Kubernetes 部署形态溯源小节。
一、环境信息
| 项 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04 LTS(x86_64) |
| Docker / Compose | Docker Engine 24+ / Compose v2(docker compose 子命令) |
| Flagsmith 版本 | v2.287.0(官方统一镜像,2026-10-28 拉取) |
| 数据库 | PostgreSQL 15.5(postgres:15.5-alpine) |
| 部署目录 | /opt/flagsmith |
| 服务端口 | 8142(映射到服务内部 8000) |
| 专用子网 | 10.89.60.0/24 |
| Compose 项目名 | flagsmith-2.287.0-stack |
| 部署形态 | flags-only(不含 Kafka/ClickHouse 实验分析栈) |
| 示例账号 | root@flagsmith.local / admin@flagsmith.local,密码 Q1w2e3r4@2026 |
资源实测参考:API 服务约 583MB、任务处理器约 503MB、PostgreSQL 约 80MB(详见第十章),生产环境建议为该栈预留 ≥2GB 空闲内存。
二、镜像选型说明
Flagsmith 自 v2.x 起采用「统一镜像」交付:官方镜像 flagsmith/flagsmith 同时包含 Django REST API 与 React 管理控制台,通过入口命令 flagsmith 的子命令区分角色(serve API 服务、migrate 数据库迁移、run-task-processor 任务处理器、migrate-and-serve 默认先迁移后服务)。版本选型结论:
| 镜像标签 | 说明 | 选型建议 |
|---|---|---|
flagsmith/flagsmith:latest | 跟随最新稳定版(本次实测即 2.287.0,镜像内置 Gunicorn 23.0.0,拉取内容 116MB) | 快速验证可用,生产不建议 |
flagsmith/flagsmith:2.287.0 | 版本化标签 | 生产固定版本,便于回滚 |
docker.flagsmith.com/flagsmith/flagsmith | 官方自建仓库(官方 Compose 默认引用) | 直连拉取在国内网络实测失败,见第十二章 Q1 |
数据库镜像选官方 Compose 同款 postgres:15.5-alpine(官方编排固定版本,避免 16 大版本兼容性问题)。若需启用 A/B 实验分析,官方完整编排还会追加 Kafka 3.9.1、ClickHouse 25.12 等组件——资源开销显著,无实验需求时选 flags-only 形态(本文即此形态,对应官方仓库 docker-compose.flags-only.yml 的结构)。
三、前置条件
- 服务器已安装 Docker Engine 与 Compose v2,
docker compose version可正常执行。 - 端口 8142 未被占用(
ss -ltn | grep 8142无输出)。 - 内存空闲 ≥2GB(
free -m确认)。 - 如需从外网拉取镜像,确认网络可达(本环境经代理完成下载,见第十二章 Q1 的网络说明)。
四、部署步骤
4.1 创建部署目录与编排文件
mkdir -p /opt/flagsmith && cd /opt/flagsmith
vim docker-compose.yml
写入以下编排文件(依据官方 docker-compose.flags-only.yml 结构按本环境改造:显式子网、宿主端口 8142、固定项目名):
# Flagsmith v2.287.0 自托管(flags-only 形态,参照官方 docker-compose.flags-only.yml)
# 官方原版: https://github.com/Flagsmith/flagsmith/blob/main/docker-compose.flags-only.yml
name: flagsmith-2.287.0-stack
x-flagsmith-env: &flagsmith-env
DATABASE_URL: postgresql://postgres:q1w2e3r4@postgres:5432/flagsmith
USE_POSTGRES_FOR_ANALYTICS: 'true'
ENVIRONMENT: production
DJANGO_ALLOWED_HOSTS: '*'
FLAGSMITH_DOMAIN: localhost:8142
DJANGO_SECRET_KEY: flagsmith-demo-secret-key-2f8d
TASK_RUN_METHOD: TASK_PROCESSOR
PROMETHEUS_ENABLED: 'true'
networks:
flagsmith_net:
driver: bridge
ipam:
config:
- subnet: 10.89.60.0/24
volumes:
pgdata:
services:
postgres:
image: postgres:15.5-alpine
container_name: flagsmith-2.287.0-postgres
environment:
POSTGRES_PASSWORD: q1w2e3r4
POSTGRES_DB: flagsmith
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- flagsmith_net
healthcheck:
test: ['CMD-SHELL', 'pg_isready -d flagsmith -U postgres']
interval: 2s
timeout: 2s
retries: 20
start_period: 20s
migrate-db:
image: flagsmith/flagsmith:latest
container_name: flagsmith-2.287.0-migrate
command: ['migrate']
environment:
<<: *flagsmith-env
networks:
- flagsmith_net
depends_on:
postgres:
condition: service_healthy
api:
image: flagsmith/flagsmith:latest
container_name: flagsmith-2.287.0-api
command: ['serve']
environment:
<<: *flagsmith-env
ports:
- '8142:8000'
networks:
- flagsmith_net
depends_on:
migrate-db:
condition: service_completed_successfully
task-processor:
image: flagsmith/flagsmith:latest
container_name: flagsmith-2.287.0-task-processor
command: ['run-task-processor']
environment:
<<: *flagsmith-env
networks:
- flagsmith_net
depends_on:
migrate-db:
condition: service_completed_successfully
关键点说明:
migrate-db是一次性任务:跑完 Django 迁移即退出,api/task-processor通过condition: service_completed_successfully确保迁移完成后才启动。x-flagsmith-env锚点让三个 Flagsmith 服务共享同一份环境变量,避免漂移。DJANGO_SECRET_KEY多实例必须一致(本文为演示值,生产请换成 50 位以上随机串);DJANGO_ALLOWED_HOSTS生产应收紧为实际域名。
4.2 启动与数据库迁移验证
docker compose up -d
实测回显(首次启动,创建网络/卷 → PostgreSQL 就绪 → 迁移退出 → 双服务启动):
Network flagsmith-22870-stack_flagsmith_net Created
Volume flagsmith-22870-stack_pgdata Created
Container flagsmith-2.287.0-postgres Starting
Container flagsmith-2.287.0-postgres Started
Container flagsmith-2.287.0-postgres Waiting
Container flagsmith-2.287.0-postgres Healthy
Container flagsmith-2.287.0-migrate Starting
Container flagsmith-2.287.0-migrate Started
Container flagsmith-2.287.0-migrate Waiting
Container flagsmith-2.287.0-migrate Exited
Container flagsmith-2.287.0-task-processor Starting
Container flagsmith-2.287.0-api Starting
Container flagsmith-2.287.0-task-processor Started
Container flagsmith-2.287.0-api Started
💡 注意:Compose 会把项目名
flagsmith-2.287.0-stack规范化为小写字母数字(去掉点号),网络/卷实际命名为flagsmith-22870-stack_flagsmith_net、flagsmith-22870-stack_pgdata,属正常现象。
查看迁移任务日志确认建表完成:
docker logs flagsmith-2.287.0-migrate
实测回显(节选,全程共 614 条 Applying ... OK;开头先等数据库就绪,末尾处理完最后一个应用):
2026-10-28T04:13:30.340742Z [info ] Checking if database is ready for connections. [common.core.management.commands.waitfordb] positional_args=()
2026-10-28T04:13:30.352443Z [info ] Successfully connected to the database. [common.core.management.commands.waitfordb] positional_args=()
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying auth.0002_alter_permission_name_max_length... OK
...
Applying workflows_core.0012_alter_changerequest_options... OK
Applying workflows_core.0013_reverse_change_request_ordering... OK
日志中的 axes.W004/axes.W006 是平台内置防暴力破解组件(django-axes)的配置告警,官方镜像自带、不影响功能,见第十二章 Q8。
4.3 服务就绪验证
docker compose ps
curl http://localhost:8142/health
实测回显(compose ps 显示三个 Flagsmith 服务均为内置健康检查的 healthy 状态;/health 返回两行 working):
NAME IMAGE COMMAND SERVICE STATUS PORTS
flagsmith-2.287.0-api flagsmith/flagsmith:latest "flagsmith serve" api Up 19 minutes (healthy) 0.0.0.0:8142->8000/tcp, [::]:8142->8000/tcp
flagsmith-2.287.0-postgres postgres:15.5-alpine "docker-entrypoint.s…" postgres Up 20 minutes (healthy) 5432/tcp
flagsmith-2.287.0-task-processor flagsmith/flagsmith:latest "flagsmith run-task-…" task-processor Up 19 minutes (healthy) 8000/tcp
<!DOCTYPE html>
<html>
<head>
<title>Flagsmith</title>
</head>
<body>
<h1>Working</h1>
<table style="text-align: center;">
<tr>
<td style="text-align: center; background-color: #464646;">
<p style="font-size: 1.2em">DB</p>
</td>
<td style="text-align: center; background-color: #3c763d;">
<p style="font-size: 1.2em">Working</p>
</td>
</tr>
<tr>
<td style="text-align: center; background-color: #464646;">
<p style="font-size: 1.2em">Cache</p>
</td>
<td style="text-align: center; background-color: #3c763d;">
<p style="font-size: 1.2em">Working</p>
</td>
</tr>
</table>
</body>
</html>
API 服务启动日志末尾可见 Gunicorn 工作进程与 Prometheus 指标端点就绪:
2026-10-28T04:14:09.575766Z [info ] Prometheus metrics server started on port 9100 [common.gunicorn.metrics_server] positional_args=(9100,)
2026-10-28T04:14:09.580445Z [info ] Booting worker with pid: 8 [gunicorn.error] positional_args=(8,)
2026-10-28T04:14:09.606369Z [info ] Booting worker with pid: 9 [gunicorn.error] positional_args=(9,)
2026-10-28T04:14:09.679961Z [info ] Booting worker with pid: 10 [gunicorn.error] positional_args=(10,)
4.4 初始化管理控制台(注册首个账号)
浏览器访问 http://<服务器IP>:8142/,进入控制台首页后点 Sign Up 注册首个账号(该账号默认即组织所有者)。本实测通过 REST API 完成等价操作:
curl -s -X POST http://localhost:8142/api/v1/auth/users/ \
-H 'Content-Type: application/json' \
-d '{"email":"admin@flagsmith.local","first_name":"Admin","last_name":"User","password":"Q1w2e3r4@2026"}'
实测回显(key 即会话 Token,后续管理 API 用 Authorization: Token <key> 认证):
{"id":1,"email":"admin@flagsmith.local","first_name":"Admin","last_name":"User","key":"448f55d8eacc1475514de7ab2a71f71081303ef0",...}
⚠️ 注意:注册密码必须通过平台内置强度校验——实测用示例弱口令
q1w2e3r4注册会被拒绝并返回"This password is too common.",改用含大小写+数字+符号的Q1w2e3r4@2026后成功。完整报错回显见第十二章 Q3。
4.5 创建组织、项目与环境
用上一步拿到的会话 Token 依次创建组织与项目:
TOKEN=448f55d8eacc1475514de7ab2a71f71081303ef0
curl -s -X POST http://localhost:8142/api/v1/organisations/ \
-H "Authorization: Token $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"Quzuo Demo Org"}'
实测回显:
{'id': 1, 'name': 'Quzuo Demo Org', 'created_date': '2026-10-28T04:16:02.913385Z', 'stop_serving_flags': False, 'persist_trait_data': True, 'num_seats': 3, 'subscription': {...}, 'require_join': False, 'restrict_project_create_to_admin': False}
curl -s -X POST http://localhost:8142/api/v1/projects/ \
-H "Authorization: Token $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"demo-app","organisation":1,"hide_disabled_flags":false}'
实测回显(精简展示):
{'id': 1, 'name': 'demo-app', 'organisation': 1, 'minimum_change_request_approvals': None}
⚠️ 注意(v2.287.0 实测行为):新版本创建项目后不会自动创建默认环境,查询
GET /api/v1/environments/?project=1在任务处理器处理完成前返回count: 0。需显式创建环境:
curl -s -X POST http://localhost:8142/api/v1/environments/ \
-H "Authorization: Token $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"Development","project":1}'
实测回显(环境创建成功即返回两类 SDK 密钥:api_key 为客户端密钥,server_side_api_key 为 ser. 前缀服务端密钥):
id: 1 | name: Development | api_key(client): TinUTVci4mXtPVbBAyJjvw | server_key: ser.S9JAfMUEgrtrPWmrqrw97E
同法再创建 Production 环境(id=2)。所有环境的密钥后续随时可用 GET /api/v1/environments/?project=1(带 Token)重新查询。
4.6 创建特性开关并切换
# 创建第一个特性(多变量形态,创建时即初始化环境状态)
curl -s -X POST http://localhost:8142/api/v1/projects/1/features/ \
-H "Authorization: Token $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"banner-toggle","description":"首页横幅开关","initial_value":true,"type":"MULTIVARIATE","default_enabled":true,"multivariate_options":[]}'
# 创建第二个特性(普通开关)
curl -s -X POST http://localhost:8142/api/v1/projects/1/features/ \
-H "Authorization: Token $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"checkout-v2","description":"新版结算流程","initial_value":"false","default_enabled":false}'
实测回显:
{'id': 1, 'name': 'banner-toggle', 'description': '首页横幅开关', 'initial_value': True, 'default_enabled': True, 'type': 'MULTIVARIATE', 'multivariate_options': [], 'is_archived': False, 'tags': [], 'owners': None, 'uuid': '2c78d40c-70a2-4377-a30e-6c1cda9a872f'}
{'id': 2, 'name': 'checkout-v2', 'description': '新版结算流程', 'default_enabled': False}
⚠️ 注意:
initial_value字段实测要求字符串("false"/"true"),直接传布尔false会返回 400({'initial_value': ['A valid integer is required.']}之类的校验错误),见第十二章 Q5。
特性在环境中的实际状态由 featurestate 记录承载。查询 Development 环境全部特性状态:
curl -s "http://localhost:8142/api/v1/environments/TinUTVci4mXtPVbBAyJjvw/featurestates/" \
-H "Authorization: Token $TOKEN"
实测回显(节选;feature_state_value 为 {"type": ..., "value": ...} 包装结构):
count: 3
fs_id: 1 | feature: banner-toggle | enabled: True | value: {'type': 'unicode', 'value': None}
fs_id: 2 | feature: checkout-v2 | enabled: False | value: {'type': 'unicode', 'value': 'false'}
把 checkout-v2 在 Development 环境切换为开启(fs_id: 3 为该环境 checkout-v2 的 featurestate id):
curl -s -X PATCH http://localhost:8142/api/v1/environments/TinUTVci4mXtPVbBAyJjvw/featurestates/3/ \
-H "Authorization: Token $TOKEN" -H 'Content-Type: application/json' \
-d '{"enabled":true,"feature_state_value":true}'
实测回显:
fs_id: 3 | enabled: True | value: True | version: 1
4.7 SDK 端点连通验证
用客户端环境密钥请求 SDK 求值接口(X-Environment-Key 请求头认证):
curl -s "http://localhost:8142/api/v1/flags/" \
-H "X-Environment-Key: TinUTVci4mXtPVbBAyJjvw"
实测回显(切换 checkout-v2 为开启后):
[
{
"enabled": true,
"feature_state_value": null,
"feature": {
"id": 2,
"name": "checkout-v2",
"type": "STANDARD"
},
"feature_segment": null
},
{
"enabled": true,
"feature_state_value": null,
"feature": {
"id": 1,
"name": "banner-toggle",
"type": "MULTIVARIATE"
},
"feature_segment": null
}
]
服务端 SDK 的本地求值场景改用 ser. 前缀服务端密钥拉取整份环境文档:
curl -s "http://localhost:8142/api/v1/environment-document/" \
-H "X-Environment-Key: ser.S9JAfMUEgrtrPWmrqrw97E"
实测回显(结构精简):
api_key: ser.S9JAfMUEgrtrPWmrqrw97E
project: demo-app | env: Development
- banner-toggle | enabled: True | value: None
- checkout-v2 | enabled: True | value: True
- another-flag | enabled: False | value: None
至此控制台初始化与开关链路全部打通。分段(Segment)圈人、身份级求值等进阶用法见本系列运维实战篇。
4.8 创建 Django 超管(Admin 后台)
Flagsmith 保留 Django Admin 后台(/admin/),用于核心数据表 CRUD。用 createsuperuser --noinput 非交互创建(密码经 DJANGO_SUPERUSER_PASSWORD 注入):
docker exec flagsmith-2.287.0-api sh -c \
"cd /app && DJANGO_SUPERUSER_PASSWORD='Q1w2e3r4@2026' \
python manage.py createsuperuser --noinput \
--email root@flagsmith.local --first_name Root --last_name Admin \
--sign_up_type NO_INVITE"
实测回显(成功创建无输出、退出码 0;若缺参数会报错,见第十二章 Q6)。
浏览器访问 http://<服务器IP>:8142/admin/,用 root@flagsmith.local / Q1w2e3r4@2026 登录即可。用 curl 脚本模拟登录会因 CSRF 校验被拒(403,见第十二章 Q7),属预期安全行为。
4.9 数据库备份
mkdir -p /opt/flagsmith/backup
docker exec flagsmith-2.287.0-postgres \
pg_dump -U postgres -d flagsmith > /opt/flagsmith/backup/flagsmith_20261028.sql
ls -lh /opt/flagsmith/backup/flagsmith_20261028.sql
实测回显(产物头部为 PostgreSQL 标准转储头):
--
-- PostgreSQL database dump
--
-- Dumped from database version 15.5
-- Dumped by pg_dump version 15.5 (Debian 15.5-1.pgdg120+1)
-rw-r--r-- 1 root root 646K Oct 28 04:40 /opt/flagsmith/backup/flagsmith_20261028.sql
数据段完整性用 COPY 语句数核对:
grep -c "^COPY" /opt/flagsmith/backup/flagsmith_20261028.sql
169
(备份策略与恢复演练详见本系列运维实战篇。)
五、数据持久化说明
| 数据 | 落盘位置 | 说明 |
|---|---|---|
| 全部业务数据 | 命名卷 flagsmith-22870-stack_pgdata → PostgreSQL 数据目录 | 组织/项目/环境/开关/身份/分段全部在库 |
| 开关分析数据 | 同上(USE_POSTGRES_FOR_ANALYTICS: 'true') | 未启用时存内存,重启丢失 |
| 控制台静态资源 | 镜像内置 | 无需挂载 |
要点:
- 首次启动执行
docker compose up时自动完成建库迁移;官方文档明确「升级时由 Django Migrations 自动执行结构变更」,升级仅需换镜像标签重启(migrate-db服务会自动补跑增量迁移)。 - 销毁数据用
docker compose down -v(会删除卷),仅停服用docker compose down。 - 备份以
pg_dump为主,恢复cat xxx.sql | docker exec -i <postgres> psql -U postgres -d flagsmith。
六、环境变量表
本编排涉及的环境变量(完整体系详见本系列配置参数篇,此处列部署强相关项):
| 变量 | 本编排取值 | 说明 |
|---|---|---|
DATABASE_URL | postgresql://postgres:q1w2e3r4@postgres:5432/flagsmith | 数据库连接串,唯一强依赖 |
DJANGO_SECRET_KEY | flagsmith-demo-secret-key-2f8d(演示值) | 会话/加密基钥,多实例必须一致,生产换强随机值 |
DJANGO_ALLOWED_HOSTS | * | Host 头白名单,生产收紧为实际域名 |
FLAGSMITH_DOMAIN | localhost:8142 | 对外访问域名/端口(构造绝对链接用) |
ENVIRONMENT | production | 运行模式标记 |
USE_POSTGRES_FOR_ANALYTICS | 'true' | API 调用/开关分析数据落 PostgreSQL |
TASK_RUN_METHOD | TASK_PROCESSOR | 异步任务交给独立 task-processor 服务 |
PROMETHEUS_ENABLED | 'true' | 开启 :9100 指标端点 |
POSTGRES_PASSWORD / POSTGRES_DB | q1w2e3r4 / flagsmith | 数据库镜像初始化参数,须与 DATABASE_URL 匹配 |
ALLOW_REGISTRATION_WITHOUT_INVITE | 未设置(默认开放注册) | 封闭场景可禁邀请注册 |
PREVENT_SIGNUP | 未设置 | 设 'true' 完全关闭注册入口 |
七、配置参数说明
编排文件中与稳定性直接相关的参数逐项解释:
healthcheck(postgres):pg_isready -d flagsmith -U postgres,2 秒间隔/20 次重试/20 秒缓冲,保证迁移在库真正就绪后才执行——Flagsmith 服务本身还带镜像内置健康检查(compose ps可见 healthy),探活 URL 即/health的库/缓存自检逻辑。depends_on条件:service_healthy(等库就绪)与service_completed_successfully(等迁移成功)两级串联,避免「库没起就迁移」「没迁移就服务」两类经典启动竞态。ports: '8142:8000':统一服务同时承载控制台与 API/SDK,只需暴露这一个端口;task-processor无需对外端口。ipam.subnet: 10.89.60.0/24:显式子网避免与宿主机网段及其他栈冲突,多套栈并存时按 10.89.x.x 依次错开。name: flagsmith-2.287.0-stack:固定项目名,保证卷/网络命名稳定(点号会被规范化为空,见 4.2 提示)。
八、配置文件挂载
flags-only 形态无需挂载任何配置文件——全部配置经环境变量注入(Django 侧 DATABASE_URL、DJANGO_SECRET_KEY 等),这是 Flagsmith 官方推荐的配置方式。需要挂载的典型场景只有两类:
- TLS 反向代理:在编排中追加 Nginx/Caddy 服务并挂载证书目录,对外 443、对内转发 8000,同时把
DJANGO_ALLOWED_HOSTS、FLAGSMITH_DOMAIN改为真实域名(官方文档「Access Flagsmith Remotely」章节推荐的正是反代 + 环境变量组合)。 - 自定义字体等静态资源:控制台支持经
FLAGSMITH_FRONTEND_BASE相关变量与挂载定制品牌资源,一般部署用不到。
九、等价 docker run(单机快速验证)
无编排文件时,可用两条命令拉起最小可用验证环境(与上文编排等价的简化形态,数据不持久化,仅供冒烟):
docker network create flagsmith-smoke
docker run -d --name flagsmith-smoke-db \
--network flagsmith-smoke \
-e POSTGRES_PASSWORD=q1w2e3r4 -e POSTGRES_DB=flagsmith \
postgres:15.5-alpine
docker run -d --name flagsmith-smoke-app \
--network flagsmith-smoke -p 8142:8000 \
-e DATABASE_URL=postgresql://postgres:q1w2e3r4@flagsmith-smoke-db:5432/flagsmith \
-e DJANGO_SECRET_KEY=flagsmith-demo-secret-key-2f8d \
-e DJANGO_ALLOWED_HOSTS='*' \
-e FLAGSMITH_DOMAIN=localhost:8142 \
-e ENVIRONMENT=production \
flagsmith/flagsmith:latest migrate-and-serve
migrate-and-serve 是镜像默认子命令:先执行迁移再启动服务,等待数据库就绪的重试由 waitfordb 内置完成。生产部署仍以第四章 Compose 编排为准(含任务处理器与显式健康检查)。
十、常用运维命令
# 状态与健康
docker compose ps
curl -s http://localhost:8142/health | grep -o '<p style="font-size: 1.2em">Working</p>'
# 日志
docker compose logs -f api
docker compose logs task-processor | tail -50
# 重启与更新版本(示例:升级镜像标签后)
docker compose pull && docker compose up -d
# 扩容 API 实例(无状态,可横向扩)
docker compose up -d --scale api=2
# 数据库直连
docker exec -it flagsmith-2.287.0-postgres psql -U postgres -d flagsmith
# 停止与彻底清理
docker compose down
docker compose down -v # 连同数据卷一起删除(危险)
资源占用实测(docker stats --no-stream,空载稳定状态):
flagsmith-2.287.0-api: CPU 0.11% MEM 583.5MiB / 15.36GiB
flagsmith-2.287.0-task-processor: CPU 0.09% MEM 503.5MiB / 15.36GiB
flagsmith-2.287.0-postgres: CPU 0.01% MEM 80.1MiB / 15.36GiB
任务处理器空闲时表现为常驻轮询(每分钟拉取待执行任务,日志为周期性循环输出),属正常现象。
十一、Kubernetes 部署形态(官方 Helm Chart)
本节为联网溯源内容:以下信息均来自 Flagsmith 官方文档与官方 Chart 仓库(查询日期 2026-10-28),本批次未做集群实测(集群实测由 K1 批次另行开展,请勿将本节视为实测结论)。
Flagsmith 官方维护 Helm Chart(仓库 Flagsmith/flagsmith-charts,Chart Museum 地址 https://flagsmith.github.io/flagsmith-charts/ ),2026-10-28 实查版本为 chart 0.85.0、appVersion: 2.286.0。标准接入方式:
helm repo add flagsmith https://flagsmith.github.io/flagsmith-charts/
helm repo update
helm install flagsmith flagsmith/flagsmith -f values.yaml
官方 Chart 的架构事实(源自 Chart 源码与官方 K8s 文档):
- 组件拓扑:默认
allInOne: true—— API 与前端合并为单个frontendDeployment(flagsmith.allInOneDeployment);taskProcessorDeployment 独立。设置separateApiAndFrontend: true可拆分为frontend+api两个 Deployment。 - 数据库:默认捆绑 Bitnami PostgreSQL 子 Chart(依赖
postgresql12.5.8,别名devPostgresql,官方标注仅开发用途);生产用databaseExternal.enabled=true+databaseExternal.url指向外部 PostgreSQL(官方文档给出以 K8s Secret 组装 URL 的示例)。 - 密钥管理:
secretKey(即DJANGO_SECRET_KEY)通过existingSecret/existingSecretKey引用 Secret,或由 Chart 生成;官方升级注意事项特别提示 chart 0.12.0 起该值变更路径,升级前必须显式固定,否则会话失效。 - 暴露方式:Chart 内置 Ingress 资源(
ingress.enabled),可选 cert-manager 注解;frontend.ingress.url/api.ingress.url分别指定前端与 API 域名(合并部署时同一域名)。 - 副本与资源建议(官方 values 默认值):
allInOne.replicas: 2、api.replicas: 4、taskProcessor.replicas: 2;官方文档「Sizing and Scaling」给出每 pod 建议基线 1 vCPU / 2GB 内存,API 扩容无状态可直接横向加副本。 - 可观测:Chart 预置 Prometheus 指标与 ServiceMonitor 支持(
serviceMonitor.enabled),自托管仓库的参考示例即以 kube-prometheus-stack 抓取 API 与 task processor 指标。 - 企业镜像:
flagsmith.flagsmith-frontend/flagsmith.flagsmith-api镜像默认docker.flagsmith.com/flagsmith/flagsmith:2.286.0(Enterprise 渠道),社区可改回 Docker Hub 官方镜像。
选型结论:单机/中小规模用本文 Compose 形态即可;多团队共享、需要滚动升级/HPA/Ingress 体系时走官方 Helm Chart,且两者数据模型一致(PostgreSQL 单库),迁移成本低。
十二、常见问题(排障实录)
以下问题全部在本次部署实测中真实遇到,回显为原始报错。
Q1:拉取 docker.flagsmith.com/flagsmith/flagsmith:latest 报「no such host」。
实测报错(官方 Compose 文件默认引用官方自建仓库,国内网络直连解析失败):
Error response from daemon: Get "https://docker.flagsmith.com/v2/": dial tcp: lookup docker.flagsmith.com: no such host
解法:改用 Docker Hub 官方同名镜像 flagsmith/flagsmith(本环境经代理 192.168.1.62:7897 拉取,版本标签一致,镜像 OCI 标签确认 org.opencontainers.image.version=2.287.0)。生产可自行同步镜像到私有仓库。
Q2:docker compose up 报端口冲突。
实测报错(本环境 8140 被同机其他栈占用):
Error response from daemon: driver failed programming external connectivity on endpoint flagsmith-2.287.0-api: Bind for 0.0.0.0:8140 failed: port is already allocated
解法:ss -ltn | grep <端口> 先确认,再改编排端口映射(本实录最终使用 8142)。多套栈并存时端口规划先行。
Q3:注册接口拒绝弱密码。
实测报错(POST /api/v1/auth/users/,密码 q1w2e3r4):
{'password': ["This password is too common."]}
解法:改用满足强度要求的密码(大小写+数字+符号,如 Q1w2e3r4@2026)。平台内置 Django 密码校验器,q1w2e3r4 命中「常见密码」规则被拒。
Q4:创建项目后查不到环境。
实测现象:POST /api/v1/projects/ 返回 201,随后 GET /api/v1/environments/?project=1 返回 {'count': 0, ...},且任务处理器启动日志同时出现启动横幅。解法:v2.287.0 项目创建不保证自动建环境,显式 POST /api/v1/environments/ 创建(见 4.5),创建返回体即含客户端/服务端两类密钥。
Q5:创建特性时 initial_value 传布尔报 400。
实测报错(initial_value: false):
{'initial_value': ['A valid integer is required.']}
解法:该字段按字符串传("false"/"true"/数值字符串),平台内部按特性值类型解释。改传 "false" 后创建成功(见 4.6)。
Q6:createsuperuser --noinput 缺参数报错。
实测报错(v2.287.0 的用户模型为全名制 + 注册类型必填):
CommandError: You must use --noinput or --username and --email with --noinput, --first_name and --last_name and --sign_up_type with --noinput.
解法:完整参数形如 4.8 示例:--email、--first_name、--last_name、--sign_up_type NO_INVITE 加 DJANGO_SUPERUSER_PASSWORD 环境变量。若超管账号与普通账号同邮箱,也可直接把既有用户提升:is_staff=True; is_superuser=True(manage.py shell 两行)。
Q7:curl 模拟 /admin/ 登录 403。
实测报错(POST /admin/login/):
403 Forbidden — CSRF cookie not set.
原因:Django Admin 对 CSRF 校验严格,且登录页 cookie 是 Secure/会话级,curl 裸模拟拿不到合法 CSRF token;另平台内置 django-axes 防爆破,多次失败会触发锁定告警。解法:浏览器正常登录即可;脚本化验证可用 manage.py shell 内的 django.test.Client().login(...)(实测返回 login ok: True 并成功 GET /admin/),或走管理 REST API(Token 认证)。
Q8:启动日志出现 axes.W004 / axes.W006 告警。
实测回显:
?: (axes.W004) You have a deprecated setting AXES_ONLY_USER_FAILURES configured in your project settings
?: (axes.W006) AXES_LOCKOUT_PARAMETERS does not contain 'ip_address'. This configuration allows attackers to bypass rate limits by rotating User-Agents or Cookies.
原因:官方镜像内置 django-axes 的默认配置沿用了旧参数名,属上游已知告警,功能不受影响。公网暴露时建议在反代层叠加限流,不要尝试在环境变量里「修」这两个告警(属代码内配置)。
Q9:照官方文档克隆 Flagsmith/self-hosted 仓库后发现不是 Compose 工程。
现象:官方文档「Deployment → Docker」开头引导 git clone https://github.com/Flagsmith/self-hosted.git && docker-compose up,但该仓库 main 分支当前是「Flagsmith Enterprise 的 Kubernetes/Helmfile 参考示例」。解法:自托管 Compose 的权威来源改用主仓库根目录的 docker-compose.yml / docker-compose.flags-only.yml(本文编排即基于后者),文档滞后问题已在本文成文时点(2026-10-28)核实。
十三、参考链接
- 官方 Docker 部署文档:https://docs.flagsmith.com/deployment/docker
- 官方 Compose 编排(flags-only):https://raw.githubusercontent.com/Flagsmith/flagsmith/main/docker-compose.flags-only.yml
- 官方 Compose 编排(完整含实验栈):https://raw.githubusercontent.com/Flagsmith/flagsmith/main/docker-compose.yml
- API 环境变量清单:https://docs.flagsmith.com/deployment/hosting/locally-api
- 前端环境变量清单:https://docs.flagsmith.com/deployment/hosting/locally-frontend
- Kubernetes/Helm 部署文档:https://docs.flagsmith.com/deployment/hosting/kubernetes
- 官方 Helm Chart:https://github.com/Flagsmith/flagsmith-charts
- Gunicorn 环境变量(Workers/Threads/Timeout/Access Log):https://docs.flagsmith.com/deployment/docker#environment-variables
- 本系列姊妹篇:《Flagsmith 介绍与选型指南》、《Flagsmith 配置参数详解》、《Flagsmith 常用命令与运维实战》