Self-Hosting Castopod with Docker Compose
What Is Castopod?
Castopod is an open-source podcast hosting platform with a unique twist: it’s ActivityPub-native, meaning your podcast becomes a federated social account. Followers on Mastodon, Pleroma, or any Fediverse platform can interact with your episodes directly. Beyond federation, it covers everything a podcast host needs — RSS feed generation, episode management, analytics, and multi-podcast support. It replaces Anchor, Buzzsprout, and Podbean. Official site
Why Self-Host Your Podcast?
Commercial podcast hosts charge $12-24/month, limit storage or bandwidth, and own the relationship with podcast directories. Self-hosting means:
- Unlimited episodes and storage (your hardware)
- Full analytics without platform gatekeeping
- Your own RSS feed URL that never changes (even if you switch hosts)
- ActivityPub integration for direct audience engagement
- No platform taking a cut of your sponsorship revenue
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 1 GB of free RAM
- Storage for audio files (plan 100 MB per episode hour at 128 kbps)
- A domain name (required for RSS feeds and ActivityPub)
Docker Compose Configuration
services:
castopod-db:
image: mariadb:11.4
container_name: castopod-db
environment:
MYSQL_ROOT_PASSWORD: change-this-root-password
MYSQL_DATABASE: castopod
MYSQL_USER: castopod
MYSQL_PASSWORD: change-this-db-password
volumes:
- castopod-db:/var/lib/mysql
networks:
- castopod
restart: unless-stopped
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
castopod-redis:
image: redis:7.4-alpine
container_name: castopod-redis
volumes:
- castopod-redis:/data
networks:
- castopod
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
castopod:
image: castopod/castopod:1.15.5
container_name: castopod
ports:
- "8080:8080"
environment:
CP_BASEURL: https://podcast.example.com
CP_MEDIA_BASEURL: https://podcast.example.com
CP_ADMIN_GATEWAY: cp-admin # Admin panel URL path
CP_AUTH_GATEWAY: cp-auth # Authentication URL path
CP_DATABASE_HOSTNAME: castopod-db
CP_DATABASE_NAME: castopod
CP_DATABASE_USERNAME: castopod
CP_DATABASE_PASSWORD: change-this-db-password
CP_CACHE_HANDLER: redis
CP_REDIS_HOST: castopod-redis
CP_REDIS_PORT: 6379
volumes:
- castopod-media:/var/www/castopod/public/media
networks:
- castopod
depends_on:
castopod-db:
condition: service_healthy
castopod-redis:
condition: service_healthy
restart: unless-stopped
networks:
castopod:
volumes:
castopod-db:
castopod-redis:
castopod-media:
Start Castopod:
docker compose up -d
Initial Setup
- Navigate to
http://your-server:8080/cp-install - Complete the installation wizard:
- Set your instance name
- Create the super admin account
- Configure your podcast metadata
- After install, the admin panel is at
/cp-admin - Create your first podcast: fill in title, description, cover art, and category
- Upload your first episode with title, description, and audio file
Key Features
| Feature | Details |
|---|---|
| Multi-podcast | Host multiple shows from one instance |
| RSS feed | Auto-generated, compliant with Apple/Spotify/Google specs |
| ActivityPub | Your podcast is a Fediverse account — followers interact directly |
| Analytics | Download stats, geographic data, listening apps, episode trends |
| Chapters | Podcast 2.0 chapter markers with images and links |
| Transcripts | Upload SRT/VTT transcripts for accessibility |
| Soundbites | Highlight clips for social sharing |
| Video podcasts | Upload video episodes alongside audio |
| Monetization | Podcast Value (Value4Value), funding links |
| Multi-user | Contributors, editors, admin roles per podcast |
| Embeddable player | Embed episodes on any website |
ActivityPub Integration
Castopod’s ActivityPub support means:
- Each podcast gets a Fediverse handle (e.g.,
@[email protected]) - New episodes appear as posts in followers’ timelines
- Followers can comment, boost, and interact from Mastodon or any ActivityPub platform
- Comments from the Fediverse appear on your episode page
- No separate social media management needed — your podcast IS your social presence
This is unique to Castopod. No other podcast host integrates with the Fediverse natively. For more on ActivityPub, see The Fediverse Explained.
Podcast Directory Submission
After creating your podcast and publishing at least one episode, submit your RSS feed to directories:
| Directory | Submission URL | Turnaround |
|---|---|---|
| Apple Podcasts | podcasters.apple.com | 1-5 days |
| Spotify | podcasters.spotify.com | 1-3 days |
| Google Podcasts | podcastsmanager.google.com | 2-5 days |
| Pocket Casts | pocketcasts.com/submit | Automatic |
| Podcast Index | podcastindex.org/add | Automatic |
Your RSS feed URL: https://podcast.example.com/@yourshow/feed.xml
Reverse Proxy
Behind Nginx Proxy Manager:
Proxy Host: podcast.example.com → http://castopod:8080
Enable: WebSocket Support, Force SSL
Set CP_BASEURL to your public URL including https://. This is critical — the RSS feed and ActivityPub federation use this URL.
Backup
| Volume | Contains | Priority |
|---|---|---|
castopod-db | Episodes, analytics, user accounts, settings | Critical |
castopod-media | Audio files, cover art, transcripts | Critical |
castopod-redis | Cache (regenerated automatically) | Low |
The media volume is your most space-intensive backup target. Each episode hour at 128 kbps ≈ 60 MB.
# Database backup
docker exec castopod-db mariadb-dump -u castopod -p'change-this-db-password' castopod > castopod-backup-$(date +%Y%m%d).sql
# Media backup (rsync to backup location)
rsync -av /var/lib/docker/volumes/castopod-media/_data/ /backup/castopod-media/
See Backup Strategy for automated approaches.
Troubleshooting
Install wizard shows 500 error
Symptom: /cp-install returns a server error.
Fix: Check that MariaDB is healthy (docker logs castopod-db). Ensure CP_DATABASE_PASSWORD matches in both containers. Check Castopod logs: docker logs castopod.
ActivityPub federation not working
Symptom: Podcast has a Fediverse handle but nobody can find or follow it.
Fix: CP_BASEURL must match your actual public URL exactly (including https://). ActivityPub requires HTTPS. Verify .well-known/webfinger is accessible: curl https://podcast.example.com/.well-known/webfinger?resource=acct:[email protected].
Audio files won’t upload
Symptom: Episode upload fails or times out.
Fix: Check the castopod-media volume has sufficient space. For large files, increase your reverse proxy upload limit (Nginx: client_max_body_size 500M). PHP max upload size inside the container defaults to 150 MB.
RSS feed not validating
Symptom: Apple Podcasts or Spotify rejects your feed.
Fix: Ensure cover art is at least 1400×1400 pixels (Apple requirement). Check your podcast has a valid category set. Test your feed at https://podba.se/validate/.
Resource Requirements
- RAM: ~250 MB idle (Castopod + MariaDB + Redis), ~500 MB during file processing
- CPU: Low — audio transcoding is not done server-side (upload pre-encoded files)
- Disk: 500 MB for application, plus ~60 MB per episode hour of audio
Verdict
Castopod is the best self-hosted podcast platform, and the ActivityPub integration is genuinely compelling. Your podcast becomes a first-class Fediverse citizen — no separate social media strategy needed. For podcasters who just need RSS hosting without the social features, AzuraCast covers radio streaming with podcast RSS as a secondary feature. But if you’re starting a podcast in 2026, Castopod’s Fediverse-native approach is the most forward-looking option.
Frequently Asked Questions
What does ActivityPub integration mean for my podcast?
Your Castopod podcast becomes a Fediverse account that Mastodon, Pleroma, and Pixelfed users can follow. When you publish a new episode, it appears in their feeds as a post. Followers can comment, boost, and interact directly — your podcast has built-in social engagement without needing separate social media accounts.
Can I import my podcast from Anchor or another host?
Yes. Castopod supports importing podcasts via RSS feed URL. Enter your existing podcast’s RSS feed during setup, and Castopod downloads all episode metadata and audio files. After import, update your podcast directories (Apple, Spotify, etc.) to point to Castopod’s RSS feed URL for a seamless migration.
Does Castopod submit my podcast to Apple Podcasts and Spotify?
No. Castopod generates a standard RSS feed that you manually submit to podcast directories. Go to Apple Podcasts Connect, Spotify for Podcasters, and other platforms, and submit your Castopod RSS URL. Once accepted, new episodes automatically appear on those platforms through the feed.
Can Castopod host multiple podcasts?
Yes. A single Castopod instance can host multiple podcasts, each with its own RSS feed, analytics, and Fediverse presence. This is useful if you run multiple shows — manage them all from one dashboard without separate installations.
Does Castopod include analytics?
Yes. Castopod has built-in analytics that track downloads, listening duration, geographic distribution, and user agents — all without third-party trackers. The analytics comply with IAB Podcast Measurement Guidelines for accurate download counting. Data stays on your server.
What audio format should I upload to Castopod?
Upload pre-encoded MP3 files (128-192 kbps for talk, 256-320 kbps for music). Castopod does not transcode audio server-side — it serves exactly what you upload. MP3 is the universal standard for podcast distribution and works everywhere. Include proper ID3 tags (title, artist, artwork) before uploading.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments