Skip to content

Commit

Permalink
feat: Support Aptible deployments (#4340)
Browse files Browse the repository at this point in the history
  • Loading branch information
rolodato authored Aug 12, 2024
1 parent b1d49a6 commit 3b47ae0
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 4 deletions.
3 changes: 3 additions & 0 deletions api/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
re_path(r"^api/v2/", include("api.urls.v2", namespace="api-v2")),
re_path(r"^admin/", admin.site.urls),
re_path(r"^health", include("health_check.urls", namespace="health")),
# Aptible health checks must be on /healthcheck and cannot redirect
# see https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks
path("healthcheck", include("health_check.urls", namespace="health")),
re_path(r"^version", views.version_info, name="version-info"),
re_path(
r"^sales-dashboard/",
Expand Down
1 change: 1 addition & 0 deletions api/core/management/commands/waitfordb.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def handle(
database: str,
**options: Any,
) -> None:

start = time.monotonic()
wait_between_checks = 0.25

Expand Down
14 changes: 10 additions & 4 deletions api/scripts/run-docker.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
#!/bin/sh
set -e

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

function migrate () {
python manage.py waitfordb && python manage.py migrate && python manage.py createcachetable
waitfordb && python manage.py migrate && python manage.py createcachetable
}
function 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}

python manage.py waitfordb
waitfordb

exec gunicorn --bind 0.0.0.0:8000 \
--worker-tmp-dir /dev/shm \
Expand All @@ -26,9 +32,9 @@ function serve() {
app.wsgi
}
function run_task_processor() {
python manage.py waitfordb --waitfor 30 --migrations
waitfordb --waitfor 30 --migrations
if [[ -n "$ANALYTICS_DATABASE_URL" || -n "$DJANGO_DB_NAME_ANALYTICS" ]]; then
python manage.py waitfordb --waitfor 30 --migrations --database analytics
waitfordb --waitfor 30 --migrations --database analytics
fi
RUN_BY_PROCESSOR=1 exec python manage.py runprocessor \
--sleepintervalms ${TASK_PROCESSOR_SLEEP_INTERVAL:-500} \
Expand Down
75 changes: 75 additions & 0 deletions docs/docs/deployment/hosting/aptible.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: Aptible
---

## Prerequisites

The options and health check routes described in this document are available from Flagsmith 2.130.0.

## Configuration

Running Flagsmith on Aptible requires some configuration tweaks because of how Aptible's application lifecycle works:

- Don't wait for the database to be available before the Flagsmith API starts. You can do this by setting the
`SKIP_WAIT_FOR_DB` environment variable.
- Add `containers` as an allowed host to comply with Aptible's
[strict health checks](https://www.aptible.com/docs/core-concepts/apps/connecting-to-apps/app-endpoints/https-endpoints/health-checks#strict-health-checks).
- Use the `before_release` tasks from `.aptible.yml` to run database migrations
- Use a Procfile to only start the API and not perform database migrations on startup

This configuration can be applied by adding the Procfile and `.aptible.yml` configuration files to a
[Docker image](https://www.aptible.com/docs/core-concepts/apps/deploying-apps/image/deploying-with-docker-image/overview#how-do-i-deploy-from-docker-image)
that you build starting from a Flagsmith base image:

```text title="Procfile"
cmd: serve
```

```yaml title=".aptible.yml"
before_release:
- migrate
- bootstrap
```
```dockerfile title="Dockerfile"
# Use flagsmith/flagsmith-private-cloud for the Enterprise image
FROM --platform=linux/amd64 flagsmith/flagsmith

# Don't wait for the database to be available during startup for health checks to succeed
ENV SKIP_WAIT_FOR_DB=1

# Use root user to add Aptible files to the container
USER root
RUN mkdir /.aptible/
ADD Procfile /.aptible/Procfile
ADD .aptible.yml /.aptible/.aptible.yml

# Use non-root user at runtime
USER nobody
```

Before deploying, set the environment variables for your database URL and allowed hosts from the Aptible dashboard, or
using the Aptible CLI:

```shell
aptible config:set --app flagsmith \
DATABASE_URL=postgresql://aptible:...@...:23532/db \
DJANGO_ALLOWED_HOSTS='containers,YOUR_APTIBLE_HOSTNAME'
```

## Deployment

After your image is built and pushed to a container registry that Aptible can access, you can deploy it using the
Aptible CLI as you would any other application:

```shell
aptible deploy --app flagsmith --docker-image example/my-flagsmith-aptible-image
```

Once Flagsmith is running in Aptible, make sure to create the first admin user by visiting `/api/v1/users/config/init/`.

## Limitations

The steps described in this document do not deploy the
[asynchronous task processor](/deployment/configuration/task-processor), which may affect performance in production
workloads.

0 comments on commit 3b47ae0

Please sign in to comment.