Installation

Environment Variables

All personal settings for FediSuite (domain, passwords, mail server, admin credentials) are configured via the .env file. This page explains each variable individually and lists the defaults from the code.

What is a .env file?

A .env file is a text file with key-value pairs in the form KEY=value. Docker Compose reads it on start and passes the values to the containers as environment variables.

All instance-specific values (passwords, domain, secrets) live in the .env, not in the docker-compose.yml. That way the Compose file can be updated with git pull without overwriting your configuration. Changes to the .env only take effect once the containers are recreated with docker compose up -d. A docker compose restart does not re-read it.

Security: The .env contains passwords and secrets. It must not end up in a Git repository. The self-hosting repository already ignores .env through its .gitignore. Still set restrictive file permissions, for example chmod 600 .env.

The complete template

The repository contains a template at .env.example. You copy it once to .env and adjust the values.

.env.example
# Database
POSTGRES_DB=fedisuite
POSTGRES_USER=fedisuite
POSTGRES_PASSWORD=change-me
DATABASE_URL=postgresql://fedisuite:change-me@db:5432/fedisuite

# Docker Image
FEDISUITE_IMAGE=christinloehner/fedisuite:latest

# App
JWT_SECRET=replace-with-a-long-random-secret
ACCOUNT_ENCRYPTION_KEY=replace-with-64-hexadecimal-characters
APP_NAME=FediSuite
APP_URL=https://your-domain.example
PUBLIC_SITE_URL=https://your-domain.example

# Admin account (created on start if it does not exist yet)
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=change-this-admin-password

# Email
SMTP_HOST=smtp.your-provider.example
SMTP_PORT=587
SMTP_USER=your-smtp-user
SMTP_PASS=your-smtp-password
SMTP_FROM=no-reply@your-domain.example

# Optional
OUTBOUND_HTTP_USER_AGENT=Mozilla/5.0 (compatible; FediSuite/1.0; +https://your-domain.example)
ENABLE_USER_REGISTRATION=true

Further variables (feature switches, time limits, reach) are optional and listed further down. With docker compose config you can check before starting whether the configuration is valid.

Database connection

FediSuite uses PostgreSQL. These four variables have to match each other: if POSTGRES_PASSWORD holds a new password, the same one must be in the DATABASE_URL.

POSTGRES_DB
fedisuite Required

Name of the database that PostgreSQL creates on the first start. Freely selectable. It is only evaluated when the data directory is created.

POSTGRES_USER
fedisuite Required

Database user, created on the first start and superuser of the database.

POSTGRES_PASSWORD
secure-password Required

Password of the database user. Choose a strong, random password and do not leave the example value change-me in place. The password is only set when the data directory is created. To change it in an existing database you need an ALTER USER in PostgreSQL.

DATABASE_URL
postgresql://fedisuite:passwort@db:5432/fedisuite Required

Connection string through which FediSuite reaches the database. Format: postgresql://USER:PASSWORD@HOST:PORT/DATABASE. The host is db, which is the name of the database container in the Docker network. User, password and database name must match the POSTGRES_* values. Special characters in the password (for example @, / or :) have to be URL-encoded. The easiest choice is a password made of letters and digits.

Example with your own values: If you choose mySecurePassword99 as the password, the DATABASE_URL reads:
postgresql://fedisuite:mySecurePassword99@db:5432/fedisuite

Docker Image

FEDISUITE_IMAGE
christinloehner/fedisuite:latest Required

Sets which Docker image app, worker1 and worker2 use. The value has the form IMAGENAME:TAG. If the variable is missing, the Compose file uses christinloehner/fedisuite:latest. The tags are on Docker Hub (opens in new tab).

christinloehner/fedisuite:latest The current version for linux/amd64. Default in the template.
christinloehner/fedisuite:2.0.0 Pin a specific version (example). Useful if you want to control updates deliberately.
christinloehner/fedisuite:arm64-latest The current version for linux/arm64, for example for ARM servers or a Raspberry Pi.
christinloehner/fedisuite:arm64-2.0.0 A specific version for ARM64 (example).
Version numbers: Versions have the form MAJOR.MINOR.PATCH. Every release tag passes a release gate before publication, which requires successful tests. What changes is listed in the changelog (opens in new tab). The process of an update is described on the Updates page.

App configuration

APP_URL
https://fedisuite.your-domain.com Required

The full public URL of your instance, with https:// and without a trailing slash. FediSuite builds links in emails and the OAuth return address (APP_URL/api/auth/fediverse/callback) from it. If it does not match the real domain, connecting accounts fails. Without a value http://localhost:3000 applies.

JWT_SECRET
(long random string) Required

Secret key with which FediSuite signs login tokens. It also encrypts the stored two-factor secrets and the secret for the instance directory. Anyone who knows it can forge tokens, so it has to be long, random and secret. FediSuite does not require a minimum length, but the process does not start without a value. Do not change it after the first start: all logins become invalid and stored two-factor secrets can no longer be decrypted.

Generate JWT_SECRET

openssl rand -hex 64

Run the command on your server and enter the output as the value of JWT_SECRET.

ACCOUNT_ENCRYPTION_KEY Required since 2.0.0

Separate 32-byte key for encrypting access tokens and client secrets of connected Fediverse accounts. It must contain exactly 64 hexadecimal characters, be distinct from JWT_SECRET, and have the same value in the app and workers. Generate it once with openssl rand -hex 32, add it to .env, and keep a separate encrypted backup. Existing credentials are migrated on first start with 2.0. A missing, invalid, or wrong key prevents startup or decryption; never change it after migration.

Safely upgrade an existing instance to 2.0.0 →
APP_NAME
FediSuite Optional

Display name of the instance, for example in emails and in the default user agent. Default: FediSuite.

PUBLIC_SITE_URL
https://fedisuite.your-domain.com Optional

Public address of the instance for the default user agent and the entry in the instance directory. Default: the value of APP_URL. In most cases you can leave it out or set it to the same value as APP_URL.

Admin account

When the app starts, FediSuite checks whether a user with the address from ADMIN_EMAIL exists. If not, it creates it as a verified administrator with ADMIN_PASSWORD. If the user already exists, the password stays unchanged and the user keeps or regains the admin role.

ADMIN_EMAIL
admin@your-domain.com Required

Email address of the admin account. You log in with it after the installation. If you enter a different address later, the next start creates a second admin for it.

ADMIN_PASSWORD
secure-admin-password Required

Password of the admin account. Choose a strong password. After the first login you can change it in the settings at any time. Changing this variable for an existing account has no effect.

Critical: If ADMIN_PASSWORD (or ADMIN_EMAIL) is missing on the first start, no admin is created and you cannot log in. Enter both values before you run docker compose up -d for the first time. To fix it afterwards, set the values and restart the app.

Email (SMTP)

FediSuite sends email for registration (confirmation), password reset, two-factor login by email and the flows around the historical import after connecting accounts. Without a working SMTP configuration these functions cannot be used. SMTP is therefore required for operation.

SMTP_HOST
smtp.your-provider.com Required

Hostname of the SMTP server of your email provider. Without a value FediSuite uses localhost.

SMTP_PORT
587 Required

Port of the SMTP server. On 465 FediSuite uses TLS right away. On any other port, for example 587, the connection is encrypted with STARTTLS if the server offers it. Without a value 1025 applies.

SMTP_USER
no-reply@your-domain.com Required

User name for SMTP authentication, often the sender address.

SMTP_PASS
your-smtp-password Required

Password for SMTP authentication. Some providers require a dedicated app password instead of the account password.

SMTP_FROM
no-reply@your-domain.com Required

Sender address of the emails. It usually has to match the domain of your SMTP account, otherwise receiving servers reject the mails. Without a value FediSuite uses "APP_NAME" <no-reply@HOST> with the host from APP_URL.

Registration & network

ENABLE_USER_REGISTRATION
true Optional

Controls whether new users can sign up through the registration page. The default is true (open). For a private instance set it to false.

ENABLE_USER_REGISTRATION=true

Public instance: anyone can register.

ENABLE_USER_REGISTRATION=false

Private instance: no registration possible. The admin from ADMIN_EMAIL is still created.

OUTBOUND_HTTP_USER_AGENT Optional

User-Agent header for all outgoing HTTP requests, for example to Fediverse servers. Default: Mozilla/5.0 (compatible; APP_NAME/1.0; +PUBLIC_SITE_URL). With a reachable URL in the header, operators of other instances can contact you if there are problems.

OUTBOUND_HTTP_USER_AGENT=Mozilla/5.0 (compatible; FediSuite/1.0; +https://your-domain.com)
TRUST_PROXY1 (server default)

Number of trusted reverse-proxy hops used to determine the client IP for rate limits, audit logs and sessions. Set 0 if port 3000 is directly reachable without a proxy; set 1 behind exactly one trusted proxy such as Traefik. The server also accepts false, true or a comma-separated list of trusted addresses/subnets. Avoid true when clients can connect directly: they could forge their IP in forwarding headers.

ALLOW_PRIVATE_INSTANCE_URLS
false Optional

By default FediSuite refuses connections into private networks (loopback, private address ranges, link-local addresses such as the cloud metadata service). The check runs on every connection, including redirects. Set true only if a connected instance runs in your own network, for example a test instance next to the server. On servers that only connect to public instances leave the variable unset.

OUTBOUND_HTTP_TIMEOUT_MS
60000 Optional

General time limit in milliseconds for outgoing HTTP requests (at least 1000). Individual jobs such as the reach calculation set shorter limits of their own.

Feature switches

The larger features of FediSuite 2.0 can be switched off individually. All are on by default. With false (also 0, no, off) the feature disappears from the web interface and the apps, and the related API routes answer with 404. They are set in the .env.

ENABLE_DRAFTS
true Optional

Drafts: posts without a time that the scheduler never publishes, with a stage (idea, in progress, ready) and a drafts tab on the posts page.

ENABLE_CONTENT_CALENDAR
true Optional

Content calendar: month and week view of posts with filters and moving by drag and drop.

ENABLE_CONTENT_LABELS
true Optional

Labels and campaigns: internal markers for posts that are never published or turned into hashtags.

ENABLE_CONTENT_RECYCLING
true Optional

Recycling: use archive posts as a new draft, the badge “Interesting again”, the evergreen collection and the warning about similar posts.

ENABLE_CONTENT_INTELLIGENCE
true Optional

Content analysis: the “Content” tab in the analytics, hints in the composer and time window markers in the calendar.

ENABLE_COMMUNITY_INTELLIGENCEtrue

Shows the Community analytics tab and enables its API. It analyses recorded interactions to distinguish interacting, new and returning accounts. Set to false to hide this feature; configure the lifetime of recorded interactions separately with ENGAGEMENT_RETENTION_DAYS.

Worker variables (in docker-compose.yml)

These variables are set per service in the bundled Compose file and control which background jobs a container takes over. They can also be set in the .env, but only take effect in containers whose environment block does not override them. The distribution of roles is explained on the Configuration page.

ENABLE_SCHEDULER Default: true

Publishes due scheduled posts (every minute) and, if published, syncs the instance list. In the Compose file only on in worker1. Several schedulers would not post twice (every post is claimed atomically) but are redundant.

ENABLE_POSTS_REFRESH Default: true

Regularly refreshes accounts and post numbers. Can run in several containers.

ENABLE_REACH_REFRESH Default: true

Works through the queue for the reach calculation. The Compose file does not set it, so it runs in every container.

ENABLE_IDLE_REMINDER Default: true

Sends the one-time reminder to users who have not connected a Fediverse account after 48 hours. In the Compose file only on in worker1.

ENABLE_TIPS_ENGINE Default: true

Generates the tips for connected accounts every six hours. Can run in several containers.

WORKER_ID Default: hostname of the container

Unique name of the container, for example worker-1. It shows up in the logs and in locks and queues.

REFRESH_BATCH_SIZE Default: 10

How many accounts a worker refreshes per pass (every 60 seconds), 1 to 50. The Compose file sets 5. Lower values go easier on the servers of the Fediverse instances, higher ones work through many accounts faster.

PLUGINS_ENABLED Default: true

Switches the plugin system on or off. With false the plugin registry stays empty.

PLUGIN_SCAN_ON_START Default: true

Scans the folder /app/plugins for plugins on start. With false the scan is skipped.

PLUGIN_API_VERSION Default: 1

Plugin API version of the instance. Plugins declare in their plugin.json which version they run on. Leave the value at 1.

ENGAGEMENT_RETENTION_DAYS730 · range 90 to 36500

How many days interaction records from other Fediverse accounts are retained for Community analytics. An hourly cleanup removes older records in batches; shorter retention also shortens the available analysis history. Invalid values fall back to 730 days and out-of-range values are clamped. Choose a period appropriate for your privacy policy.

PLUGIN_DIR (obsolete)

Older changelog entries mention this variable, but current images ignore it. The plugin directory is fixed at /app/plugins. Mount your plugin repository there in every app and worker container; use PLUGINS_ENABLED and PLUGIN_SCAN_ON_START to control loading.

Advanced settings

These variables are optional. The defaults suit most instances. Numeric values outside the given range are moved to the nearest limit, a missing or invalid value falls back to the default. Times are in milliseconds.

Refreshing accounts

REFRESH_ACCOUNT_TIMEOUT_MS Default 45000 · range ≥ 5000

Time after which refreshing a single account is given up.

REFRESH_FAILURE_THRESHOLD Default 5 · range ≥ 1

How many failures in a row mark an account as “reconnect” or “unreachable”.

STALE_POST_REFRESH_BATCH_SIZE Default 10 · range 0 to 50

How many of the posts fetched longest ago each hourly refresh of an account reads again so the counters of old posts stay current. 0 switches the rotation off.

STALE_POST_REFRESH_MIN_AGE_DAYS Default 7 · range 1 to 365

Minimum age of the last fetch in days from which a post belongs to the rotation.

SLOW_REFRESH_LOG_MS Default 20000 · range 1000 to 600000

From this duration on, the refresh of an account is logged with the times of all its steps and requests. If it runs into its time limit it is always logged that way.

Reach

REACH_WORKER_BATCH_SIZE Default 12 · range 1 to 50

Jobs a worker takes from the queue per pass.

REACH_REFRESH_INTERVAL_MS Default 10000 · range 1000 to 60000

How often each process checks the queue.

REACH_MAX_CONCURRENT_PER_INSTANCE Default 6 · range 1 to 20

Concurrent requests per remote instance, across all workers. Protects small instances from overload.

REACH_PARALLEL_INSTANCES Default 4 · range 1 to 12

How many instances a worker queries at the same time.

REACH_QUEUE_PER_ACCOUNT_LIMIT Default 80 · range 1 to 200

Maximum number of open jobs per account in the queue.

REACH_QUEUE_LOOKBACK_DAYS Default 90 · range ≥ 1

Period in days for which repeat calculations are triggered. Missing reach data is backfilled regardless of age.

REACH_RECALCULATE_AFTER_HOURS Default 24 · range 1 to 720

After how many hours a post with unchanged counters is calculated again. If the counters change it happens right away.

REACH_MAX_REBLOGGER_PAGES Default 5 · range 1 to 10

How many pages (80 each) of a post's boost list are read.

REACH_JOB_TIMEOUT_MS Default 60000 · range 10000 to 600000

Time limit per job. After that it is given up and retried later.

REACH_JOB_REQUEST_TIMEOUT_MS Default 10000 · range 1000 to 60000

Time limit per single request within a job.

REACH_JOB_MAX_RATE_LIMIT_WAIT_MS Default 15000 · range 0 to 300000

Longest wait for a rate limit. If an instance asks for more, its jobs are put off instead of waiting.

REACH_RETRY_BASE_MS Default 300000 · range ≥ 1000

Base wait before failed jobs are retried (grows exponentially).

Others

MASTODON_MEDIA_PROCESSING_TIMEOUT_MS Default 120000 · range ≥ 10000

How long FediSuite waits for a Mastodon instance to process media after an upload before the post is created.

MASTODON_MEDIA_PROCESSING_POLL_MS Default 2000 · range ≥ 500

Interval between the checks during that wait.

AUDIT_LOG_DIR Default /app/logs

Directory in the container for the audit logs. Only change it together with the volume.

FEDISUITE_REGISTRY_URL Default https://www.fedisuite.com/api/instances

Address of the instance directory the instance syncs with on request (admin area). Only change it for directories of your own.

FEDISUITE_REGISTRY_TIMEOUT_MS Default 30000 · range ≥ 5000

Time limit for requests to the instance directory. Slow servers (for example a Raspberry Pi) sometimes need more time there.