Skip to content

6. Admin and Operations

DannyVFilms edited this page Jul 31, 2026 · 8 revisions

Admin Guide

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=True and restart the app.
  • The /admin/ route is only registered when ADMIN_ENABLED is true.

Log in

  • Use a superuser account (both is_staff and is_superuser must be true).
  • Create one with Django:
# Local dev
cd src && python manage.py createsuperuser

# Docker
docker exec -it floppy python manage.py createsuperuser

Promote an existing user to admin

# Local dev
cd src && python manage.py shell
from 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 shell
from 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.

Configuration Overview

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

  • .env files or container environment: blocks.
  • Docker secrets via *_FILE variables (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 (or CSRF + ALLOWED_HOSTS) when using a reverse proxy.
  • Provider keys for metadata/imports (TMDB, MAL, IGDB, BGG, etc.).
  • ADMIN_ENABLED=True if you want /admin/.
  • BASE_URL if hosting under a subpath.
  • Social auth settings if you use SSO.

Jump to sections:

Environment Variables

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). Supports SECRET_FILE for Docker secrets.
  • DEBUG (bool). Keep False in 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). Sets FORCE_SCRIPT_NAME, static URL, and cookie paths.
  • URLS (comma-separated public origins). Appends to CSRF and ALLOWED_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 (set DB_HOST to enable Postgres).
  • DB_SSL_MODE, DB_SSL_CERT_MODE for 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 (default WAL).
  • SQLITE_SYNCHRONOUS (default NORMAL).

Redis and cache

  • REDIS_URL (default redis://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 in supervisord.

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) or SOCIALACCOUNT_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 to True) provisions a publicly known demo / demodemo account after migrations. Set it to False on 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

Import Provider Setup

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) and TRAKT_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

MyAnimeList

  • Create an app at https://myanimelist.net/apiconfig and use the Client ID as your MAL_API key.
  • 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.

CSV Import (Floppy / Yamtrack format)

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.

Docker Deployment

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: :release and :dev

Compose defaults

  • docker-compose.yml runs Floppy + Redis, maps port 8000, and stores SQLite in ./db.
  • docker-compose.postgres.yml adds Postgres and uses a postgres_data volume.

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 / PGID default to 1000/1000 in the example; change them to match your Unraid user (often 99/100) if you see permission errors on the mounted volumes.
  • Point volumes at your appdata share, e.g. /mnt/user/appdata/floppy/db, instead of a relative ./db path.
  • 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: VERSION and COMMIT_SHA become env vars inside the container.
  • The Dockerfile reads git origin and writes /etc/floppy/fork_owner; settings uses this if FORK_OWNER_NAME is not set.

Entrypoint behavior

  • Runs python manage.py migrate --noinput on startup.
  • Applies PUID/PGID ownership to /floppy, db, staticfiles, and nginx directories.
  • Starts supervisord (nginx, gunicorn, celery worker, celery beat).

Common pitfalls

  • 403 behind reverse proxy: set URLS (or CSRF + ALLOWED_HOSTS).
  • No sessions / background tasks: ensure Redis is reachable and REDIS_URL is correct.
  • Admin not available: set ADMIN_ENABLED=True and restart.

Database: SQLite vs Postgres

Floppy uses SQLite by default. If DB_HOST is set, it switches to Postgres.

SQLite (default)

  • Database lives at src/db/db.sqlite3 in local dev and ./db volume in Docker.
  • Tuned via environment variables:
    • SQLITE_JOURNAL_MODE (default WAL)
    • SQLITE_SYNCHRONOUS (default NORMAL)
    • 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_PORT to enable Postgres.
  • docker-compose.postgres.yml provides 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.

Redis and Sessions

  • Sessions use the Redis cache backend (SESSION_ENGINE=cache).
  • Redis is required for background tasks and caching even if you use SQLite.
  • REDIS_PREFIX can be used to isolate keys when sharing Redis across apps.
  • Health checks for Redis (and Celery) are exposed at /health/.

Celery and Background Tasks

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 events tasks).

Scheduling

  • Reload calendar runs every 24 hours.
  • Send release notifications runs every 10 minutes.
  • Send daily digest runs at DAILY_DIGEST_HOUR.
  • Plex watchlist sync runs every 15 minutes when watchlist sync is enabled for at least one user.
  • Nightly metadata quality backfill runs 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_DISABLED and RUNTIME_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 celery and celery-beat processes under supervisord.

Hosting and Security

Host under subpath

  • Set BASE_URL to a path like /floppy (no trailing slash).
  • This updates FORCE_SCRIPT_NAME, static URLs, and cookie paths.

Reverse proxies and CSRF

  • Use URLS (or CSRF + ALLOWED_HOSTS) to avoid 403 errors behind Nginx/Traefik/Caddy.

Self-signed certificates

  • Set REQUESTS_CA_BUNDLE to a CA bundle path so requests can verify self-signed certs.

Docker secrets

Social Authentication

Floppy uses django-allauth for social auth and OIDC.

Getting started

  • Set SOCIAL_PROVIDERS to enable provider modules.
  • Set SOCIALACCOUNT_PROVIDERS to configure providers (JSON string or SOCIALACCOUNT_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=True disables local auth.
  • REDIRECT_LOGIN_TO_SSO=True auto-redirects when only one provider is available.
  • REGISTRATION=False disables new user signup.

Clone this wiki locally