Castopod on AWS User Guide
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.

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.

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:

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:

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.

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.