Deploy Castopod

Self-hosted podcast hosting with Fediverse support

Deploy Castopod

Just deployed

/var/lib/mysql

Just deployed

/app/public/media

Castopod

Self-hosted podcast hosting platform for creators who want to own their data. Upload episodes, manage your show notes, publish to the Fediverse, and get analytics — no ad trackers, no SaaS lock-in.

Two services: Castopod (web app) + MariaDB (database).

Deploy and Host

Host your own Castopod on Railway. This template provisions the all-in-one Castopod container (FrankenPHP + Caddy + s6-overlay under the hood) and a MariaDB companion for persistence. Podcast audio/artwork and app state persist in a Railway volume at /app/public/media.

Deploy to Railway

Why Deploy

Castopod is the open-source backend that powers the Castopod service used by podcasters. Running it on Railway gives you a durable, auto-updating, globally reachable instance with:

  • Full data ownership — audio, artwork, and DB live on your Railway volume.
  • ActivityPub fediverse support — engage with the fediverse from your own instance.
  • REST API — publish episodes programmatically (see the Castopod plugin ecosystem).
  • Two-factor auth — optional TOTP (toggle per instance).
  • No ad stack — plain self-hosted software, your analytics.

Common Use Cases

  • Solo podcasters who want to move away from SaaS and own their episode archive
  • Fediverse-engaged shows — republish to the fediverse from one control panel
  • API-first producers — drive uploads from your editor or a custom pipeline
  • Community hosts — offer your members a private Castopod instance

Deployment Dependencies

The deploy form pre-fills all companion variables (DB host / name / user / password are wired to the MariaDB service via private-domain references — nothing to type).

After the first successful deploy:

  1. Open https:///cp-install — the setup wizard ("Create your Super Admin")
  2. Set your admin email and password — you become the first (and by default the only) admin user
  3. The same site is now both your admin dashboard and your public player — there is no separate admin panel

No OAuth app, no external service, no key-pair registration — the app ships with what it needs.

Architecture

  • Castopod (all-in-one) — runs FrankenPHP + Caddy under s6-overlay. Three s6 services: bootstrap (renders /app/.env from the CP_* variables and runs migrations), frankenphp (serves the web app on :8080, health at /health), and supercronic (cron for background jobs incl. queue drain). Persists to /app/public/media.
  • MariaDB 12.1 — database companion. Persists to /var/lib/mysql (volume). Castopod connects over the Railway private network using the companion-mapping references.

Redis is not required — Castopod defaults to file cache and the supercronic service handles periodic jobs. To add Redis later, deploy a separate Redis service and set CP_REDIS_HOST / CP_REDIS_PASSWORD.

Features

  • Episode & person management — upload, edit, publish, unpublish, and reorder episodes
  • REST API v1 — drive Castopod from scripts or editors
  • ActivityPub — native fediverse engagement (needs TLS — Railway provides it)
  • Two-factor authentication — TOTP, enabled by default
  • Web dashboard — plain PHP/CodeIgniter stack, no build step
  • Analytics — episode plays, uniques, geo distribution (opt in with CP_ANALYTICS_SALT)
  • Custom domain support — set CP_BASEURL to your custom domain after deploy

Dependencies for

This is a two-service template:

ServiceImageVersionRole
castopodcastopod/castopod1.15.5All-in-one web + s6 (bootstrap / frankenphp / supercronic)
mariadbmariadb12.1MySQL-compatible database companion

About Hosting

  • Castopod service — web front-end on port 8080, health at /health. The s6 bootstrap one-shot runs php spark castopod:database-update (migrations) and php spark cache:clear before frankenphp starts. /app/public/media must be writable by the pod — running as root (uid 0) with the root-owned volume is the pattern that works on Railway.
  • MariaDB service:3306, CP_DATABASE_USERNAME/CP_DATABASE_PASSWORD credentials are injected by the template (wired to the MariaDB service's MYSQL_USER/MYSQL_PASSWORD). The mariadb image's own entrypoint handles volume-owning (no wrapper needed).

Volume sizing: For a personal show, a 20 GB Railway volume is plenty. For a multi-year archive, size to your expected audio size (roughly 45 MB/min for a 64 kbps stereo mp3, so a 1-hour episode is about 90 MB).

Configuration

All variables shown in the deploy form are pre-wired; the only two you may want to override are the DB credentials (already auto-generated) and the optional SMTP / media-domain block.

VariableRequiredDescription
CP_BASEURLYesPublic URL of this service (trailing slash). Auto-filled from the public domain.
CP_ANALYTICS_SALTYes64-char random string for analytics hashing. Auto-generated.
RAILWAY_RUN_UIDYesMust be 0 (root) so the root-owned volume is writable by the s6 services.
CP_DATABASE_HOSTNAMENoDefault: ${{mariadb.RAILWAY_PRIVATE_DOMAIN}}
CP_DATABASE_NAMENoDefault: ${{mariadb.MYSQL_DATABASE}}
CP_DATABASE_USERNAMENoDefault: ${{mariadb.MYSQL_USER}}
CP_DATABASE_PASSWORDNoDefault: ${{mariadb.MYSQL_PASSWORD}}
CP_MEDIA_BASEURLNoSeparate domain for media (e.g. S3 or CDN). Leave empty to use CP_BASEURL.
CP_ENABLE_2FANotrue/false. Default false. Set true to require TOTP 2FA at login.
CP_EMAIL_FROMNoSMTP From address.
CP_EMAIL_SMTP_HOSTNoSMTP host.
CP_EMAIL_SMTP_USERNAMENoSMTP user.
CP_EMAIL_SMTP_PASSWORDNoSMTP password.

Quick Start

  1. Deploy via the button above.
  2. Wait ~90 seconds for both services to reach Running.
  3. Open https:///cp-install and create your Super Admin (email + password).
  4. Create your first podcast, upload your first episode, done.

How to Add Podcasts

The deployed site is the entire product — one URL serves three things:

  • Public playerhttps:/// lists all podcasts with a built-in web player
  • Admin dashboard — same site, sign in with your Super Admin credentials
  • RSS feeds — each podcast exposes an RSS feed you can subscribe to in any podcast app (Apple Podcasts, Overcast, Pocket Casts, etc.)

Adding content:

  1. Sign in on the public site → Add a Podcast: name, author, description, cover art, slug (this slug becomes the @{podcastHandle} in all URLs)
  2. Open that podcast → Add Episode: upload the audio file (MP3 recommended), set title/description/date → publish
  3. Audio files are stored on the /app/public/media volume, so they survive redeploys
  4. Each podcast's RSS feed is at https:///@{podcastHandle>/feed.xml — copy this URL into any podcast app (Apple Podcasts, Overcast, Pocket Casts, etc.) to subscribe

Tip: use a strong password for the Super Admin account — it is the only credential for this instance and there is no recovery UI once set.

License

Castopod is open source under AGPL-3.0.


Template Content

More templates in this category

View Template
Pixelfed
Explore + Share beautiful photos and videos on the Fediverse

Evan Boehs
29
View Template
Hexo
Hexo — fast static blog framework with admin editor and S3 media storage

INAPP
1
View Template
Bluesky PDS (Atproto Spaces Alpha)
"The Atproto Spaces Alpha" version of Bluesky PDS.

mkizka
2