Heroku Deployment
Open Chat Studio ships with a heroku.yml manifest for deployment as a Docker-based Heroku app.
Prerequisites
- Heroku CLI installed and authenticated
- A Heroku account with billing enabled (the PostgreSQL and Redis add-ons require a verified account)
Step 1: Create the App
heroku create your-app-name
heroku stack:set container -a your-app-name
Step 2: Provision Add-ons
The heroku.yml manifest specifies the required add-ons, but you can also provision them manually:
# PostgreSQL with pgvector support (requires Standard tier or above for pgvector)
heroku addons:create heroku-postgresql:standard-0 -a your-app-name
# Redis
heroku addons:create heroku-redis:mini -a your-app-name
pgvector on Heroku
pgvector is only available on Heroku Postgres Standard tier and above (not the free/mini tier).
Ensure your plan supports the vector extension before running migrations.
After provisioning, enable the extension:
heroku pg:psql -a your-app-name -c "CREATE EXTENSION IF NOT EXISTS vector;"
Step 3: Set Config Vars
heroku config:set -a your-app-name \
DJANGO_SETTINGS_MODULE=config.settings_production \
SECRET_KEY="$(python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())')" \
DJANGO_ALLOWED_HOSTS=your-app-name.herokuapp.com \
CRYPTOGRAPHY_KEY="$(openssl rand -hex 32)" \
CRYPTOGRAPHY_SALT="$(openssl rand -hex 16)"
Set your email provider (example for Mailgun):
heroku config:set -a your-app-name \
DJANGO_EMAIL_BACKEND=anymail.backends.mailgun.EmailBackend \
MAILGUN_API_KEY=your-key \
MAILGUN_SENDER_DOMAIN=mail.yourdomain.com
For S3 media storage (recommended on Heroku, since the filesystem is ephemeral):
heroku config:set -a your-app-name \
USE_S3_STORAGE=True \
AWS_ACCESS_KEY_ID=... \
AWS_SECRET_ACCESS_KEY=... \
AWS_S3_REGION=us-east-1 \
AWS_PUBLIC_STORAGE_BUCKET_NAME=your-public-bucket \
AWS_PRIVATE_STORAGE_BUCKET_NAME=your-private-bucket
See Configuration Reference for all available variables.
Step 4: Deploy
git push heroku main
The heroku.yml release phase runs python manage.py migrate automatically before the new processes start.
Step 5: Create a Superuser
heroku run python manage.py createsuperuser -a your-app-name
Then visit https://your-app-name.herokuapp.com/admin/ and create a Team.
Process Types
The heroku.yml defines three process types:
| Type | Command | Scale |
|---|---|---|
web |
gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 config.wsgi:application |
Scale as needed |
worker |
celery -A config worker -l INFO --pool gevent --concurrency 100 |
Scale as needed |
beat |
celery -A config beat -l INFO |
Always exactly 1 |
Scale dynos:
heroku ps:scale web=1 worker=1 beat=1 -a your-app-name
Warning
Always run exactly one beat dyno. Running more than one will cause duplicate scheduled tasks.
Custom Domain
heroku domains:add yourdomain.com -a your-app-name
heroku config:set DJANGO_ALLOWED_HOSTS=yourdomain.com,your-app-name.herokuapp.com -a your-app-name
heroku config:set CSRF_TRUSTED_ORIGINS=https://yourdomain.com -a your-app-name
Heroku will provision a TLS certificate automatically via ACM when you add a custom domain on a paid dyno.
Upgrading
git pull origin main
git push heroku main
Migrations run automatically in the release phase. Monitor the release log:
heroku releases -a your-app-name
heroku logs --tail -a your-app-name