Service for private Il Post podcast RSS feed

This commit is contained in:
pazpi 2025-12-08 00:08:29 +01:00
parent 8d8a5ef0fe
commit ade6e6ac83
7 changed files with 218 additions and 0 deletions

View file

@ -5,6 +5,7 @@
./firefly-iii.nix
./forgejo.nix
./forgejo-runner.nix
./ilpost-addict.nix
./immich.nix
./media-mgr.nix
./n8n.nix

View file

@ -0,0 +1,172 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.ilpost-addict;
# Fetch the ilpost-addict source from GitHub
ilpostAddict = pkgs.fetchFromGitHub {
owner = "stagadet";
repo = "ilpost-addict";
rev = "main";
sha256 = "sha256-kL7tVHXZunqGFztbVx850QQ1U5h5wY1ltIONWXwe7QQ=";
};
phpPackage = pkgs.php.withExtensions ({ enabled, all }: enabled ++ [
all.curl
all.dom
]);
in
{
options.my.services.ilpost-addict = {
enable = lib.mkEnableOption "Enable ilpost-addict podcast feed generator";
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/ilpost-addict";
description = "Directory where ilpost-addict stores its data (logs, cookies)";
};
user = lib.mkOption {
type = lib.types.str;
default = "ilpost-addict";
description = "User which runs the ilpost-addict service";
};
group = lib.mkOption {
type = lib.types.str;
default = "ilpost-addict";
description = "Group which runs the ilpost-addict service";
};
port = lib.mkOption {
type = lib.types.port;
default = 8095;
description = "Port on which Caddy serves ilpost-addict";
};
poolSettings = lib.mkOption {
type = with lib.types; attrsOf (oneOf [ str int bool ]);
default = {
"pm" = "dynamic";
"pm.max_children" = 8;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 1;
"pm.max_spare_servers" = 4;
"pm.max_requests" = 500;
};
description = "PHP-FPM pool settings for ilpost-addict";
};
proxy = {
enable = lib.mkEnableOption "Set the proxy entry for this service";
domain = lib.mkOption {
default = "example.com";
type = lib.types.str;
description = "The domain where Caddy is reachable";
};
subdomain = lib.mkOption {
default = "ilpost-podcast";
type = lib.types.str;
description = "The subdomain where ilpost-addict is reachable";
};
host = lib.mkOption {
default = "localhost";
type = lib.types.str;
description = "Host name where the service is running";
};
};
};
config = lib.mkMerge [
(lib.mkIf cfg.enable {
users.groups.${cfg.group} = { };
users.users.${cfg.user} = {
home = cfg.dataDir;
group = cfg.group;
description = "ilpost-addict service user";
isSystemUser = true;
};
# Add caddy user to ilpost-addict group so it can read the files
users.users.${config.services.caddy.user}.extraGroups = [ cfg.group ];
# Create data directories
# The PHP script uses relative paths (log/, cookies/) so we create them
# in the www directory where the script runs from
systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0750 ${cfg.user} ${cfg.group} -"
"d '${cfg.dataDir}/log' 0750 ${cfg.user} ${cfg.group} -"
"d '${cfg.dataDir}/cookies' 0750 ${cfg.user} ${cfg.group} -"
];
# Setup service to copy PHP files
systemd.services.ilpost-addict-setup = {
wantedBy = [ "multi-user.target" ];
before = [ "phpfpm-ilpost-addict.service" ];
serviceConfig = {
Type = "oneshot";
User = cfg.user;
Group = cfg.group;
};
script = ''
# Copy the PHP source to the data directory
cp ${ilpostAddict}/src/index.php ${cfg.dataDir}/index.php
chmod 644 ${cfg.dataDir}/index.php
'';
};
# PHP-FPM pool configuration
# The chdir setting ensures the PHP script runs from dataDir
# so the relative paths (log/, cookies/) resolve correctly
services.phpfpm.pools.ilpost-addict = {
user = cfg.user;
group = cfg.group;
phpPackage = phpPackage;
settings = lib.mapAttrs (name: lib.mkDefault) {
"listen.owner" = config.services.caddy.user;
"listen.group" = config.services.caddy.group;
"chdir" = cfg.dataDir;
} // cfg.poolSettings;
};
# Caddy configuration for serving PHP
# Using :port syntax to match any hostname on this port
services.caddy = {
enable = true;
virtualHosts.":${toString cfg.port}".extraConfig = ''
root * ${cfg.dataDir}
php_fastcgi unix/${config.services.phpfpm.pools.ilpost-addict.socket}
file_server
encode gzip
log {
output file ${config.services.caddy.logDir}/ilpost-addict.log
}
'';
};
networking.firewall.allowedTCPPorts = [ cfg.port ];
})
(lib.mkIf cfg.proxy.enable {
services.caddy = with cfg.proxy; {
virtualHosts."${subdomain}.${domain}".extraConfig = ''
reverse_proxy http://${host}:${toString cfg.port}
import cloudflare_${domain}
'';
};
})
];
}