Environment variables

All Tether configuration is done through environment variables in the .env file. This page documents every variable, its default value, and its effect.

First-run vs runtime variables

Some variables (marked "first run only") are only read when the database is empty. Changing them after first run has no effect — use the Settings page in the UI instead.

Core

VariableDefaultRequiredDescription
SECRET_KEY(insecure placeholder)YesUsed to sign and verify JWT login tokens. Must be a long, random string. If this changes, all existing login sessions are immediately invalidated. Generate with: python -c "import secrets; print(secrets.token_hex(32))"
BASE_DOMAINatechsolutions.orgYesYour root domain. A tenant with slug acme is accessed at acme.BASE_DOMAIN. For local development use localhost.
DEPLOYMENT_MODEselfhostedNoControls billing behaviour. selfhosted = no limits. saas = tier limits enforced. demo = enables the hourly reset endpoint.

Admin account

These are only read on the first run when the database has no users. After the MSP admin account is created, changing these values has no effect — use Settings → Change Password in the UI.

VariableDefaultDescription
ADMIN_EMAIL[email protected]Email address for the initial MSP admin account
ADMIN_PASSWORDadminPassword for the initial MSP admin account. Change this immediately after first login.
ADMIN_NAMEMSP AdminDisplay name for the initial MSP admin
Change the default admin password

The default password admin is universally known. If you deploy Tether with the default and don't change it immediately, anyone who finds your server can log in as an administrator.

Database connection

Tether resolves the database connection in this priority order:

  1. If DATABASE_URL is set, it is used directly and all DB_* variables are ignored
  2. If DB_HOST and DB_USER are set, a MariaDB connection string is built automatically
  3. If neither is set, SQLite is used with the file at TETHER_DATA/tether.db
VariableDefaultDescription
DATABASE_URL(auto-built)Full connection string. Overrides all DB_* vars. Format: mysql+pymysql://user:pass@host:3306/db?charset=utf8mb4
DB_HOST(unset)MariaDB/MySQL hostname or IP. When set (alongside DB_USER), triggers MariaDB connection mode.
DB_PORT3306Database port. Change if your MariaDB runs on a non-standard port.
DB_NAMEtetherDatabase name
DB_USER(unset)Database username
DB_PASSWORD(unset)Database password
DB_ROOT_PASSWORDchangemeMariaDB root password. Only used by the Docker Compose db service.
TETHER_DATA./dataDirectory where Tether stores its data files. In Docker, this is /data (mounted as a named volume).

Demo mode

VariableDefaultDescription
RESET_SECRET(unset)A secret token that must be included in the X-Reset-Secret HTTP header to call the demo reset endpoint. Set this to a long random string and configure the same value in your Cloudflare Worker.

Default tenant

On first run, Tether creates one demo tenant. These variables control what it's called. Only read once on first run.

VariableDefaultDescription
DEFAULT_TENANT_SLUGdemoURL slug for the demo tenant (becomes demo.yourdomain.com)
DEFAULT_TENANT_NAMEDemo ClientDisplay name for the demo tenant

Generating a SECRET_KEY

The SECRET_KEY should be a 64-character random hex string. Generate one with Python:

bash
python3 -c "import secrets; print(secrets.token_hex(32))"

Or with OpenSSL:

bash
openssl rand -hex 32
Do not reuse SECRET_KEY values

Using the same secret key across multiple environments (e.g. staging and production) creates a security risk — a token generated on one could authenticate on the other. Always generate a unique key per environment.

Full .env.example

bash
# Deployment mode: selfhosted (no limits) | saas (tier limits) | demo DEPLOYMENT_MODE=selfhosted # Generate: python3 -c "import secrets; print(secrets.token_hex(32))" SECRET_KEY=please-change-this-to-a-long-random-string # Your domain — subdomains will be tenant.BASE_DOMAIN BASE_DOMAIN=atechsolutions.org # Database — set DB_HOST+DB_USER to use MariaDB, or leave unset for SQLite DB_HOST=localhost DB_PORT=3306 DB_NAME=tether DB_USER=tether DB_PASSWORD=tether DB_ROOT_PASSWORD=changeme # Docker only # Admin account (first run only) [email protected] ADMIN_PASSWORD=admin ADMIN_NAME=MSP Admin # Demo tenant (first run only) DEFAULT_TENANT_SLUG=demo DEFAULT_TENANT_NAME=Demo Client
Last updated: May 2026