Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ ARG PROMETHEUS_MULTIPROC_DIR="/tmp/prometheus"
ARG ACCESS_LOG_LOCATION="/dev/null"
ENV ACCESS_LOG_LOCATION=${ACCESS_LOG_LOCATION} \
PROMETHEUS_MULTIPROC_DIR=${PROMETHEUS_MULTIPROC_DIR} \
DJANGO_SETTINGS_MODULE=app.settings.production
DJANGO_SETTINGS_MODULE=app.settings.production \
APPLICATION_LOGGERS="app_analytics,audit,code_references,common,core,dynamodb,edge_api,environments,features,import_export,integrations,mcp,oauth2_metadata,organisations,projects,segments,task_processor,users,webhooks,workflows"

ARG CI_COMMIT_SHA
RUN echo ${CI_COMMIT_SHA} > /app/CI_COMMIT_SHA && \
Expand All @@ -144,7 +145,7 @@ RUN echo ${CI_COMMIT_SHA} > /app/CI_COMMIT_SHA && \

EXPOSE 8000

ENTRYPOINT ["/app/scripts/run-docker.sh"]
ENTRYPOINT ["flagsmith"]

CMD ["migrate-and-serve"]

Expand Down
17 changes: 17 additions & 0 deletions api/app/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1503,3 +1503,20 @@
},
}
DATABASES["clickhouse"] = _clickhouse_db # type: ignore[assignment]

# Startup verbs (flagsmith-common `flagsmith` entrypoint): which databases each
# role migrates and waits on. Mirrors the per-role gating run-docker.sh applied —
# only databases actually configured are included. `DATABASES` is undefined when
# no `DATABASE_URL` is set (e.g. build-time collectstatic), so guard for that.
_configured_databases = globals().get("DATABASES", {})
FLAGSMITH_MIGRATE_DATABASES = [
alias
for alias in ("default", "analytics", "task_processor", "clickhouse")
if alias in _configured_databases
]
FLAGSMITH_WAIT_FOR_MIGRATIONS_DATABASES = [
alias
for alias in ("default", "analytics", "task_processor")
if alias in _configured_databases
]
FLAGSMITH_STARTUP_COMMANDS = ["bootstrap"]
3 changes: 3 additions & 0 deletions api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ explicit = true

[tool.uv.sources]
flagsmith-private = { index = "flagsmith-pypi-production" }
# TEMPORARY: track the composite startup verbs branch until flagsmith-common ships them.
# TODO: revert to the PyPI release once the entrypoint verbs are released.
flagsmith-common = { git = "https://github.com/Flagsmith/flagsmith-common", branch = "feat/composite-startup-verbs" }
clickhouse-driver = { git = "https://github.com/Flagsmith/clickhouse-driver", branch = "newjson" }
# TODO: Revert to the PyPI release once a version closing
# https://github.com/jayvynl/django-clickhouse-backend/issues/154 is published.
Expand Down
114 changes: 9 additions & 105 deletions api/scripts/run-docker.sh
Original file line number Diff line number Diff line change
@@ -1,108 +1,12 @@
#!/bin/sh
set -e

# common environment variables
ACCESS_LOG_FORMAT=${ACCESS_LOG_FORMAT:-'%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %({origin}i)s %({access-control-allow-origin}o)s'}
APPLICATION_LOGGERS=${APPLICATION_LOGGERS:-"app_analytics,audit,code_references,common,core,dynamodb,edge_api,environments,features,import_export,integrations,mcp,oauth2_metadata,organisations,projects,segments,task_processor,users,webhooks,workflows"}

waitfordb() {
if [ -z "${SKIP_WAIT_FOR_DB}" ]; then
python manage.py waitfordb "$@"
fi
}

migrate () {
waitfordb \
&& python manage.py showmigrations --verbosity 2 \
&& python manage.py migrate --verbosity 2 \
&& python manage.py createcachetable
}
serve() {
# configuration parameters for statsd. Docs can be found here:
# https://docs.gunicorn.org/en/stable/instrumentation.html
export STATSD_PORT=${STATSD_PORT:-8125}
export STATSD_PREFIX=${STATSD_PREFIX:-flagsmith.api}

waitfordb

exec flagsmith start \
--worker-tmp-dir /dev/shm \
--timeout ${GUNICORN_TIMEOUT:-30} \
--workers ${GUNICORN_WORKERS:-3} \
--threads ${GUNICORN_THREADS:-2} \
--access-logfile $ACCESS_LOG_LOCATION \
--access-logformat "$ACCESS_LOG_FORMAT" \
--keep-alive ${GUNICORN_KEEP_ALIVE:-2} \
${STATSD_HOST:+--statsd-host $STATSD_HOST:$STATSD_PORT} \
${STATSD_HOST:+--statsd-prefix $STATSD_PREFIX} \
api
}
run_task_processor() {
waitfordb --waitfor 30 --migrations
if [ -n "$ANALYTICS_DATABASE_URL" ] || [ -n "$DJANGO_DB_NAME_ANALYTICS" ]; then
waitfordb --waitfor 30 --migrations --database analytics
fi
if [ -n "$TASK_PROCESSOR_DATABASE_URL" ] || [ -n "$TASK_PROCESSOR_DATABASE_NAME" ]; then
waitfordb --waitfor 30 --migrations --database task_processor
fi
exec flagsmith start \
--bind 0.0.0.0:8000 \
--access-logfile $ACCESS_LOG_LOCATION \
--access-logformat "$ACCESS_LOG_FORMAT" \
task-processor \
--sleepintervalms ${TASK_PROCESSOR_SLEEP_INTERVAL_MS:-${TASK_PROCESSOR_SLEEP_INTERVAL:-500}} \
--graceperiodms ${TASK_PROCESSOR_GRACE_PERIOD_MS:-20000} \
--numthreads ${TASK_PROCESSOR_NUM_THREADS:-5} \
--queuepopsize ${TASK_PROCESSOR_QUEUE_POP_SIZE:-10}

}
migrate_analytics_db(){
if [ -z "$ANALYTICS_DATABASE_URL" ] && [ -z "$DJANGO_DB_NAME_ANALYTICS" ]; then
return 0
fi
python manage.py migrate --database analytics
}
migrate_task_processor_db(){
if [ -z "$TASK_PROCESSOR_DATABASE_URL" ] && [ -z "$TASK_PROCESSOR_DATABASE_NAME" ]; then
return 0
fi
python manage.py migrate --database task_processor
}
migrate_clickhouse_db(){
if [ -z "$CLICKHOUSE_URL" ] && [ -z "$CLICKHOUSE_HOST" ]; then
return 0
fi
python manage.py migrate --database clickhouse
}
bootstrap(){
python manage.py bootstrap
}
default(){
python manage.py "$@"
}

set -x

if [ "$1" = "migrate" ]; then
migrate
migrate_analytics_db
migrate_task_processor_db
migrate_clickhouse_db
elif [ "$1" = "serve" ]; then
serve
elif [ "$1" = "run-task-processor" ]; then
migrate
migrate_analytics_db
migrate_task_processor_db
migrate_clickhouse_db
run_task_processor
elif [ "$1" = "migrate-and-serve" ]; then
migrate
migrate_analytics_db
migrate_task_processor_db
migrate_clickhouse_db
bootstrap
serve
else
default "$@"
fi
# Container startup is handled by the `flagsmith` entrypoint (flagsmith-common),
# which provides the serve / migrate / run-task-processor / migrate-and-serve
# verbs this script used to implement in shell.
#
# This shim stays for backwards compatibility: anything invoking the script
# path directly (Helm charts, compose files, task definitions) keeps working.
# Prefer calling `flagsmith <verb>` directly; this file can be removed once all
# consumers have migrated.
exec flagsmith "$@"
13 changes: 5 additions & 8 deletions api/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
{
"name": "flagsmith-task-processor",
"command": [
"run-task-processor"
"start",
"task-processor"
],
"portMappings": [
{
Expand All @@ -29,7 +30,7 @@
"interval": 10,
"timeout": 2,
"retries": 5,
"startPeriod": 120
"startPeriod": 30
},
"essential": true,
"environment": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"containerDefinitions": [
{
"name": "flagsmith-task-processor",
"command": ["run-task-processor"],
"command": ["start", "task-processor"],
"portMappings": [
{
"containerPort": 9100,
Expand All @@ -24,7 +24,7 @@
"interval": 10,
"timeout": 2,
"retries": 5,
"startPeriod": 120
"startPeriod": 30
},
"essential": true,
"environment": [
Expand Down
Loading