App configuration
PodVault is configured in two places:
- Environment variables (
PODVAULT_*) for deployment settings: paths, the login, backups, timeouts and logging. All of them are optional. - The database for settings you change while it runs: the naming templates and per-podcast schedules. Change these from the web interface or with
podvault configandpodvault schedule.
Environment variables
Section titled “Environment variables”Set them with -e on docker run, under environment: in Compose, or in your shell before podvault serve. The Settings page shows the values in effect.
Login and access
Section titled “Login and access”| Variable | Default | Purpose |
|---|---|---|
PODVAULT_USERNAME |
unset (no login) | Username for the web interface. Set together with PODVAULT_PASSWORD. |
PODVAULT_PASSWORD |
unset (no login) | Password for the web interface. Set both if port 8000 is reachable from other machines. |
PODVAULT_FEED_TOKEN |
derived from the password | Fixed access token for podcast app feed URLs when the login is on. Without it, changing the password revokes old feed URLs. |
PODVAULT_BASE_URL |
taken from each request | Address used in links inside your podcast feeds, e.g. https://podvault.example.com behind a reverse proxy. |
Setting only one of PODVAULT_USERNAME and PODVAULT_PASSWORD is treated as a mistake: every request is refused until both are set (or neither), podvault serve names the missing one when it starts, and the sign-in page explains the problem. See Security for how the login works.
Paths and database
Section titled “Paths and database”| Variable | Default (from source) | Default in Docker | Purpose |
|---|---|---|---|
PODVAULT_DB_PATH |
podvault_data.db |
/app/data/podvault_data.db |
SQLite database file |
PODVAULT_DOWNLOADS_FOLDER |
downloads |
/app/data/downloads |
Where episodes are saved |
PODVAULT_FEEDS_FILE |
feeds.txt |
/app/data/feeds.txt |
Your list of feed URLs |
PODVAULT_DB_TIMEOUT |
30.0 |
30.0 |
Database timeout, in seconds |
Relative paths are relative to the directory you run podvault from. In Docker, the image sets these three to paths under /app/data, so keep them there or make sure the new location is on a mounted volume.
Downloads
Section titled “Downloads”| Variable | Default | Purpose |
|---|---|---|
PODVAULT_DEFAULT_DELAY_SECONDS |
5 |
Pause between episode downloads, to go easy on publishers’ servers |
PODVAULT_DOWNLOAD_TIMEOUT |
30 |
Download timeout, in seconds |
Auto-refresh
Section titled “Auto-refresh”| Variable | Default | Purpose |
|---|---|---|
PODVAULT_SCHEDULER_POLL_INTERVAL_SECONDS |
300 |
How often the scheduler checks for podcasts that are due for a refresh |
The refresh interval itself (6h, 12h, 24h, 7d) is set per podcast, in the web interface or with podvault schedule.
Database backups
Section titled “Database backups”| Variable | Default | Purpose |
|---|---|---|
PODVAULT_BACKUP_ENABLED |
true |
Automatic database backups on or off |
PODVAULT_BACKUP_KEEP |
7 |
How many backups to keep |
PODVAULT_BACKUP_INTERVAL_HOURS |
24 |
Minimum time between automatic backups |
PODVAULT_BACKUP_DIR |
backups/ next to the database (/app/data/backups in Docker) |
Where backups are written |
See Archive safety for how backups work and how to restore one.
Logging
Section titled “Logging”| Variable | Default | Purpose |
|---|---|---|
PODVAULT_LOG_LEVEL |
INFO |
DEBUG, INFO, WARNING, ERROR or CRITICAL |
PODVAULT_LOG_FILE |
unset (console only) | Also write the log to this file |
Example
Section titled “Example”services: podvault: image: martitoci/podvault:latest ports: - "8000:8000" volumes: - ./data:/app/data environment: PODVAULT_USERNAME: admin PODVAULT_PASSWORD: a-long-password PODVAULT_BACKUP_KEEP: "14" PODVAULT_LOG_LEVEL: WARNING restart: unless-stoppedNaming templates
Section titled “Naming templates”PodVault decides where each episode goes with two templates: one for the folder and one for the file name. The defaults are:
| Template | Default |
|---|---|
| Folder | {podcast_name}/{year}/{month}/{episode_label} - {episode_title} |
| File name | {episode_title} - {podcast_name} |
That produces a tree like this:
downloads/└── podcast_name/ └── 2024/ └── 01/ └── 003 - Episode Title/ ├── Episode Title - podcast_name.mp3 ├── episode_image.jpg (if available) └── episode_metadata.xml (original RSS entry)Each episode gets its own folder. The audio keeps its real extension (.mp3, .m4a, .ogg…), and the folder also holds the cover image and the original RSS entry as XML. Your files stay organized and usable without PodVault.
Variables
Section titled “Variables”| Variable | Value |
|---|---|
{podcast_name} |
The podcast’s name |
{episode_title} |
The episode title, or your custom name if you renamed it |
{episode_number} |
Episode number from the feed |
{season_number} |
Season number from the feed |
{year}, {month}, {day} |
Parts of the publication date |
{date} |
The publication date |
{episode_label} |
The episode number zero-padded to 3 digits (003), or the publication date if the feed doesn’t number its episodes |
{episode_label} is a ready-made fallback, so you don’t have to handle unnumbered shows yourself.
- Templates are plain
str.format-style strings. A/in the folder template starts a new folder. - Each folder segment is cleaned up for the file system on its own, and
.and..segments are dropped, so a template can’t write outside the downloads folder. - Templates are checked against two sample episodes before saving, one with numbers and one without. A template that only works when a number is present (like
{episode_number:03d}with no fallback) is rejected right away instead of failing later on a real episode.
Changing the templates
Section titled “Changing the templates”Use the Settings page, which has clickable variables and a live preview, or the CLI:
podvault configpodvault config --folder-template "{podcast_name}/{year}/{episode_label} - {episode_title}"podvault config --filename-template "{episode_number} - {episode_title}"PodVault writes tags to MP3 files (ID3) and M4A/M4B/MP4 files (MP4 tags). Other formats (Ogg/Opus, FLAC, WAV…) are downloaded and archived, but their tags are left as the publisher made them.
Each tagged file gets:
| Tag | Value |
|---|---|
| Title | Episode title (or your custom name) |
| Artist, Album | Podcast name |
| Year | Publication year |
| Track | Episode number, if any |
| Disc | Season number, if any |
| Comment | Episode description |
| Genre | Podcast |
| Cover art | The episode’s image, or the podcast’s cover |
Built-in constants
Section titled “Built-in constants”A few settings aren’t environment variables. They’re constants in podvault/config.py in the source code:
MAX_RETRIES = 3 # Retry attempts for failed downloadsRETRY_DELAY_BASE = 1 # Base delay for exponential backoffRETRY_DELAY_MAX = 60 # Maximum delay for exponential backoffRSS_CACHE_TTL_HOURS = 1 # How long fetched feeds are cachedMAX_FILENAME_LENGTH = 200