add rsshub
Some checks failed
Flake check / flake-check (pull_request) Failing after 4s
Build hosts / build-hosts (pull_request) Failing after 6s

This commit is contained in:
sid 2026-03-30 19:52:16 +02:00
parent 86de57611a
commit f8a929c13b
6 changed files with 210 additions and 0 deletions

View file

@ -6,6 +6,7 @@
forgejo-runner = import ./forgejo-runner;
gnome = import ./gnome;
monero = import ./monero;
rsshub-oci = import ./rsshub-oci;
tailscale = import ./tailscale;
xfce = import ./xfce;
}

View file

@ -0,0 +1,185 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.rsshub-oci;
images = {
# https://github.com/DIYgod/RSSHub/pkgs/container/rsshub
rsshub = pkgs.dockerTools.pullImage {
imageName = "ghcr.io/diygod/rsshub";
imageDigest = "sha256:67e23d9afc6081753c1a51a71f5a58f57d43b12ff927c2263a9f767112ec1819";
hash = "sha256-vEQi12NCY35dGJ3vKUjwocfRn8xOBp/2inIqg8DNTRE=";
finalImageName = "ghcr.io/diygod/rsshub";
finalImageTag = "2026-03-07";
};
# https://github.com/browserless/browserless/pkgs/container/chromium
browserless = pkgs.dockerTools.pullImage {
imageName = "ghcr.io/browserless/chromium";
imageDigest = "sha256:71ae7fa09bd1bf78efaa2803d75c837ab5a56e0d7637695bff3077d87248e642";
hash = "sha256-adu+fvWK1X/nVt2cFLDO0Czq6GA+46VvL1wy9KQ+/tI=";
finalImageName = "ghcr.io/browserless/chromium";
finalImageTag = "v2.42.0";
};
# https://github.com/hyoban/puppeteer-real-browser-hono/pkgs/container/puppeteer-real-browser-hono
real-browser = pkgs.dockerTools.pullImage {
imageName = "ghcr.io/hyoban/puppeteer-real-browser-hono";
imageDigest = "sha256:21bb4cd27144a61ca2f85eb3b4f555a074165bc6beaee318873ced0eb4046a04";
hash = "sha256-O8qV8Wfh75rhtEnSAlUBzBUVNGpypNF1sNY2F4zVqZE=";
finalImageName = "ghcr.io/hyoban/puppeteer-real-browser-hono";
finalImageTag = "sha-6c6cbbc";
};
# https://hub.docker.com/_/redis
redis = pkgs.dockerTools.pullImage {
imageName = "redis";
imageDigest = "sha256:2afba59292f25f5d1af200496db41bea2c6c816b059f57ae74703a50a03a27d0";
hash = "sha256-t3SFoeUME8Ntz5QdMfJnJ3QYRNAaHHpXngnBvR8LOlg=";
finalImageName = "redis";
finalImageTag = "8.6.1-alpine";
};
};
defaultEnv = {
NODE_ENV = "production";
CACHE_TYPE = "redis";
REDIS_URL = "redis://127.0.0.1:6379/";
PUPPETEER_WS_ENDPOINT = "ws://127.0.0.1:3000";
PUPPETEER_REAL_BROWSER_SERVICE = "http://127.0.0.1:3001";
};
inherit (lib)
mkEnableOption
mkIf
mkOption
mkOverride
optional
types
;
in
{
options.services.rsshub-oci = {
enable = mkEnableOption "RSSHub service stack with Podman";
port = mkOption {
type = types.port;
default = 1200;
description = "The port RSSHub will listen on.";
};
environment = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Extra environment variables for RSSHub.";
};
environmentFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "Environment file for secrets.";
};
};
config = mkIf cfg.enable {
virtualisation.podman = {
enable = true;
autoPrune.enable = true;
dockerCompat = true;
};
networking.firewall.interfaces =
let
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
in
{
"${matchAll}".allowedUDPPorts = [ 53 ];
};
virtualisation.oci-containers.backend = "podman";
virtualisation.oci-containers.containers = {
rsshub-browserless = {
image = with images.browserless; imageName + ":" + imageTag;
imageFile = images.browserless;
log-driver = "journald";
extraOptions = [ "--network=host" ];
};
rsshub-real-browser = {
image = with images.real-browser; imageName + ":" + imageTag;
imageFile = images.real-browser;
log-driver = "journald";
environment = {
PORT = "3001";
};
extraOptions = [ "--network=host" ];
};
rsshub-redis = {
image = with images.redis; imageName + ":" + imageTag;
imageFile = images.redis;
volumes = [ "rsshub_redis-data:/data:rw" ];
log-driver = "journald";
extraOptions = [ "--network=host" ];
};
rsshub-rsshub = {
image = with images.rsshub; imageName + ":" + imageTag;
imageFile = images.rsshub;
log-driver = "journald";
environment =
defaultEnv
// cfg.environment
// {
PORT = "${toString cfg.port}";
};
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
extraOptions = [ "--network=host" ];
};
};
systemd.services =
let
commonServiceCfg = {
serviceConfig.Restart = mkOverride 90 "always";
partOf = [ "podman-compose-rsshub-root.target" ];
wantedBy = [ "podman-compose-rsshub-root.target" ];
};
in
{
podman-rsshub-browserless = commonServiceCfg;
podman-rsshub-real-browser = commonServiceCfg;
podman-rsshub-redis = commonServiceCfg // {
after = [ "podman-volume-rsshub_redis-data.service" ];
requires = [ "podman-volume-rsshub_redis-data.service" ];
};
podman-rsshub-rsshub = commonServiceCfg // {
after = [
"podman-rsshub-redis.service"
"podman-rsshub-browserless.service"
"podman-rsshub-real-browser.service"
];
};
podman-volume-rsshub_redis-data = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect rsshub_redis-data || podman volume create rsshub_redis-data
'';
partOf = [ "podman-compose-rsshub-root.target" ];
wantedBy = [ "podman-compose-rsshub-root.target" ];
};
};
systemd.targets."podman-compose-rsshub-root" = {
unitConfig.Description = "Root target for RSSHub services.";
wantedBy = [ "multi-user.target" ];
};
};
}