Skip to main content

Install & Setup

Environment variables

Configure required values, secrets, your community address, email, and security options before the first start.

Before you begin

Copy `.env.example` to `.env` and replace the required values before the first start. Keep `.env` private and use an independent secret for each security purpose.

Quick start

Create the private file, then set the production domain, required secrets, and PostgreSQL password. Configure SMTP only when you want a deployment-level email fallback. Add setup protection when initialization is reachable from the internet.

  • Set APP_DOMAIN and WEB_ORIGIN to the address used by members.
  • Replace every secret placeholder with an independent random value.
  • Set POSTGRES_PASSWORD to a strong URL-safe value.
  • Review the production example before continuing to Installation.
TerminalTerminal
cp .env.example .env

Required production configuration

VariableRequirementPurpose
APP_DOMAINRequiredPublic hostname, such as community.example.com. Use :80 only for direct HTTP deployment.
WEB_ORIGINRequiredExact address opened by users, including the scheme and without a trailing slash.
POSTGRES_PASSWORDRequiredPrivate, stable password for the PostgreSQL role. Use a strong URL-safe value.
JWT_SECRETRequiredPrivate, stable secret that protects sessions. Changing it invalidates active sessions.
PASSWORD_PEPPERRequiredPrivate, stable secret of at least 32 bytes for password protection.
COMPOSE_PROJECT_NAMERecommendedStable deployment and volume identity. Keep pe-community unless you have a specific reason to change it.
VariableRequirementPurpose
EMAIL_ENCRYPTION_KEYRecommendedPrivate, stable key that protects saved SMTP and CAPTCHA credentials.
REGISTRATION_KEY_HASH_SECRETRecommendedPrivate, stable secret that strengthens registration rate-limit protection.
SETUP_TOKENRecommended before initializationProtects first-run setup when it is reachable from an untrusted network.
OWNER_BREAK_GLASS_SECRETOptionalAdds secret proof to the emergency Owner 2FA recovery procedure.

Application address

For the standard deployment, use a public hostname, match WEB_ORIGIN to the exact HTTPS address opened by users, keep the same-origin API path, and leave the explicit realtime origin empty.

  • APP_DOMAIN contains the hostname without a path.
  • WEB_ORIGIN includes the scheme and must not end with a slash.
  • NEXT_PUBLIC_API_URL and NEXT_PUBLIC_REALTIME_ORIGIN are browser-visible. Rebuild the application after changing them.
  • Set NEXT_PUBLIC_REALTIME_ORIGIN only when realtime uses a different origin.
.envEnvironment
APP_DOMAIN=community.example.com
WEB_ORIGIN=https://community.example.com
NEXT_PUBLIC_API_URL=/api/v1
NEXT_PUBLIC_REALTIME_ORIGIN=

Database and Redis

Set POSTGRES_PASSWORD before the first start. The standard deployment configures PostgreSQL and Redis connections automatically, so you normally do not need to change DATABASE_URL or REDIS_URL.

If you use an external database or Redis service, set the advanced addresses and verify connectivity before startup.

Authentication and sessions

Sessions expire after 20 minutes of inactivity and no later than seven days after creation. These durations are currently fixed.

VariableRequirementPurpose
JWT_SECRETRequiredKeep it private and stable. Rotation signs out active sessions.
PASSWORD_PEPPERRequiredKeep it private and stable. It must contain at least 32 bytes.
PASSWORD_PEPPER_PREVIOUSRotation onlyTemporarily set the old pepper during a planned rotation, then remove it after active accounts have migrated.
SESSION_COOKIE_NAMEOptionalSession cookie name. The default is pe_session; changing it abandons existing cookies.
SESSION_COOKIE_SECUREOptionalUse true or false to force Secure behavior. Leave it empty to follow WEB_ORIGIN and production mode.

Generate secure secrets

This command produces a 32-byte hexadecimal value suitable for the secrets on this page. Run it separately for every variable so the values remain independent.

TerminalTerminal
openssl rand -hex 32

Email delivery

You can configure email from the administration interface. SMTP environment variables provide a deployment-level fallback when no active community setting overrides them.

VariableRequirementPurpose
SMTP_HOSTRequired with SMTP fallbackHostname supplied by your SMTP provider.
SMTP_PORTOptional, default 587Use 587 with STARTTLS or 465 with implicit TLS.
SMTP_USERRequired with SMTP fallbackSMTP username.
SMTP_PASSWORDRequired with SMTP fallback, privateSMTP password or credential. Never commit it to version control.
SMTP_SECUREOptional, default falseUse false for port 587 and true for port 465.
SMTP_FROM_EMAILRequired with SMTP fallbackSender address used for email.
SMTP_FROM_NAMERequired with SMTP fallbackDisplayed sender name.
EMAIL_ENCRYPTION_KEYRecommended, private, stableProtects SMTP and CAPTCHA credentials saved through administration.

Registration protection

Configure CAPTCHA/Turnstile from administration settings rather than `.env`. Set REGISTRATION_KEY_HASH_SECRET to a private, stable value to strengthen registration rate-limit protection.

First-run protection

Set SETUP_TOKEN when first-run setup is reachable from the internet. Then open `/setup?token=<value>` in a trusted session. After successful initialization, first-run setup cannot be repeated.

Owner account recovery

OWNER_BREAK_GLASS_SECRET is optional additional protection for the server-side emergency Owner 2FA recovery procedure. Keep it private and see Security for the complete procedure. Changing it affects only future recovery operations.

File uploads

The standard deployment keeps uploaded files in a persistent volume and sets UPLOADS_DIR automatically. You normally do not need to change this path. Include both the uploads volume and PostgreSQL in your backup plan.

Advanced and custom deployments

The standard deployment manages internal addresses, process ports, and the uploads path automatically. Change the values below only for host development, an external service, or a custom topology.

VariableUse
DATABASE_URLCustom PostgreSQL connection or host development. Format: postgresql://user:password@host:5432/database?schema=public.
REDIS_URLCustom Redis connection or host development. The usual local value is redis://localhost:6379.
INTERNAL_API_URLInternal address used by server rendering. The standard deployment sets it automatically.
API_PUBLIC_URLCustom public base for generated media URLs. The deployment uses WEB_ORIGIN by default.
API_PORTApplication process port for host execution. Default: 4000.
WEB_PORTInterface process port for host execution. Default: 3000.
HTTP_PORTHTTP port published by Docker Compose. Default: 80.
HTTPS_PORTHTTPS port published by Docker Compose. Default: 443.
UPLOADS_DIRCustom uploaded-file path. The standard deployment uses /app/uploads.
REALTIME_DIAGNOSTICSSet true temporarily to add realtime connection diagnostics to logs.

Development-only settings

EMAIL_DEV_LOG=true replaces missing SMTP delivery with email logging outside production only. Do not use it to validate real delivery.

Changing configuration later

VariableImpact when changed
JWT_SECRETInvalidates active sessions.
PASSWORD_PEPPERRequires a planned rotation with PASSWORD_PEPPER_PREVIOUS.
EMAIL_ENCRYPTION_KEYMakes previously saved SMTP and CAPTCHA credentials unreadable.
POSTGRES_PASSWORDMust remain synchronized with PostgreSQL credentials.
COMPOSE_PROJECT_NAMECan select a different volume set and make existing data appear absent.
APP_DOMAIN / WEB_ORIGINRequires DNS/TLS review and a restart or redeployment of affected services.
NEXT_PUBLIC_API_URL / NEXT_PUBLIC_REALTIME_ORIGINRequires rebuilding application assets.
OWNER_BREAK_GLASS_SECRETChanges the proof requested for future Owner recovery.

Production example

Use this as a starting point and replace every placeholder. Leave SMTP values empty when email is configured only through administration.

.env (redacted production example)Environment
COMPOSE_PROJECT_NAME=pe-community

APP_DOMAIN=community.example.com
WEB_ORIGIN=https://community.example.com
NEXT_PUBLIC_API_URL=/api/v1
NEXT_PUBLIC_REALTIME_ORIGIN=

POSTGRES_PASSWORD=<strong-url-safe-database-password>
JWT_SECRET=<strong-independent-secret>
PASSWORD_PEPPER=<strong-independent-secret-at-least-32-bytes>
EMAIL_ENCRYPTION_KEY=<strong-independent-stable-secret>
REGISTRATION_KEY_HASH_SECRET=<strong-independent-secret>

SETUP_TOKEN=<optional-setup-secret>
OWNER_BREAK_GLASS_SECRET=<optional-recovery-secret>

SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
SMTP_SECURE=false
SMTP_FROM_EMAIL=
SMTP_FROM_NAME=

Validation checklist

  • The `.env` file is not committed and every required placeholder is replaced.
  • Each security purpose uses an independent secret.
  • APP_DOMAIN and WEB_ORIGIN match the address opened by users.
  • POSTGRES_PASSWORD is set to a strong URL-safe value.
  • Email configuration has been tested when email features are required.
  • SETUP_TOKEN protects an empty installation exposed to the internet.
  • PostgreSQL and uploaded files are included in backups.

Troubleshooting

  • Sign-in or browser requests fail: check APP_DOMAIN, WEB_ORIGIN, DNS, HTTPS, and the reverse proxy.
  • Realtime features disconnect: check NEXT_PUBLIC_REALTIME_ORIGIN if set, then proxy connectivity and browser errors.
  • Email is not sent: check host, port, TLS mode, credentials, sender identity, and outbound SMTP restrictions from your host.
  • The database is unavailable: check POSTGRES_PASSWORD and deployment status; check DATABASE_URL only for a custom deployment.
  • Saved email or CAPTCHA credentials are unreadable: restore the previous EMAIL_ENCRYPTION_KEY or re-enter credentials under the new key.
  • Uploaded files are unavailable: verify that the persistent uploads volume is mounted and restored.