Configuring the Environment (.env)¶
The .env file at the root of the project is the single source of truth for the entire ThingLarp platform. It supplies configuration parameters, database credentials, domain names, and cryptographic keys to Docker Compose, which automatically distributes them across all microservices.
1. Initial Setup¶
To begin, copy the provided template to create your active .env file:
Ensure the file permissions restrict read access to authorized system users:
2. Section-by-Section Configuration¶
Section 1: Domain & TLS Configuration¶
These variables configure Traefik v3 for routing and automated SSL/TLS certificate issuance via Let's Encrypt:
# Domain & TLS Configuration
DOMAIN=example.com
API_DOMAIN=api.example.com
MQTT_DOMAIN=mqtt.example.com
ACME_EMAIL=admin@example.com
DOMAIN: The base apex domain of your organization or project.API_DOMAIN: Subdomain routed to the FastAPI Gateway (HTTPS on port443).MQTT_DOMAIN: Subdomain routed to the Mosquitto broker with TLS termination (MQTTS on port8883).ACME_EMAIL: The email address submitted to Let's Encrypt for registration and expiration warnings.
[!IMPORTANT] DNS Prerequisite for Production: Before starting Traefik, ensure you have configured
AorCNAMErecords with your DNS registrar pointingapi.example.comandmqtt.example.comto your public server IP. Let's Encrypt requires successful HTTP-01 challenge resolution on port80.For Local Development / LAN: You can leave these as defaults or point them to
localhost. Local traffic accesses the API onhttp://localhost:8000and MQTT on port1883directly without TLS.
Section 2: PostgreSQL Superuser & Database¶
These settings configure the core PostgreSQL 16 container running TimescaleDB:
# PostgreSQL Root & App Database
POSTGRES_DB=iot
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres_supersecret_change_me
POSTGRES_DB: The database name initialized inside the cluster (defaults toiot).POSTGRES_USER: The PostgreSQL administrative superuser account (defaults topostgres).POSTGRES_PASSWORD: The master password for the administrative user. Replace with a random password.
Section 3: Service Database Passwords¶
ThingLarp enforces strict least-privilege security. Each service connects to PostgreSQL using a dedicated database role with restricted table permissions:
# Service Database Passwords (must match passwords in db/init/03_roles.sql)
PG_MQTT_AUTH_PASSWORD=iot_mqtt_auth_secret
PG_BRIDGE_PASSWORD=iot_bridge_secret
PG_API_PASSWORD=iot_api_secret
PG_MQTT_AUTH_PASSWORD: Password for theiot_mqtt_authuser, consumed by themosquitto-go-authplugin to query credentials and ACLs.PG_BRIDGE_PASSWORD: Password for theiot_bridgeuser, used by the Python Ingestion Bridge to bulkCOPYtelemetry into TimescaleDB.PG_API_PASSWORD: Password for theiot_apiuser, used by the FastAPI Gateway for user registration, channel management, and telemetry queries.
[!WARNING] The passwords defined here must match the passwords set during database initialization in
db/init/03_roles.sql. If you change these values before the first run, ensure you also updatedb/init/03_roles.sql.
Section 4: Internal Service MQTT Credentials¶
The Python Bridge and FastAPI Gateway connect to the Mosquitto broker as dedicated internal service clients:
# Internal Service MQTT Credentials
BRIDGE_MQTT_USER=svc_bridge
BRIDGE_MQTT_PASSWORD=bridge_mqtt_secret
API_MQTT_USER=svc_api
API_MQTT_PASSWORD=api_mqtt_secret
BRIDGE_MQTT_USER/BRIDGE_MQTT_PASSWORD: Credentials used by the Python Bridge to subscribe to$share/ingest/channels/+/data.API_MQTT_USER/API_MQTT_PASSWORD: Credentials used by FastAPI to forward HTTP data writes (POST /channels/{id}/data) directly into the broker.
How Mosquitto Validates Service Credentials¶
The Mosquitto mosquitto-go-auth plugin validates MQTT passwords against Bcrypt hashes stored in db/init/03_roles.sql.
If you update BRIDGE_MQTT_PASSWORD or API_MQTT_PASSWORD, you must generate a corresponding Bcrypt hash:
# Generate a Bcrypt hash using Python
python3 -c "import bcrypt; print(bcrypt.hashpw(b'YOUR_NEW_PASSWORD', bcrypt.gensalt(10)).decode())"
Then update the password_hash entries in db/init/03_roles.sql before starting the database.
Section 5: Security & JWT Token Settings¶
These settings configure JSON Web Token issuance for user authentication in the API Gateway and Flutter app:
# Security
JWT_SECRET=super_secret_random_jwt_key_32_chars_min
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=15
REFRESH_TOKEN_EXPIRE_DAYS=30
JWT_SECRET: Cryptographic secret key used to sign and verify user JWTs. Must be at least 32 characters long.JWT_ALGORITHM: Cryptographic signing algorithm (defaults toHS256).ACCESS_TOKEN_EXPIRE_MINUTES: Lifespan of short-lived access tokens (default: 15 minutes).REFRESH_TOKEN_EXPIRE_DAYS: Lifespan of persistent refresh tokens (default: 30 days).
3. Generating Secure Production Secrets¶
For production environments, you can generate cryptographically secure random values using openssl or python:
4. Applying Changes to Running Containers¶
When you modify .env, restart the Docker Compose stack to apply the new environment variables:
# Restart services to pick up new environment variables
docker compose up -d
# If database passwords or service credentials were changed from scratch:
docker compose down -v
docker compose up -d --build
[!CAUTION] Running
docker compose down -vdeletes PostgreSQL storage volumes. Only use-vduring initial setup or when you intend to wipe the database.