Skip to content

Configuration

All configuration is by environment variable, set on the container (docker-compose.yml) or the process directly. Everything the app persists lives under DATA_DIR, so a single Docker volume covers credentials, the OAuth token, and the job database.

Several settings below only seed an initial value: once you change them from the app's own pages (Account, Telegram), the stored database value wins from then on, and the environment variable no longer has any effect until the stored value is cleared.

VariableDefaultDescription
DATA_DIRdataRoot folder for everything the app persists: OAuth client secret, token, and the job database.
CLIENT_SECRET_FILE$DATA_DIR/client_secret.jsonPath to the uploaded Google OAuth client JSON — a "Desktop app" client for localhost, a "Web application" one for any other address.
TOKEN_FILE$DATA_DIR/token.jsonPath to the stored OAuth token after sign-in.
DB_FILE$DATA_DIR/transfers.sqlite3SQLite database holding jobs and settings.
APP_HOST0.0.0.0Interface the app binds to.
APP_PORT8000Port the app binds to.
PUBLIC_BASE_URLhttp://localhost:$APP_PORTWhere Google sends the user back after sign-in. Must match the address you actually open in the browser, and <PUBLIC_BASE_URL>/oauth/callback must be registered on the OAuth client. Never derived from the incoming request, so an ingress or reverse proxy cannot fill it in for you — leaving it unset behind one causes redirect_uri_mismatch. See Getting started.
QUOTA_DAILY_LIMIT10000The project's daily YouTube Data API quota, in units. Only seeds the figure shown on the Account page — the value set there is stored in the database and wins from then on. Clamped to a minimum of 50.
QUOTA_RESERVE50Units held back so a run never spends the last of the allocation on an insert it cannot confirm. Set to 0 to spend the allocation to the floor.
QUOTA_RESET_TZAmerica/Los_AngelesTimezone the daily quota resets in. Google's own reset is midnight Pacific.
PLAYLIST_PRIVACYprivatePrivacy of playlists this app creates. One of private, unlisted, public.
SCHEDULER_INTERVAL60Seconds between checks of jobs marked "run this job daily, when credits allow". A cheap local check — the database and the app's own ledger, no API call. Floored at 15 seconds.
INSERT_DELAY0.2Seconds paused between playlist inserts, gentle on the per-second rate limit.
LOG_LEVELINFOHow much the container logs. At INFO it logs one line per playlist mirror started and finished (status, videos added, videos failed, videos left, units spent), one per daily run, and one per Telegram message sent or refused. The per-request access log is off at every level — a page that polls its own status would otherwise bury everything else. WARNING keeps only problems; DEBUG adds the libraries' own chatter.
TELEGRAM_BOT_TOKEN(empty)Only seeds the stored value — see Notifications.
TELEGRAM_CHAT_ID(empty)Only seeds the stored value — see Notifications.
TELEGRAM_TIMEOUT15Seconds to wait on api.telegram.org before giving up. A notification that can't be delivered never holds up the next playlist mirror.
UPDATE_CHECK_URLPlaylist Mirror's latest-release GitHub API URLEndpoint checked for the latest stable release. An invalid or unreachable override quietly disables successful checks.
UPDATE_CHECK_TIMEOUT10Seconds to wait for GitHub before giving up. A failed check never holds up startup or a page.
UPDATE_CHECK_INTERVAL_HOURS24Hours between release checks while the app remains running. Floored at one hour.
UPDATE_CHECK_INITIAL_DELAY5Seconds after startup before the first release check, keeping the request off the startup path.

See docker-compose.yml in the repository for a working example, or Helm for the Kubernetes equivalent.

Self-hosted, single user, single Docker container.