-
-
Notifications
You must be signed in to change notification settings - Fork 30
6. Admin and Operations
The admin interface is optional and disabled by default. When enabled, it uses Django admin at /admin/ (or BASE_URL + /admin/ if you host under a subpath).
Enable the admin interface
- Set
ADMIN_ENABLED=Trueand restart the app. - The
/admin/route is only registered whenADMIN_ENABLEDis true.
Log in
- Use a superuser account (both
is_staffandis_superusermust be true). - Create one with Django:
# Local dev
cd src && python manage.py createsuperuser
# Docker
docker exec -it floppy python manage.py createsuperuserPromote an existing user to admin
# Local dev
cd src && python manage.py shellfrom django.contrib.auth import get_user_model
User = get_user_model()
User.objects.filter(username="your_username").update(is_staff=True, is_superuser=True)Create a new admin user (shell)
# Local dev
cd src && python manage.py shellfrom django.contrib.auth import get_user_model
User = get_user_model()
User.objects.create_user(
username="admin",
password="change-me",
is_staff=True,
is_superuser=True,
)Admin interface overview
- The admin exposes most models (items, media entries, users, lists, integrations, collection entries, metadata backfill state, etc.).
- Use it for data fixes, metadata cleanup, and inspection.
- The app also auto-registers many models; search and filters are available on common tables like Items and Episodes.
Floppy configuration comes from environment variables, Docker compose settings, and optional Docker secrets files. Some per-user credentials (Plex tokens, Trakt list credentials, Pocket Casts login, etc.) are stored in the database after you connect accounts in the UI.
Where config comes from
-
.envfiles or containerenvironment:blocks. - Docker secrets via
*_FILEvariables (read from/run/secrets/by default). - Defaults baked into
src/config/settings.py(many provider keys ship with low-rate defaults). - Build metadata and fork owner info (Dockerfile stage +
COMMIT_SHA,FORK_OWNER_*).
Minimum required config
-
SECRET(a long random string). - A reachable Redis instance (
REDIS_URL), because sessions and background tasks use Redis. - Database settings only if you want Postgres (
DB_HOST+DB_*); otherwise SQLite is used.
Optional but common
-
URLS(orCSRF+ALLOWED_HOSTS) when using a reverse proxy. - Provider keys for metadata/imports (TMDB, MAL, IGDB, BGG, etc.).
-
ADMIN_ENABLED=Trueif you want/admin/. -
BASE_URLif hosting under a subpath. - Social auth settings if you use SSO.
Jump to sections:
- Environment Variables
- Docker Deployment
- Database: SQLite vs Postgres
- Redis and Sessions
- Celery and Background Tasks
- Hosting and Security
- Social Authentication
This is the consolidated list of env vars used by the app. Values are read in src/config/settings.py unless noted.
Core app
-
SECRET(required). SupportsSECRET_FILEfor Docker secrets. -
DEBUG(bool). KeepFalsein production — enabling it activates the debug toolbar on every request and disables Django's cached template loader, which noticeably slows page loads. -
TZ(timezone string, used by Django). -
ADMIN_ENABLED(bool). Enables/admin/route. -
TRACK_TIME(bool). Enables time tracking features. -
VERSION,COMMIT_SHA,GIT_COMMIT,GITHUB_SHA(build metadata). -
FORK_OWNER_NAME,FORK_OWNER_URL(display fork owner in UI). -
FORK_OWNER_FILE,GITHUB_REPOSITORY_OWNER,GITHUB_REPOSITORY(used to derive fork owner if not set).
Base URL and cookies
-
BASE_URL(subpath mount like/floppy). SetsFORCE_SCRIPT_NAME, static URL, and cookie paths. -
URLS(comma-separated public origins). Appends toCSRFandALLOWED_HOSTS. -
CSRF(comma-separated trusted origins). -
ALLOWED_HOSTS(comma-separated hostnames). -
ACCOUNT_DEFAULT_HTTP_PROTOCOL(only needed if CSRF origins are mixed http/https). -
ACCOUNT_LOGOUT_REDIRECT_URL(absolute URL for SSO logout flows). -
USE_X_FORWARDED_PROTO- Whether to check X-Forwarded-Proto. Recommended only behind reverse proxy. -
USE_X_FORWARDED_HOST- Whether to check X-Forwarded-Host. Needed only behind reverse proxy for correct callback URLs -
USE_X_FORWARDED_PORT- Whether to check X-Forwarded-Port. Needed only behind reverse proxy for correct callback URLs. Ignored if X-Forwarded-Host includes a port. -
USE_X_FORWARDED- Sets the value of the three above.
Database (Postgres)
-
DB_HOST,DB_NAME,DB_USER,DB_PASSWORD,DB_PORT(setDB_HOSTto enable Postgres). -
DB_SSL_MODE,DB_SSL_CERT_MODEfor Postgres SSL settings. - Secrets variants:
DB_NAME_FILE,DB_USER_FILE,DB_PASSWORD_FILE.
Database (SQLite tuning)
-
SQLITE_BUSY_TIMEOUT_SECONDS(default 30). -
SQLITE_JOURNAL_MODE(defaultWAL). -
SQLITE_SYNCHRONOUS(defaultNORMAL).
Redis and cache
-
REDIS_URL(defaultredis://localhost:6379). -
REDIS_PREFIX(optional prefix for keys and Celery queues).
Web server (gunicorn)
-
WEB_CONCURRENCY(default 2). Number of gunicorn worker processes. -
GUNICORN_THREADS(default 4). Threads per worker; total concurrent requests = workers x threads. Keep at least 2 workers so a single slow request can't stall the UI.
Celery and scheduling
-
HEALTHCHECK_CELERY_PING_TIMEOUT(seconds). -
DAILY_DIGEST_HOUR(hour for daily digest task). -
ENV_DEBUG=True(container-only) to run Celery with DEBUG log level insupervisord.
Feature flags
-
RUNTIME_POPULATION_DISABLED(bool). -
RUNTIME_POPULATION_ON_STARTUP(bool).
Integrations and providers
- TMDB:
TMDB_API,TMDB_API_FILE,TMDB_NSFW,TMDB_LANG. - TVDB:
TVDB_API_KEY,TVDB_API_KEY_FILE,TVDB_PIN(subscriber PIN; only for user-supported keys),TVDB_PIN_FILE. - MyAnimeList:
MAL_API(Client ID),MAL_API_FILE,MAL_NSFW. - MangaUpdates:
MU_NSFW. - IGDB:
IGDB_ID,IGDB_ID_FILE,IGDB_SECRET,IGDB_SECRET_FILE,IGDB_NSFW. - BoardGameGeek:
BGG_API_TOKEN,BGG_API_TOKEN_FILE. - Hardcover:
HARDCOVER_API,HARDCOVER_API_FILE. - ComicVine:
COMICVINE_API,COMICVINE_API_FILE. - Steam:
STEAM_API_KEY,STEAM_API_KEY_FILE. - Trakt:
TRAKT_API,TRAKT_API_FILE,TRAKT_API_SECRET,TRAKT_API_SECRET_FILE. - Simkl:
SIMKL_ID,SIMKL_ID_FILE,SIMKL_SECRET,SIMKL_SECRET_FILE. - AniList:
ANILIST_ID,ANILIST_ID_FILE,ANILIST_SECRET,ANILIST_SECRET_FILE. - Plex:
PLEX_CLIENT_IDENTIFIER,PLEX_PRODUCT,PLEX_DEVICE,PLEX_PLATFORM,PLEX_PLATFORM_VERSION,PLEX_SSL_VERIFY,PLEX_SECTIONS_TTL_HOURS,PLEX_HISTORY_PAGE_SIZE,PLEX_HISTORY_MAX_ITEMS. - Last.fm:
LASTFM_API_KEY,LASTFM_POLL_INTERVAL_MINUTES. - Pocket Casts (debug):
POCKETCASTS_DEBUG_UUID,POCKETCASTS_INFER_DEBUG. - Audiobookshelf: no global env vars; server URL and API token are stored per user in the database after connecting in Settings → Integrations.
Authentication
-
SOCIAL_PROVIDERS(comma-separated allauth provider modules). -
SOCIALACCOUNT_PROVIDERS(JSON string) orSOCIALACCOUNT_PROVIDERS_FILE. -
SOCIALACCOUNT_ONLY(bool) to disable local auth. -
REDIRECT_LOGIN_TO_SSO(bool) to auto-redirect when only one SSO provider exists. -
REGISTRATION(bool) to enable/disable new user signups. -
DEMO_ACCOUNT_ENABLED(bool, defaults toTrue) provisions a publicly knowndemo/demodemoaccount after migrations. Set it toFalseon any instance that is not a public demo.
Docker secrets
These variables support *_FILE variants that read from /run/secrets/ by default:
-
SECRET,DB_NAME,DB_USER,DB_PASSWORD -
TMDB_API,MAL_API,IGDB_ID,IGDB_SECRET -
TVDB_API_KEY,TVDB_PIN -
BGG_API_TOKEN,STEAM_API_KEY -
HARDCOVER_API,COMICVINE_API -
TRAKT_API,TRAKT_API_SECRET -
ANILIST_ID,ANILIST_SECRET,SIMKL_ID,SIMKL_SECRET SOCIALACCOUNT_PROVIDERS
These are the provider-specific setup notes carried over from the legacy Media Import Configuration page. For usage details, see Integrations and Import Overview.
Trakt
- Public import: enter your Trakt username.
- Private import (OAuth): create a Trakt app and set redirect URI to
https://your_domain.com/import/trakt/private. - Required env vars:
TRAKT_API(client ID) andTRAKT_API_SECRET(client secret).
Simkl
- OAuth import only.
- Create an app at https://simkl.com/settings/developer/ and set redirect URI to
https://your_domain.com/import/simkl_private. - Required env vars:
SIMKL_ID,SIMKL_SECRET.
AniList
- Public import: enter your AniList username.
- Private import (OAuth): create an app at https://anilist.co/settings/developer and set redirect URI to
https://your_domain.com/import/anilist/private. - Required env vars:
ANILIST_ID,ANILIST_SECRET.
Steam
- Requires a Steam Web API key from https://steamcommunity.com/dev/apikey.
- Use your Steam ID64 as the import identifier. Your Steam profile must be public.
MyAnimeList
- Create an app at https://myanimelist.net/apiconfig and use the Client ID as your
MAL_APIkey. -
App Redirect URL: Set to
https://localhost(recommended default). -
Homepage URL: Set to your external Floppy address (e.g.,
https://floppy.yourdomain.com). - No Client Secret is required for standard metadata access.
Floppy supports a CSV format for bulk imports. Each row represents a media entry.
| Column | Required | Example | Notes |
|---|---|---|---|
media_id |
No | 12345 |
Provider ID. Must be unique per (source, media_type); leave blank to resolve by title. |
source |
Yes | tmdb |
One of: tmdb, mal, mangaupdates, igdb, openlibrary, hardcover, comicvine, manual. |
media_type |
Yes | movie |
One of: tv, season, episode, movie, anime, manga, game, book, comic. |
title |
No | Inception |
Leave blank to fetch by media_id. |
image |
No | https://image.tmdb.org/t/p/w500/... |
Optional poster/cover URL. |
season_number |
Cond. | 2 |
Required when media_type=season; also required with episode_number for episodes. |
episode_number |
Cond. | 5 |
Required when media_type=episode. |
score |
No | 8.5 |
Decimal 0-10 (stored as 0-100 internally). |
status |
Yes | Completed |
One of: Completed, In progress, Planning, Paused, Dropped. |
notes |
No | Watched in cinema |
Free-text notes. |
start_date |
No | 2023-01-16 03:56:13+00:00 |
ISO-8601 timestamp with timezone. |
end_date |
No | 2023-02-10 22:15:00+00:00 |
ISO-8601 timestamp with timezone. |
progress |
No | 10 |
Numeric progress (chapters, pages, minutes). Ignored for TV/Season rows. |
Floppy ships as a prebuilt image and runs with nginx, gunicorn, Celery worker, and Celery beat under supervisord.
Image and tags
-
ghcr.io/dannyvfilms/floppy:latest(default) - Also available:
:releaseand:dev
Compose defaults
-
docker-compose.ymlruns Floppy + Redis, maps port 8000, and stores SQLite in./db. -
docker-compose.postgres.ymladds Postgres and uses apostgres_datavolume.
Unraid
- Deploy the README's Docker Compose (SQLite) example as a single Portainer stack (via Unraid's Portainer plugin) rather than installing the app from a Community Applications template and standing up Redis as a separate container — one stack keeps both containers, their restart policy, and their volumes together as one unit.
-
PUID/PGIDdefault to1000/1000in the example; change them to match your Unraid user (often99/100) if you see permission errors on the mounted volumes. - Point volumes at your
appdatashare, e.g./mnt/user/appdata/floppy/db, instead of a relative./dbpath. - See the README's Docker Compose section for the full copy-pasteable stack and env var example.
Build metadata and fork owner
- Docker build args:
VERSIONandCOMMIT_SHAbecome env vars inside the container. - The Dockerfile reads git
originand writes/etc/floppy/fork_owner; settings uses this ifFORK_OWNER_NAMEis not set.
Entrypoint behavior
- Runs
python manage.py migrate --noinputon startup. - Applies
PUID/PGIDownership to/floppy,db,staticfiles, and nginx directories. - Starts supervisord (nginx, gunicorn, celery worker, celery beat).
Common pitfalls
- 403 behind reverse proxy: set
URLS(orCSRF+ALLOWED_HOSTS). - No sessions / background tasks: ensure Redis is reachable and
REDIS_URLis correct. - Admin not available: set
ADMIN_ENABLED=Trueand restart.
Floppy uses SQLite by default. If DB_HOST is set, it switches to Postgres.
SQLite (default)
- Database lives at
src/db/db.sqlite3in local dev and./dbvolume in Docker. - Tuned via environment variables:
-
SQLITE_JOURNAL_MODE(defaultWAL) -
SQLITE_SYNCHRONOUS(defaultNORMAL) -
SQLITE_BUSY_TIMEOUT_SECONDS(default 30)
-
- The app includes a retry middleware for SQLite lock and disk I/O errors (GET requests only).
Postgres
- Set
DB_HOST,DB_NAME,DB_USER,DB_PASSWORD,DB_PORTto enable Postgres. -
docker-compose.postgres.ymlprovides a ready-to-run Postgres container. - SSL settings:
DB_SSL_MODE,DB_SSL_CERT_MODE.
Migration guidance
- There is no built-in SQLite -> Postgres migration helper; plan a backup and use standard Django tooling if you migrate.
- Sessions use the Redis cache backend (
SESSION_ENGINE=cache). - Redis is required for background tasks and caching even if you use SQLite.
-
REDIS_PREFIXcan be used to isolate keys when sharing Redis across apps. - Health checks for Redis (and Celery) are exposed at
/health/.
Celery handles imports, history/statistics caching, runtime backfills, and scheduled jobs.
What runs in the background
- Import tasks (Trakt, Simkl, AniList, Steam, Plex, Pocket Casts, Last.fm, CSV, etc.).
- History and statistics cache refreshes.
- Runtime and genre backfills for missing metadata.
- Calendar reloads and release notifications (from
eventstasks).
Scheduling
-
Reload calendarruns every 24 hours. -
Send release notificationsruns every 10 minutes. -
Send daily digestruns atDAILY_DIGEST_HOUR. -
Plex watchlist syncruns every 15 minutes when watchlist sync is enabled for at least one user. -
Nightly metadata quality backfillruns nightly to fill in missing metadata fields (genres, runtimes, game time-to-beat lengths, etc.) for items that lack them.
Runtime population
- Controlled by
RUNTIME_POPULATION_DISABLEDandRUNTIME_POPULATION_ON_STARTUP. - Startup scheduling is guarded to avoid running when Redis is unavailable.
Health checks and verification
-
/health/includes a Celery ping check. - In Docker, check logs for
celeryandcelery-beatprocesses under supervisord.
Host under subpath
- Set
BASE_URLto a path like/floppy(no trailing slash). - This updates
FORCE_SCRIPT_NAME, static URLs, and cookie paths.
Reverse proxies and CSRF
- Use
URLS(orCSRF+ALLOWED_HOSTS) to avoid 403 errors behind Nginx/Traefik/Caddy.
Self-signed certificates
- Set
REQUESTS_CA_BUNDLEto a CA bundle path so requests can verify self-signed certs.
Docker secrets
- See the
*_FILEvariables in Environment Variables.
Floppy uses django-allauth for social auth and OIDC.
Getting started
- Set
SOCIAL_PROVIDERSto enable provider modules. - Set
SOCIALACCOUNT_PROVIDERSto configure providers (JSON string orSOCIALACCOUNT_PROVIDERS_FILE).
Example: OpenID Connect (Authelia)
SOCIAL_PROVIDERS=allauth.socialaccount.providers.openid_connect
SOCIALACCOUNT_PROVIDERS={"openid_connect":{"OAUTH_PKCE_ENABLED":true,"APPS":[{"provider_id":"authelia","name":"Authelia","client_id":"your-client-id","secret":"your-client-secret","settings":{"server_url":"https://authelia.yourdomain.com/.well-known/openid-configuration"}}]}}
Example: GitHub
SOCIAL_PROVIDERS=allauth.socialaccount.providers.github
SOCIALACCOUNT_PROVIDERS={"github":{"SCOPE":["user","repo","read:org"]}}
Provider setup notes
- OIDC redirect URI format:
https://floppy.yourdomain.com/accounts/oidc/<provider_id>/login/callback/
Linking social accounts to an existing user
- Log in with local credentials.
- Settings -> Accounts -> Manage Account Connections.
Options
-
SOCIALACCOUNT_ONLY=Truedisables local auth. -
REDIRECT_LOGIN_TO_SSO=Trueauto-redirects when only one provider is available. -
REGISTRATION=Falsedisables new user signup.