{"id":2218,"date":"2025-10-27T09:36:22","date_gmt":"2025-10-27T08:36:22","guid":{"rendered":"https:\/\/grupp-web.de\/cms\/?p=2218"},"modified":"2025-10-27T10:04:19","modified_gmt":"2025-10-27T09:04:19","slug":"podcastplattform-castopod-installieren","status":"publish","type":"post","link":"https:\/\/grupp-web.de\/cms\/2025\/10\/27\/podcastplattform-castopod-installieren\/","title":{"rendered":"Podcastplattform &#8222;Castopod&#8220; installieren"},"content":{"rendered":"\n<p>Im Rahmen meiner Arbeit war ich j\u00fcngst in die Suche nach einem Podcasting-Dienst eingebunden. Die Nutzung propriet\u00e4rer Plattformen als Basis wurde dabei zu Gunsten selbst gehosteter Dienste verworfen.<\/p>\n\n\n\n<p>Da ich dienstlich schon einen PeerTube-Server betreibe wurde damit der erste Versuch gestartet. Funktioniert grunds\u00e4tzlich aber leider war es damit nicht m\u00f6glich die Einbindung des Podcasts z.B. in die Publikations-Plattformen von Apple oder Spotify zu bewerkstelligen.<\/p>\n\n\n\n<p>Z.B. \u00fcber Stephanie Henkels (aka \u00dcck\u00fcck) Vortrag &#8222;<a href=\"https:\/\/media.ccc.de\/v\/clt25-193-castopod-podcasting-im-fediverse\" target=\"_blank\" rel=\"noreferrer noopener\">Castopod \u2013 Podcasting im Fediverse<\/a>&#8220; im Rahmen der <a href=\"https:\/\/chemnitzer.linux-tage.de\" target=\"_blank\" rel=\"noreferrer noopener\">Chemnitzer Linuxtage<\/a> war ich schon auf diesen Dienst aufmerksam geworden. Der zweite Versuch fand somit mit Castopod statt.<\/p>\n\n\n\n<p>Fazit, ich nehme es vorweg: Hier war Erfolg beschieden. Mit Castopod ist ein eigenes Hosting, mit einem gezielt f\u00fcr Podcasting ausgerichteten Dienst, einfach m\u00f6glich. Podcasts sind damit dann im <a href=\"https:\/\/grupp-web.de\/cms\/2025\/04\/26\/das-fediverse\/\" data-type=\"post\" data-id=\"2183\" target=\"_blank\" rel=\"noreferrer noopener\">dezentralen Fediverse<\/a> beheimatet, technisch unabh\u00e4ngiger Betrieb ist m\u00f6glich, und die Einbindung in die obigen Mainstream-Publikationsplattformen total unproblematisch.<\/p>\n\n\n\n<p>Nachfolgend nun &#8222;<em>my way<\/em>&#8220; der Installation, direkt in einem Debian-System, ohne Docker. Dieser Weg hat sich zwar an der offiziellen Anleitung &#8222;<a href=\"https:\/\/docs.castopod.org\/main\/en\/getting-started\/install\/\" target=\"_blank\" rel=\"noreferrer noopener\">How to install Castopod?<\/a>&#8220; (auch deutsche Version verf\u00fcgbar) entlang bewegt, f\u00fcllte aber ein paar L\u00fccken der Anleitung und nutzt eine andere Variante der Mailanbindung.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nginx mit PHP-FPM<\/h2>\n\n\n\n<p>Auf dem genutzten Server war, wegen der parallelen PeerTube-Installation, schon Nginx als Webserver installiert. Ben\u00f6tigt wird hier noch PHP-Unterst\u00fctzung da Castopod eben eine PHP-Anwendung ist. F\u00fcr m\u00f6glichst gute Performance ist PHP-FPM hier bevorzugt.<\/p>\n\n\n\n<p>Debian bringt zwar PHP-FPM mit, aber da ich schon mehrfach die Situation hatte unterschiedliche PHP-Versionen auf einem Server zu ben\u00f6tigen gehe ich hier immer den Weg \u00fcber das Sury-Repo (siehe dazu auch <a href=\"https:\/\/wiki.debian.org\/AdditionalPHPVersions\" target=\"_blank\" rel=\"noreferrer noopener\">Additional PHP Versions on Debian | 3rd party integration<\/a>). Gesagt getan &#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">apt-get install extrepo<br \/>extrepo enable sury<br \/>apt install php8.4-{fpm,intl,curl,mbstring,gd,exif,mysql,xml}<\/code><\/pre>\n\n\n\n<p><strong>Anmerkung:<\/strong> Die Original-Anleitung hat zwar angemerkt, dass xml aktiviert sein muss, aber wenn es nicht installiert wurde kann es auch nicht aktiviert werden. Hat mich eine wenig Zeit gekostet.<\/p>\n\n\n\n<p>F\u00fcr die Gr\u00f6\u00dfe der sp\u00e4ter bereit zu stellenden MP3-Dateien muss die Uploadgrenze sowohl bei Nginx als auch bei PHP-FPM angepasst werden.<\/p>\n\n\n\n<p>Im Fall von PHP-FPM erfolgt das \u00fcber die die Konfigurationsdatei <code>\/etc\/php\/8.4\/fpm\/php.ini<\/code>. Hier wurden die beiden folgenden Werte eingestellt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">post_max_size = 75M<br \/>upload_max_filesize = 50M<\/code><\/pre>\n\n\n\n<p>Die TLS-Zertifikate f\u00fcr den Nginx sind hier unter <code>\/var\/www\/certs\/...<\/code> installiert. F\u00fcr den Castpod-Server selbst wurde das Verzeichnis <code>\/var\/www\/castopod<\/code> angelegt.<\/p>\n\n\n\n<p>F\u00fcr den Nginx habe ich unter <code>\/etc\/nginx\/sites-available<\/code> eine neue Datei <code>castopod<\/code> angelegt. Der hier relevante Teil der Datei sieht so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">root          \/var\/www\/castopod\/public;&nbsp;\n<strong>index<\/strong> <strong>index<\/strong>.html <strong>index<\/strong>.htm <strong>index<\/strong>.php;\n\n&nbsp;<strong>access_log<\/strong> \/var\/log\/nginx\/castopod.access.log; # reduce I\/0 with buffer=10m flush=5m\n&nbsp;<strong>error_log<\/strong> &nbsp;\/var\/log\/nginx\/castopod.error.log;\n\n&nbsp;##\n&nbsp;# Certificates\n&nbsp;# you need a certificate to run in production. see https:\/\/letsencrypt.org\/\n&nbsp;##\n&nbsp;<strong>ssl_certificate<\/strong> &nbsp;&nbsp;&nbsp;&nbsp;\/var\/www\/certs\/fullchain.pem;\n&nbsp;<strong>ssl_certificate_key<\/strong> \/var\/www\/certs\/privkey.pem;\n\n&nbsp;<strong>server_tokens<\/strong> off;\n&nbsp;<strong>add_header<\/strong> X-Frame-Options sameorigin always;\n&nbsp;<strong>add_header<\/strong> Permissions-Policy interest-cohort=();\n&nbsp;<strong>add_header<\/strong> X-Content-Type-Options nosniff;\n&nbsp;<strong>add_header<\/strong> Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload;\";\n\n&nbsp;<strong>fastcgi_buffers<\/strong> 64 4K;\n\n&nbsp;<strong>gzip<\/strong> on;\n&nbsp;<strong>gzip_vary<\/strong> on;\n&nbsp;<strong>gzip_comp_level<\/strong> 4;\n&nbsp;<strong>gzip_min_length<\/strong> 256;\n&nbsp;<strong>gzip_types<\/strong> <strong>application<\/strong>\/atom+xml <strong>application<\/strong>\/javascript <strong>application<\/strong>\/rss+xml image\/bmp image\/svg+xml image\/x-icon text\/css text\/plain text\/html;\n\n&nbsp;<strong>autoindex<\/strong> off;\n\n&nbsp;location \/ {\n&nbsp;&nbsp;&nbsp;try_files <strong>$uri<\/strong> <strong>$uri<\/strong>\/ \/<strong>index<\/strong>.php<strong>$is_args$args<\/strong>;\n&nbsp;}\n\n&nbsp;location ~ \\.php$ {\n&nbsp;&nbsp;&nbsp;include snippets\/fastcgi-php.conf;\n&nbsp;&nbsp;&nbsp;fastcgi_pass unix:\/var\/run\/php\/php8.4-fpm.sock;\n&nbsp;}\n\n&nbsp;# Upload-Groesse\n&nbsp;<strong>client_max_body_size<\/strong> 75M;<\/code><\/pre>\n\n\n\n<p>Abschlie\u00dfend wird der PHP-FPM neu gestartet und der neue virtuelle Webserver in Betrieb genommen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">cd \/etc\/nginx\/sites-enabled<br \/>ln -s \/etc\/nginx\/sites-available\/castopod<br \/>systemctl reload nginx<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">MariaDB-Datenbankserver und Castopod-Datenbank<\/h2>\n\n\n\n<p>Mit <code>apt install mariadb-server<\/code> wird der Datenbankserver installiert. Anschlie\u00dfend wird der MariaDB-Client mit dem Kommando mariadb gestartet und die Castopod-Datenbank angelegt.<\/p>\n\n\n\n<p><strong>Anmerkung:<\/strong> Im Gegensatz zur Originalanleitung werden hier alle PRIVILEGES erteilt. Hier war bei der Installation einer der Fallstricke, dass die Rechte n\u00e4mlich nicht ausgereicht haben. Auch hier blieb f\u00fcr die Ursachenforschung einiges an Zeit liegen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">CREATE DATABASE castopod DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\nCREATE USER castopoduser@localhost IDENTIFIED BY 'GeheimesPassswort';\nGRANT ALL PRIVILEGES ON castopod.* TO 'castopoduser'@'localhost';\nFLUSH PRIVILEGES;\nQUIT<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Redis-Server<\/h2>\n\n\n\n<p>Durch die PeerTube-Installation war schon Redis installiert. Dessen Installation ist aber mit <code>apt install redis-server<\/code> auch nicht sonderlich schwierig. Sp\u00e4ter ist nur relevant, dass in meinem Fall damit die Redis-Datenbank 0 schon von PeerTube genutzt wird.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Postfix-Mailserver mit Smarthost<\/h2>\n\n\n\n<p>Da der Mailserver der genutzten Domain an anderer Stelle gehostet ist, muss die Mailkonfiguration von Castopod auf einen solchen Server geleitet werden. Dabei bin ich an den Konfigurationsm\u00f6glichkeiten von Castopod gescheitert und konnte das erforderliche STARTTLS nicht in Betrieb nehmen.<\/p>\n\n\n\n<p>Die L\u00f6sung bestand in einem Postfix, im Modus &#8222;Internet with smarthost&#8220; auf der Castopod-Maschine. Installation ist ziemlich einfach! Mit <code>apt install postfix libsasl2-modules<\/code> werden die notwendigen Software-Paket installiert. In den Konfigurationsdialogen wurden dann diese Einstellungen vorgenommen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Server-Konfiguration: Internet with smarthost<\/li>\n\n\n\n<li>System mail name: &lt;DNS-Name des Castopod-Servers&gt;<\/li>\n\n\n\n<li>SMTP relay host: &lt;DNS-Name des Mailservers&gt;<\/li>\n\n\n\n<li>&#8230;<\/li>\n<\/ul>\n\n\n\n<p>Um Postfix noch die SASL-Authentifizierung bei <code>mail.lehrerfortbildung-bw.de<\/code> beizubringen sind noch folgende Aktionen erforderlich:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">echo mail.meinmailserver.de \\\n     systemmailer:PasswortVonSystemmailer \\\n       &gt; \/etc\/postfix\/relay_password\npostmap hash:\/etc\/postfix\/relay_password<\/code><\/pre>\n\n\n\n<p>In der Datei <code>\/etc\/postfix\/main.cf<\/code> m\u00fcssen dann noch folgende Zeilen enthalten sein:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">relayhost = mail.meinmailserver.de:587\nsmtp_sasl_password_maps=hash:\/etc\/postfix\/relay_password\nsmtp_sasl_auth_enable=yes\nsmtp_sasl_security_options = noanonymous<\/code><\/pre>\n\n\n\n<p>Abschlie\u00dfen Neu-Einlesen der Konfiguration mit <code>postfix reload<\/code> und Versandtest mit <code>mailx -r noreply.meinmailserver.de -s \"Testmail 2 von pt01\" ich@meinemaildomain.de<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die eigentliche Castopod-Installation<\/h2>\n\n\n\n<p>Verwendet wurde die (zum Installations-Zeitpunkt aktuelle) Version 1.13.5. Damit l\u00e4uft dann die Installation wie folgt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">CPDWNLD=https:\/\/code.castopod.org\/-\/project\/2\/uploads\/f113e0feb39d129758629e3ea629d704\/castopod-1.13.5.zip<br \/>cd \/var\/www<br \/>wget $CPDWNLD<br \/>unzip castopod-1.13.5.zip<br \/>rm castopod-1.13.5.zip<br \/>chown -R www-data:www-data castopod<br \/>chmod -R go-rwx castopod<\/code><\/pre>\n\n\n\n<p>Anschlie\u00dfend webbasierter Aufruf des Castopod-Installers \u00fcber https:\/\/cp.meincastopodserver.de\/cp-install. Die Dialoge werden mit den oben genutzten Daten durchgef\u00fchrt und als Cache Redis ausgew\u00e4hlt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Anpassungen bzgl. Redis<\/h3>\n\n\n\n<p>Da bei mir die Redis-Datenbank 0 schon genutzt wird, ich Kollisionen mit einem anderen Dienst vermeiden wollte, ist sp\u00e4ter die Castopod-Konfiguration mittels <code>cache.redis.database=1<\/code> angepasst worden. Damit nutzt Castopod die Redis-Datenank 1.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Mail-Konfiguration<\/h3>\n\n\n\n<p>Da ich es, wie weiter oben schon erw\u00e4hnt, nicht geschafft habe Castopod direkt als Mail-Client zu konfigurieren (es scheiterte an nicht verf\u00fcgbaren SASL-Methoden) habe ich auf <code>pt01.lehrerfortbildung-bw.de<\/code> (auf dieser Maschine lief zu dem Zeitpunkt der Castopod-Server) eine Postfix als Mail-Relay aufgesetzt (siehe passenden Abschnitt). Die Mailkonfiguration f\u00fcr Castopod erfolgte dann durch Eintrag der folgenden Zeilen in <code>\/var\/www\/castopod\/.env<\/code> (siehe dazu auch <a href=\"https:\/\/codeigniter.com\/user_guide\/libraries\/email.html#id2\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/codeigniter.com\/user_guide\/libraries\/email.html#id2<\/a>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">email.protocol=mail\nemail.fromEmail=\"noreply@meinemaildomain.de\"\nemail.fromName=\"Castopod\"<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">cron-Job<\/h3>\n\n\n\n<p>\u00dcber <code>crontab -u www-data -e<\/code> folgende Zeile hinterlegen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><\/code><code>* * * * * \/usr\/bin\/php \/var\/www\/castopod\/spark tasks:run &gt;&gt; \/dev\/null 2&gt;&amp;1<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Die finale Castopod-Konfigurationsdatei im \u00dcberblick<\/h3>\n\n\n\n<p>Die Castopod-Konfiguration ist in <code>\/var\/www\/castopod\/.env<\/code> zu finden und sah final bei mir dann so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">app.baseURL=\"https:\/\/cp.meincastopodserver.de\/\"\nmedia.baseURL=\"https:\/\/cp.meincastopodserver.de\/\"\nanalytics.salt=\"OriginalSaltHierNatuerlichNichtDokumentiert\"\nadmin.gateway=\"cpmd-admin\"\nauth.gateway=\"cpmd-auth\"\ndatabase.default.hostname=\"localhost\"\ndatabase.default.database=\"castopod\"\ndatabase.default.username=\"castopoduser\"\ndatabase.default.password=\"GeheimesPassswort\"\ndatabase.default.DBPrefix=\"cp_\"\ncache.handler=\"redis\"\ncache.redis.database=1\nemail.protocol=mail\nemail.fromEmail=\"noreply@meinemaildomain.de\"\nemail.fromName=\"Castopod\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Validierung von Podcast-Feeds<\/h2>\n\n\n\n<p>Hat man sp\u00e4ter Podcast konfiguriert, plant deren Publikation auch bei den (aktuell leider noch) Mainstream-Plattformen Apple oder Spotify, kann man seine Feeds vorab mit dem <a href=\"https:\/\/www.castfeedvalidator.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cast Feed Validator von Blubrry Podcasting<\/a> auf Compliance testen. Geht dort alles klar, ist der n\u00e4chste Schritt sich mit Apple und Spotify zu besch\u00e4ftigen. But this is none of my business :-)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Rahmen meiner Arbeit war ich j\u00fcngst in die Suche nach einem Podcasting-Dienst eingebunden. Die Nutzung propriet\u00e4rer Plattformen als Basis wurde dabei zu Gunsten selbst gehosteter Dienste verworfen. Da ich dienstlich schon einen PeerTube-Server betreibe wurde damit der erste Versuch gestartet. Funktioniert grunds\u00e4tzlich aber leider war es damit nicht m\u00f6glich die Einbindung des Podcasts z.B. &#8230; <a title=\"Podcastplattform &#8222;Castopod&#8220; installieren\" class=\"read-more\" href=\"https:\/\/grupp-web.de\/cms\/2025\/10\/27\/podcastplattform-castopod-installieren\/\" aria-label=\"Mehr Informationen \u00fcber Podcastplattform &#8222;Castopod&#8220; installieren\">Weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":2223,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,5],"tags":[28,25,30],"class_list":["post-2218","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gesellschaftliches","category-linux","tag-castopod","tag-fediverse","tag-podcast"],"_links":{"self":[{"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/posts\/2218","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/comments?post=2218"}],"version-history":[{"count":8,"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/posts\/2218\/revisions"}],"predecessor-version":[{"id":2227,"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/posts\/2218\/revisions\/2227"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/media\/2223"}],"wp:attachment":[{"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/media?parent=2218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/categories?post=2218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/grupp-web.de\/cms\/wp-json\/wp\/v2\/tags?post=2218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}