Skip to content

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>
See the 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_uploader Compose service). Used by both trapper-tools and the Citizen Science frontend for resumable uploads.
  • MAX_UPLOAD_SIZE (per-file) and MAX_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's api_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's api_url (AI Manager's address) and trapper_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.