Technology Encyclopedia Home >Host Your Own Podcast with Castopod on a VPS — Full Control Over Your Podcast Feed and Analytics

Host Your Own Podcast with Castopod on a VPS — Full Control Over Your Podcast Feed and Analytics

Most podcast hosting platforms charge per-download, limit your episode storage, or take a cut if you monetize. If you have a cloud server, you can host your own podcast for the cost of the server — unlimited episodes, no per-download fees, your RSS feed lives on your domain, and you own every byte of your audience data.

Castopod is an open-source podcast hosting platform built specifically for self-hosting. It handles episode uploads, RSS feed generation, episode pages, a built-in player, podcast analytics, and even ActivityPub support so your podcast can be followed on Mastodon and other fediverse platforms.

I host my podcast on Tencent Cloud Lighthouse. The 2 GB RAM / 2 vCPU plan handles Castopod comfortably. Two Lighthouse features matter particularly for podcast hosting: CBS cloud disk expansion for audio file storage (a year of weekly 60-minute episodes at 128kbps is roughly 3 GB — small now, but it grows), and the bandwidth allowance for episode downloads. Lighthouse's fixed monthly bandwidth means listener download traffic doesn't generate variable per-GB charges.


Table of Contents

  1. Why Self-Host a Podcast?
  2. What You Need
  3. Part 1: Install the LEMP Stack
  4. Part 2: Install Castopod
  5. Part 3: Configure Nginx and SSL
  6. Part 4: Complete the Web Setup
  7. Part 5: Create Your First Episode
  8. Part 6: Submit to Apple Podcasts, Spotify, and Others
  9. The Thing That Tripped Me Up
  10. Troubleshooting
  11. Summary

  • Key Takeaways
  • Use the appropriate Lighthouse application image to skip manual installation steps where available
  • Lighthouse snapshots provide one-click full-server backup before major changes
  • OrcaTerm browser terminal lets you manage the server from any device
  • CBS cloud disk expansion handles growing storage needs without server migration
  • Console-level firewall + UFW = two independent protection layers

Why Self-Host a Podcast? {#why}

Running Castopod on your own server gives you:

  • No per-download fees — your costs are fixed regardless of how many people listen
  • Unlimited episodes and storage — limited only by your server's disk
  • Your own RSS feed URLpodcast.yourdomain.com/feed.xml, not a third-party platform URL
  • Complete analytics — download counts, listening duration, geographic distribution
  • Episode pages — each episode gets a web page with a built-in player
  • Monetization on your terms — no platform taking a percentage
  • ActivityPub support — your podcast appears on Mastodon/fediverse platforms
  • Chapter markers — add chapters with URLs and images to episodes

What You Need {#prerequisites}

Requirement Details
Server Ubuntu 22.04, 2 GB+ RAM
Domain Required — podcast feed URL and episode pages
PHP 8.1+
MySQL 8.0+
Storage Plan for episode file storage (60–100 MB per hour of audio)

Part 1: Install the LEMP Stack {#part-1}

1.1 — Install Nginx

sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx

1.2 — Install MySQL

sudo apt install -y mysql-server
sudo systemctl enable mysql
sudo mysql_secure_installation

Create a database for Castopod:

sudo mysql -u root -p
CREATE DATABASE castopod CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'castopod'@'localhost' IDENTIFIED BY 'your-secure-password';
GRANT ALL PRIVILEGES ON castopod.* TO 'castopod'@'localhost';
FLUSH PRIVILEGES;
EXIT;

1.3 — Install PHP 8.1 and Extensions

sudo apt install -y software-properties-common
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
sudo apt install -y php8.1-fpm php8.1-mysql php8.1-xml php8.1-mbstring php8.1-curl php8.1-zip php8.1-gd php8.1-intl php8.1-redis

Configure PHP for uploads:

sudo nano /etc/php/8.1/fpm/php.ini

Update these values:

upload_max_filesize = 512M
post_max_size = 512M
max_execution_time = 300
memory_limit = 512M

Restart PHP-FPM:

sudo systemctl restart php8.1-fpm

Part 2: Install Castopod {#part-2}

2.1 — Download Castopod

cd /var/www
sudo wget https://code.castopod.org/adaures/castopod/-/releases/permalink/latest/downloads/castopod-package.zip
sudo apt install -y unzip
sudo unzip castopod-package.zip -d castopod
sudo rm castopod-package.zip

2.2 — Set Permissions

sudo chown -R www-data:www-data /var/www/castopod
sudo find /var/www/castopod -type d -exec chmod 755 {} \;
sudo find /var/www/castopod -type f -exec chmod 644 {} \;

2.3 — Create the .env File

sudo cp /var/www/castopod/.env.example /var/www/castopod/.env
sudo nano /var/www/castopod/.env

Update the database settings:

app.baseURL="https://podcast.yourdomain.com"
database.default.hostname=localhost
database.default.database=castopod
database.default.username=castopod
database.default.password=your-secure-password

Part 3: Configure Nginx and SSL {#part-3}

3.1 — Create Nginx Site

sudo nano /etc/nginx/sites-available/castopod
server {
    listen 80;
    server_name podcast.yourdomain.com;
    root /var/www/castopod/public;

    index index.php;

    # Podcast feed and media files
    client_max_body_size 512M;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }

    # Cache static assets
    location ~* \.(mp3|mp4|ogg|m4a|jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Deny .htaccess access
    location ~ /\.ht {
        deny all;
    }
}
sudo ln -s /etc/nginx/sites-available/castopod /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

3.2 — Get SSL Certificate

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d podcast.yourdomain.com

Part 4: Complete the Web Setup {#part-4}

4.1 — Run the Install Wizard

Navigate to https://podcast.yourdomain.com/cp-install in your browser.

The wizard will:

  1. Check system requirements (all should pass)
  2. Initialize the database (creates tables)
  3. Create your admin account

Fill in:

  • Database credentials (from your .env if not pre-filled)
  • Admin account: email, username, password
  • Instance name: your podcast network name

Click Install Castopod.

4.2 — Access the Admin Panel

After setup, go to https://podcast.yourdomain.com/cp-admin.

Log in with your admin credentials.


Part 5: Create Your First Episode {#part-5}

5.1 — Create a Podcast

In the admin panel:

  1. Podcasts → New Podcast
  2. Fill in: title, description, language, category, author
  3. Upload podcast artwork (3000×3000 px recommended)
  4. Click Save

5.2 — Record and Publish Your First Episode

Prepare your episode:

  • Record and edit audio (any tool — Audacity, GarageBand, etc.)
  • Export as MP3 (128–192 kbps for voice content)
  • Write show notes

In Castopod:

  1. Your Podcast → Episodes → New Episode
  2. Fill in: title, description, episode number
  3. Upload the MP3 file
  4. Add chapter markers (optional but useful)
  5. Set publication date and time
  6. Click Publish

5.3 — Get Your RSS Feed URL

Your podcast RSS feed is at:

https://podcast.yourdomain.com/@yourpodcast/feed.xml

This is the URL you submit to podcast directories.

5.4 — Test Your Feed

Paste the feed URL into podcastpage.io/podcast-validator to check for errors.


Part 6: Submit to Apple Podcasts, Spotify, and Others {#part-6}

Once your feed has at least one episode:

Platform Submission URL
Apple Podcasts podcastsconnect.apple.com
Spotify podcasters.spotify.com
Amazon Music music.amazon.com/podcasts/submit
Google Podcasts podcastsmanager.google.com
Pocket Casts Automatically picks up from Apple Podcasts

Most directories verify your feed within 24–72 hours. Apple Podcasts is the most important submission — many other apps pull from Apple's directory.

For each submission, you'll provide:

  • Your RSS feed URL
  • An Apple/Spotify/Amazon account
  • Brief description for review

The Thing That Tripped Me Up {#gotcha}

After publishing my first episode, the episode page loaded fine, but the audio player wasn't working — clicking play did nothing, and the browser console showed a CORS error.

The cause: my audio files were being served from the same server, but I hadn't set CORS headers in Nginx. Some podcast players and the Castopod web player use JavaScript to fetch audio, which triggers CORS checks.

The fix: Add CORS headers to the Nginx config for audio files:

location ~* \.(mp3|mp4|ogg|m4a)$ {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, HEAD, OPTIONS';
    expires 1y;
    add_header Cache-Control "public";
}

Reload Nginx:

sudo systemctl reload nginx

The player started working immediately. If you plan to embed the player on other websites, CORS headers are essential.


Troubleshooting {#troubleshooting}

Issue Likely Cause Fix
500 error on install PHP extension missing Check php -m for required extensions
Upload fails File size limit Increase upload_max_filesize in php.ini
Audio player not working CORS headers missing Add Access-Control-Allow-Origin: * for audio files
RSS feed returns empty No published episodes Publish at least one episode
Apple Podcasts rejected Feed validation error Test feed at podcastpage.io/podcast-validator
Admin panel inaccessible Wrong base URL Update app.baseURL in .env
Database connection failed Wrong credentials Check .env database settings match MySQL user

Summary {#verdict}

What you built:

  • Self-hosted podcast platform with full admin control
  • RSS feed at your own domain URL
  • Episode pages with built-in web player
  • Podcast analytics (downloads, geography, listening apps)
  • ActivityPub support for fediverse discovery
  • Ready for submission to Apple Podcasts, Spotify, and all major directories

Total ongoing cost: the price of your cloud server, regardless of how many episodes you publish or how many people listen.

Frequently Asked Questions {#faq}

What video formats does Castopod podcast hosting support for streaming?
Modern media servers support most common formats. Direct Play (native format support by client) is preferred over transcoding. H.264 video in MKV or MP4 containers has the widest client support.

What's the difference between Direct Play and Transcoding?
Direct Play streams the original file to the client, requiring no server CPU. Transcoding converts the video in real-time to a compatible format, requiring significant server CPU.

How much bandwidth do I need for video streaming?
Blu-ray quality: 25–40 Mbps. 1080p: 8–25 Mbps. 720p: 3–8 Mbps. Lighthouse bandwidth packages support these rates. For multiple simultaneous streams, multiply accordingly.

How do I add media files to the server?
Upload via SCP/SFTP from your local machine, rsync from a NAS, or download directly on the server. The guide covers the recommended directory structure for automatic library scanning.

How do I access my media library from outside my home network?
Your media server runs on a cloud VPS with a public IP — it's accessible from anywhere. Set up HTTPS (covered in the guide) and use the appropriate client app or web interface.

👉 Get started with Tencent Cloud Lighthouse
👉 View current pricing and launch promotions
👉 Explore all active deals and offers