Castopod
Modifié par john le 2026/09/19 18:14
Instance de test de Castopod, plateforme d'hébergement de podcasts, déployée en vue d'éventuelles conférences.
Fonctionnalités
- Publication d'épisodes et génération automatique du flux RSS, pour la diffusion dans les annuaires de podcasts.
- Intégration au Fédivers (ActivityPub) : les auditeurs suivent, commentent et partagent depuis leur propre compte.
- Statistiques d'écoute, sans traceur publicitaire.
- Plusieurs podcasts et plusieurs utilisateurs, avec des rôles.
- API REST, double authentification (TOTP) optionnelle.
Architecture
| Conteneur | Rôle |
|---|---|
| castopod-test | Application (FrankenPHP et Caddy intégrés) |
| castopod-test-db | Base MariaDB 12.1 |
| castopod-test-redis | Cache Redis, protégé par mot de passe |
La base et Redis sont sur un réseau internal : ils n'ont aucun accès extérieur et ne sont joignables que par l'application.
Variables d'environnement
| Variable | Rôle |
|---|---|
| CASTOPOD_BASEURL | URL publique de l'instance |
| CP_ANALYTICS_SALT | Sel servant à anonymiser les données d'écoute ; ne plus le changer une fois l'instance en service |
| MARIADB_DATABASE, MARIADB_USER, MARIADB_PASSWORD, MARIADB_ROOT_PASSWORD | Accès à la base |
| REDIS_PASSWORD | Mot de passe de Redis |
| TZ | Fuseau horaire |
Stack
networks:
proxy:
external: true
castopod-test-backend:
internal: true
services:
castopod-test-db:
image: mariadb:12.1
container_name: castopod-test-db
restart: unless-stopped
environment:
- TZ=${TZ}
- MYSQL_DATABASE=${MARIADB_DATABASE}
- MYSQL_USER=${MARIADB_USER}
- MYSQL_PASSWORD=${MARIADB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
volumes:
- <APPDATA>/castopod-test/mariadb:/var/lib/mysql
networks:
- castopod-test-backend
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
castopod-test-redis:
image: redis:8.4-alpine
container_name: castopod-test-redis
restart: unless-stopped
command: --requirepass ${REDIS_PASSWORD}
volumes:
- <APPDATA>/castopod-test/redis:/data
networks:
- castopod-test-backend
castopod-test:
image: castopod/castopod:1.15.5
container_name: castopod-test
restart: unless-stopped
environment:
- TZ=${TZ}
- MYSQL_DATABASE=${MARIADB_DATABASE}
- MYSQL_USER=${MARIADB_USER}
- MYSQL_PASSWORD=${MARIADB_PASSWORD}
- CP_BASEURL=${CASTOPOD_BASEURL}
- CP_ANALYTICS_SALT=${CP_ANALYTICS_SALT}
- CP_DATABASE_HOSTNAME=castopod-test-db
- CP_CACHE_HANDLER=redis
- CP_REDIS_HOST=castopod-test-redis
- CP_REDIS_PASSWORD=${REDIS_PASSWORD}
volumes:
- <APPDATA>/castopod-test/app-media:/app/public/media
networks:
- proxy
- castopod-test-backend
depends_on:
castopod-test-db:
condition: service_healthy
castopod-test-redis:
condition: service_started
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
proxy:
external: true
castopod-test-backend:
internal: true
services:
castopod-test-db:
image: mariadb:12.1
container_name: castopod-test-db
restart: unless-stopped
environment:
- TZ=${TZ}
- MYSQL_DATABASE=${MARIADB_DATABASE}
- MYSQL_USER=${MARIADB_USER}
- MYSQL_PASSWORD=${MARIADB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
volumes:
- <APPDATA>/castopod-test/mariadb:/var/lib/mysql
networks:
- castopod-test-backend
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
castopod-test-redis:
image: redis:8.4-alpine
container_name: castopod-test-redis
restart: unless-stopped
command: --requirepass ${REDIS_PASSWORD}
volumes:
- <APPDATA>/castopod-test/redis:/data
networks:
- castopod-test-backend
castopod-test:
image: castopod/castopod:1.15.5
container_name: castopod-test
restart: unless-stopped
environment:
- TZ=${TZ}
- MYSQL_DATABASE=${MARIADB_DATABASE}
- MYSQL_USER=${MARIADB_USER}
- MYSQL_PASSWORD=${MARIADB_PASSWORD}
- CP_BASEURL=${CASTOPOD_BASEURL}
- CP_ANALYTICS_SALT=${CP_ANALYTICS_SALT}
- CP_DATABASE_HOSTNAME=castopod-test-db
- CP_CACHE_HANDLER=redis
- CP_REDIS_HOST=castopod-test-redis
- CP_REDIS_PASSWORD=${REDIS_PASSWORD}
volumes:
- <APPDATA>/castopod-test/app-media:/app/public/media
networks:
- proxy
- castopod-test-backend
depends_on:
castopod-test-db:
condition: service_healthy
castopod-test-redis:
condition: service_started
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
- L'image de l'application est épinglée sur une version précise : Watchtower ne la met pas à jour. Changer le tag à la main après lecture des notes de version.
- L'application écoute sur le port 8080 du conteneur, relayé par SWAG.
Sauvegarde
- Base : dump SQL de castopod-test-db par le script de Sauvegarde.
- Épisodes et illustrations : <APPDATA>/castopod-test/app-media, sauvegardé tel quel.