← Templates · Applications
CA

Castopod

Verified

3 services

Castopod, the open-source podcast hosting platform — publish episodes, track real analytics, and own your RSS feed instead of renting it.

Deploy Castopod

Runs3 services
Stack castopodcastopod-dbcastopod-redis
Provisioned for itNothing, it's self-contained
VerifiedYes, deployed end to end by the Railyard team

Why deploy on Railyard

Railyard provisions all 3 services in this stack together — castopod, castopod-db, castopod-redis — wired to reach each other over the private network, on a server you already pay for.

Deploying Castopod is one piece of a bigger stack you can keep building — add a database, a worker, a cache, or another app, all on the same servers you already pay for.

Good for

  • Self-hosted podcast hosting with your own RSS feed and real listener analytics
  • Podcasting 2.0 features (transcripts, chapters, value4value) without a third-party host

Good to know

  • MariaDB and Redis are wired up automatically
  • HTTPS is required by default (mandatory to federate with the fediverse) — Railyard terminates TLS in front of this app, so that's already satisfied
  • Uploaded media lives on a dedicated volume — plan real disk space for audio files
  • Its own image runs as non-root (www-data) and needs to chown /run on boot — disable_no_new_privileges is required or the container fatals out (s6-overlay-suexec: child failed with exit code 100), same class of fix as Jitsi's services
  • Castopod's own image already generates its real .env from the documented CP_* env vars this template sets (s6-overlay's prepare-environment.sh bootstrap script runs on every boot) — no Railyard config-writing primitive needed. An earlier investigation wrongly concluded CP_* names were incompatible with Castopod's dotted-key config; that was based on a flawed diagnostic (`railyard run` spins up a brand-new one-off container, not an exec into the live one, so its own entrypoint — and the .env generation — never ran). The only real bugs were disable_no_new_privileges (above) and a MariaDB container occasionally getting killed mid-first-boot under heavy host CPU contention (interrupts user/grant creation, producing 'Host X is not allowed to connect' until the volume is wiped and redeployed clean) — confirmed live end to end: a real HTTP 200 with the real page title.

Project docs ↗