Applications AWS

Castopod on AWS User Guide

| Product: Castopod

Castopod on AWS User Guide

Castopod is a free, open source platform for hosting and publishing podcasts. It serves standards-compliant RSS feeds with Podcasting 2.0 tags (chapters, transcripts, funding, location), hosts multiple podcasts on one instance, and has ActivityPub built in — every podcast is its own Fediverse account that listeners on Mastodon and other platforms can follow, comment on and share. Privacy-friendly analytics report episode downloads by country and player with no third-party trackers, and embeddable players let you place episodes on any website.

This cloudimg Amazon Machine Image delivers Castopod fully installed and configured on Ubuntu 24.04, so a complete podcast platform is running within minutes of launch. Castopod is a CodeIgniter 4 application on PHP 8.3 with OPcache, served by nginx with php-fpm, backed by MariaDB. The install wizard is already completed — you land directly on the admin sign-in page.

This guide covers connecting to your instance, retrieving the per-instance administrator credentials, signing in, creating your first podcast and episode, and enabling HTTPS.

Castopod admin sign-in page


Architecture at a glance

Component Detail
Application Castopod 1.15 (CodeIgniter 4), served from /var/www/castopod/public
Web server nginx, listening on port 80
PHP PHP 8.3 (php8.3-fpm) with OPcache
Database MariaDB 10.11, datadir on a dedicated EBS volume at /var/lib/mysql
Application storage Code and uploaded media on a dedicated EBS volume at /var/www
Scheduled tasks castopod-tasks.timer runs spark tasks:run every minute
Admin console http://<instance-public-ip>/cp-admin

The database tier and the application tier (including all uploaded podcast media under /var/www/castopod/public/media) each live on their own independently-resizable EBS volume, separate from the operating-system disk, so you can grow storage for either tier without disturbing the other.


Connecting to your instance

Connect over SSH on port 22 as the default login user for your operating-system variant.

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<instance-public-ip>

Replace <instance-public-ip> with the public IPv4 address of your instance (visible in the EC2 console) and /path/to/your-key.pem with the private key you launched the instance with.


Per-instance credentials

On the first boot of every instance, a one-shot service (castopod-firstboot.service) generates state that is unique to that instance:

  • a fresh database schema (the image ships with no content),
  • a fresh MariaDB database password,
  • a fresh analytics salt (used to anonymise listener IP addresses), and
  • a fresh administrator (superadmin) password.

The instance's own address is set as the application base URL automatically. No shared or default credentials and no content ship in the image. Retrieve the generated administrator login with:

sudo cat /root/castopod-credentials.txt

The file (mode 0600, root only) contains the administrator email and password, the admin console URL and the database credentials. Castopod signs in by email — the generated superadmin is admin / admin@example.com with a per-instance random password.


Verifying the service

The services that back Castopod should all report active — nginx, php-fpm, MariaDB and the scheduled-tasks timer:

systemctl is-active nginx php8.3-fpm mariadb castopod-tasks.timer

Expected output:

active
active
active
active

Confirm the installed Castopod version:

grep -o "CP_VERSION., .[0-9.]*" /var/www/castopod/app/Config/Constants.php
CP_VERSION', '1.15.5

Confirm the admin sign-in page is served:

curl -s -o /dev/null -w '%{http_code}\n' http://localhost/cp-auth/login
200

Confirm the database and application tiers are on their dedicated EBS volumes:

df -h /var/www /var/lib/mysql
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme2n1     30G  173M   28G   1% /var/www
/dev/nvme1n1     20G  195M   19G   2% /var/lib/mysql

Signing in

Browse to the admin console and sign in with the administrator email and password from /root/castopod-credentials.txt:

http://<instance-public-ip>/cp-admin

After signing in you land on the Admin dashboard, which shows podcasts, episodes and storage use across the whole instance.

Castopod admin dashboard

We recommend changing the administrator password and creating additional named user accounts (with per-podcast roles) from Users in the admin sidebar once you are signed in.


Creating your first podcast

Click Podcasts → New podcast in the admin sidebar. Provide a title, a handle (the podcast's unique name in URLs and on the Fediverse), a description, a language, a category and a square cover image of at least 1400x1400 pixels, then save.

Each podcast gets its own dashboard with episodes, analytics, broadcast (Fediverse and WebSub) and contributor management:

A podcast dashboard in Castopod

To publish your first episode, click Add an episode, upload your audio file (mp3 or m4a), give it a title and description, save, and then Publish it. Publishing also requires publishing the podcast itself the first time — Castopod will prompt you with a draft-mode banner until you do.

Once published, the episode has a public page with an embeddable web player, comments and Fediverse activity, and is included in the podcast's RSS feed at http://<instance-public-ip>/@<handle>/feed.xml:

A published episode page with the web player

Every podcast is also a Fediverse actor: listeners on Mastodon and other ActivityPub platforms can follow @<handle>@<your-domain>, and announcement posts you write from the podcast's page federate to followers.

The public podcast page with activity feed


Scheduled tasks

Castopod relies on a once-a-minute background task runner for Fediverse broadcasting, WebSub hub notification, RSS imports and video-clip generation. The image wires this up as a systemd timer (castopod-tasks.timer) — no cron configuration is needed:

systemctl list-timers castopod-tasks.timer --no-pager
NEXT                        LEFT LAST                         PASSED UNIT                 ACTIVATES
Fri 2026-06-12 15:20:00 UTC   2s Fri 2026-06-12 15:19:01 UTC 55s ago castopod-tasks.timer castopod-tasks.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.

Administering from the command line

Castopod ships CodeIgniter's spark CLI. Run admin tasks as the www-data user from the application root:

sudo -u www-data php /var/www/castopod/spark <command>

Common tasks:

  • ... spark list — list every available command.
  • ... spark tasks:run — run the scheduled tasks immediately (the timer does this every minute).
  • ... spark cache:clear — clear the application cache.

The instance configuration (base URL, database connection, email settings) lives in /var/www/castopod/.env. To configure outgoing email (needed for password-reset links and premium-subscriber instructions), add your SMTP gateway to that file. The user guide on email configuration is at docs.castopod.org; after editing, restart php-fpm with sudo systemctl restart php8.3-fpm.

Manage the services with systemctl (nginx, php8.3-fpm, mariadb, castopod-tasks.timer).


Enabling HTTPS

The image serves Castopod over HTTP on port 80 so it works immediately behind whatever networking you place in front of it. For production podcast hosting you should serve over HTTPS on a proper domain — podcast directories and Fediverse federation expect it.

Point a DNS name at the instance's public IP, then install Certbot and request a certificate. Run the following, replacing the placeholders with your own domain and email:

sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com -m you@example.com --agree-tos --no-eff-email

Certbot will obtain a certificate and reconfigure nginx for HTTPS. After enabling HTTPS, update Castopod's base URLs in /var/www/castopod/.env to the https:// address:

app.baseURL="https://your-domain.example.com/"
media.baseURL="https://your-domain.example.com/"
app.forceGlobalSecureRequests=true

then clear the application cache and restart php-fpm:

sudo -u www-data php /var/www/castopod/spark cache:clear
sudo systemctl restart php8.3-fpm

Note that changing the domain after listeners have subscribed changes your RSS feed URLs — set up your final domain before submitting feeds to podcast directories.


Support

This is a repackaged open source software product. Castopod itself is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). cloudimg provides 24/7 technical support for this image by email and chat — covering Castopod deployment, upgrades, HTTPS and domain configuration, email and S3 media storage setup, Fediverse federation, RSS migration from other hosts, performance tuning and database administration.

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.