Configuration reference¶
TRAPPER Expert's runtime configuration flows through the rendered .env file produced by trapper-setup's configure.py. This page is the env-var reference; for task-oriented guides see Storage & infra and AI pipeline.
Where things live¶
In v2 the deployment toolchain is layered:
| Concern | Where it's configured |
|---|---|
| Compose stack composition (services, ports, SSL, volumes) | trapper-setup/docker-compose*.yml + the per-profile overlay rendered by configure.py |
| Per-profile env values (DB credentials, secrets, feature flags) | trapper-setup/profiles/<profile>/.env, generated by configure.py |
| Expert-side runtime options (this module) | This page — read by Django from the same .env at startup |
| AI Manager runtime options | trapper-ai repo's settings, fed from the same .env |
| AI Worker / coordinator options | Per-profile coordinator.yaml, rendered by configure.py from trapper-setup/config/coordinator/ |
| Per-Classification-Project AI behaviour | Django admin (this module) — see Create a classification project |
| Per-Deployment depth / distance settings | Django admin (this module) — see Distance estimation |
Editing a deployed instance
If you find yourself editing .env by hand on a deployed instance, re-render the profile through configure.py instead — values stay coherent across the stack and survive a re-run of the wizard:
./configure.py interactive --from-profile <name>
trapper-setup README for --reuse-env semantics.
Basic settings¶
Present in every .env regardless of profile flavour:
DOMAIN_NAME=demo.trapper-project.org
SECRET_KEY='cudv86xkzva)o1lkt-ow72)y__*xwsb1@43wtp1cc@zak=i@@e'
SECRET_KEY is used by Django for cryptographic signing and must be unique and unpredictable (see the Django docs). configure.py generates one on first run — never reuse it across deployments.
Admin and manager notifications:
ADMIN1=admin1,admin1@oscf.org # {username},{email}
ADMIN2=admin2,admin2@oscf.org
MANAGER1=manager1,manager1@oscf.org
MANAGER2=manager2,manager2@oscf.org
When email is configured, admins receive 500 notifications and managers receive new-user-registration / new-research-project notifications.
HTTP/HTTPS port mappings:
HTTP_PORTS=80:80
HTTPS_PORTS=443:443
These two are specific to the legacy Expert-only ./start.sh path's docker-compose.yml (this repo's own root, not trapper-setup) — confirmed trapper-setup's docker-compose.yml doesn't reference them at all; it ports/exposes services differently per profile (Traefik labels in domain mode, fixed TRAPPER_NGINX_DEV_PORT-style vars in localhost mode — see its own .env).
SSL certificates¶
The trapper-setup wizard handles three SSL paths — Let's Encrypt, static certificates, self-signed — and renders the matching Compose overlay. See its README for the wizard prompts.
On the legacy Expert-only ./start.sh path (Expert-only development setup), point at existing certificates directly:
# default
SSL_CERTIFICATE=${PWD}/ssl/cert.pem
SSL_CERTIFICATE_KEY=${PWD}/ssl/key.pem
# Let's Encrypt
SSL_CERTIFICATE=/etc/letsencrypt/live/trapper/fullchain.pem
SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/trapper/privkey.pem
These same certificates secure the HTTPS Nginx proxy and the FTPS pure-ftpd container. If neither variable is set, the start script generates self-signed certs with openssl.
Database¶
The default Compose stack ships a TimescaleDB-enabled PostgreSQL image (trapper-postgresql:timescaledb). TimescaleDB is always required — the ObjectFrameObservation hypertable is created unconditionally by migration, there's no opt-out. See Frame hypertable.
Default credentials (overridable):
POSTGRES_USER=trapper
POSTGRES_PASSWORD=trapper
POSTGRES_DB=trapper
For an external Postgres instance, see External database.
Storage¶
Multimedia files live either on local disk (default) or in a supported cloud bucket.
On the legacy Expert-only ./start.sh path, local mode bind-mounts host directories via:
DEFAULT_FILE_STORAGE=
VOL_MEDIA=/storage/trapper_data/media
VOL_EXTERNAL_MEDIA=/storage/trapper_data/external_media
trapper-setup profiles use named Docker volumes (trapper_media, trapper_external_media) for the same two mount points instead — VOL_MEDIA/VOL_EXTERNAL_MEDIA aren't referenced anywhere in its docker-compose.yml. DEFAULT_FILE_STORAGE (cloud backend selector) applies on both paths.
VOL_MEDIA (or its trapper-setup volume equivalent) keeps original images/videos plus previews and thumbnails:
protected/storage/resources/{user_id}/{date_uploaded}/
protected/storage/resources/{user_id}/{date_uploaded}/previews/
protected/storage/resources/{user_id}/{date_uploaded}/thumbnails/
VOL_EXTERNAL_MEDIA holds user-uploaded archives (FTP drops, zip batches) and exported data packages.
Per-classification frame msgpack files (Classification.frames_msgpack) live under:
protected/media_classification/msgpacks/{project_id}/{deployment_id}/{resource_id}/
For cloud buckets (Azure / S3 / MinIO), see Cloud storage.
Email service¶
Off by default. To enable it (Gmail example):
EMAIL_NOTIFICATIONS=True
EMAIL_NOTIFICATIONS_RESEARCH_PROJECT=True
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_HOST_USER=project@gmail.com
EMAIL_HOST_PASSWORD=password
EMAIL_USE_TLS=True
A working email backend is needed for new-user activation links, admin error reports, manager notifications about new project requests, and the Mail users admin action.
User registration¶
USER_REGISTRATION_OPEN=True
USE_RECAPTCHA=True
RECAPTCHA_PUBLIC_KEY=public_key
RECAPTCHA_PRIVATE_KEY=private_key
When registration is open, anyone can sign up — but the resulting User row is is_active=False until an admin runs the set roles action. See Users & roles.
Debugging¶
USE_DEBUG_TOOLBAR=True
DEBUG_TOOLBAR_USERS=admin1,admin2
USE_SILK=True
Django Debug Toolbar shows a per-request panel; django-silk profiles SQL and view-level performance.
Trapper Tools (data upload)¶
The companion CLI trapper-tools packages and uploads camera-trap data to a Trapper Expert instance. Configuration on the Trapper Tools side lives under ~/.trapper-tools/default.toml; on the Expert side the relevant knobs are:
- FTPS endpoint — Pure-FTPd on port 21, secured by the same SSL certs as the web stack. Per-user accounts created via Users & roles.
- Chunked upload service — FastAPI on port 8088 (the
trapper_uploaderCompose service). Used by bothtrapper-toolsand the Citizen Science frontend for resumable uploads. MAX_UPLOAD_SIZE(per-file) andMAX_UPLOAD_COLLECTION_SIZE(per-collection) — cap individual transfers.
See Convert, package & upload with Trapper-Tools for the tooling-side workflow.
AI Manager / Worker integration¶
There's no Django setting for this — the link is a database row, AIProviderConnection (Expert admin: Media classification → Ai provider connections), not an env var Django reads at startup. trapper-setup's wizard bootstraps/updates that row directly (a update_or_create(name="Trapper AI Manager", ...) shell snippet run on the Expert container) from these .env values:
AI_WORKER_USERNAME/AI_WORKER_PASSWORD— credentials for the AI Worker user on the AI Manager, written into the connection'sapi_auth_login/api_auth_passw.TRAPPER_AI_DOMAIN_NAME/TRAPPER_DOMAIN_NAME/TRAPPER_NGINX_DEV_PORT/TRAPPER_NGINX_AI_DEV_PORT/SSL_MODE/BASE_DOMAIN/TRAPPER_NETWORK_GATEWAY— combined into the connection'sapi_url(AI Manager's address) andtrapper_instance_url(this Expert's own address, used for callbacks), with different derivations for Traefik-domain mode vs. bridge-gateway localhost mode.
See Configure an AI Manager connection for the manual/admin-side view of the same model, and the Create AI Worker user action (Users & roles) for provisioning the AI Manager-side user these credentials point at.
The AI Worker coordinator's own configuration (coordinator.yaml, hardware autodetect, runtime selection, $TRAPPERAI_HOME paths) lives in the trapper-ai-worker repo — see its README.