Skip to content

Commit 746d26b

Browse files
committed
Add FreshRSS Docker container
1 parent c20ca1a commit 746d26b

File tree

3 files changed

+112
-35
lines changed

3 files changed

+112
-35
lines changed

hosts/itxserver/configuration.nix

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
{
2-
config,
3-
lib,
4-
pkgs,
5-
...
6-
}@args:
7-
let
8-
inherit (args) inputs;
9-
in
10-
{
1+
{ config, lib, pkgs, ... }@args:
2+
let inherit (args) inputs;
3+
in {
114
imports = [
125
# The hardware-dependent options
136
./hardware-configuration.nix
@@ -18,6 +11,7 @@ in
1811
../../modules/containers/stump.nix
1912
../../modules/containers/homeassistant.nix
2013
../../modules/containers/plex.nix
14+
../../modules/containers/freshrss.nix
2115
# Any other modules
2216
inputs.sops-nix.nixosModules.sops
2317
];
@@ -35,10 +29,7 @@ in
3529
};
3630
};
3731

38-
nix.settings.experimental-features = [
39-
"nix-command"
40-
"flakes"
41-
];
32+
nix.settings.experimental-features = [ "nix-command" "flakes" ];
4233

4334
time.timeZone = "Europe/Berlin";
4435

@@ -48,12 +39,10 @@ in
4839
zfsSupport = true;
4940
efiSupport = true;
5041
efiInstallAsRemovable = true;
51-
mirroredBoots = [
52-
{
53-
devices = [ "nodev" ];
54-
path = "/boot";
55-
}
56-
];
42+
mirroredBoots = [{
43+
devices = [ "nodev" ];
44+
path = "/boot";
45+
}];
5746
};
5847
zfs.extraPools = [ "zpool" ];
5948
};
@@ -67,22 +56,16 @@ in
6756
};
6857
useDHCP = false;
6958
interfaces = {
70-
eno1.ipv4.addresses = [
71-
{
72-
address = "10.0.0.10";
73-
prefixLength = 24;
74-
}
75-
];
59+
eno1.ipv4.addresses = [{
60+
address = "10.0.0.10";
61+
prefixLength = 24;
62+
}];
7663
};
7764
defaultGateway = {
7865
address = "10.0.0.1";
7966
interface = "eno1";
8067
};
81-
nameservers = [
82-
"1.1.1.1"
83-
"1.0.0.1"
84-
"100.100.100.100"
85-
];
68+
nameservers = [ "1.1.1.1" "1.0.0.1" "100.100.100.100" ];
8669
firewall = {
8770
allowedTCPPorts = [
8871
8123
@@ -135,9 +118,7 @@ in
135118
AllowUsers = [ "lukas" ];
136119
};
137120
};
138-
fail2ban = {
139-
enable = true;
140-
};
121+
fail2ban = { enable = true; };
141122
envfs.enable = true;
142123
tailscale.enable = true;
143124
syncthing = {
@@ -156,7 +137,8 @@ in
156137
};
157138
devices = {
158139
"MacBook-Pro" = {
159-
id = "GZAKPGB-BBVIY5T-2D3EY22-YYMGT5L-R3MNHGX-GYWNRWR-TG4BUMW-BQMBBAU";
140+
id =
141+
"GZAKPGB-BBVIY5T-2D3EY22-YYMGT5L-R3MNHGX-GYWNRWR-TG4BUMW-BQMBBAU";
160142
};
161143
};
162144
folders = {

modules/containers/freshrss.nix

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Auto-generated using compose2nix v0.3.1. Edited.
2+
{ pkgs, lib, config, ... }@args:
3+
let inherit (args) inputs;
4+
in {
5+
imports = [ inputs.sops-nix.nixosModules.sops ];
6+
7+
# Secrets are managed via sops
8+
sops = {
9+
defaultSopsFile = ../../secrets/freshrss.env.enc;
10+
defaultSopsFormat = "dotenv";
11+
age.keyFile = "/home/lukas/.config/sops/age/keys.txt";
12+
secrets.freshrss-env = { };
13+
};
14+
15+
# Create persistent directory for container data
16+
systemd.tmpfiles.rules = [
17+
"d /srv/freshrss/database 0750 docker docker -"
18+
"d /srv/freshrss/config 0750 docker docker -"
19+
];
20+
21+
# Runtime
22+
virtualisation.docker = {
23+
enable = true;
24+
autoPrune.enable = true;
25+
};
26+
virtualisation.oci-containers.backend = "docker";
27+
28+
# Containers
29+
virtualisation.oci-containers.containers."freshrss" = {
30+
image = "freshrss/freshrss:latest";
31+
environment = {
32+
"CRON_MIN" = "3,33";
33+
"TZ" = "Europe/Berlin";
34+
};
35+
environmentFiles = [ config.sops.secrets.freshrss-env.path ];
36+
volumes = [
37+
"/srv/freshrss/data:/var/www/FreshRSS/data:rw"
38+
"/srv/freshrss/extensions:/var/www/FreshRSS/extensions:rw"
39+
];
40+
ports = [ "8008:80/tcp" ];
41+
extraOptions = [
42+
"--hostname=freshrss"
43+
# "--log-opt=max-size=10m"
44+
"--network-alias=freshrss"
45+
"--network=freshrss_default"
46+
];
47+
};
48+
systemd.services."docker-freshrss" = {
49+
serviceConfig = {
50+
Restart = lib.mkOverride 90 "always";
51+
RestartMaxDelaySec = lib.mkOverride 90 "1m";
52+
RestartSec = lib.mkOverride 90 "100ms";
53+
RestartSteps = lib.mkOverride 90 9;
54+
};
55+
after = [ "docker-network-freshrss_default.service" ];
56+
requires = [ "docker-network-freshrss_default.service" ];
57+
partOf = [ "docker-compose-freshrss-root.target" ];
58+
wantedBy = [ "docker-compose-freshrss-root.target" ];
59+
};
60+
61+
# Networks
62+
systemd.services."docker-network-freshrss_default" = {
63+
path = [ pkgs.docker ];
64+
serviceConfig = {
65+
Type = "oneshot";
66+
RemainAfterExit = true;
67+
ExecStop = "docker network rm -f freshrss_default";
68+
};
69+
script = ''
70+
docker network inspect freshrss_default || docker network create freshrss_default
71+
'';
72+
partOf = [ "docker-compose-freshrss-root.target" ];
73+
wantedBy = [ "docker-compose-freshrss-root.target" ];
74+
};
75+
76+
networking.firewall.allowedTCPPorts = [ 8008 ];
77+
78+
# Root service
79+
# When started, this will automatically create all resources and start
80+
# the containers. When stopped, this will teardown all resources.
81+
systemd.targets."docker-compose-freshrss-root" = {
82+
unitConfig = { Description = "Root target generated by compose2nix."; };
83+
wantedBy = [ "multi-user.target" ];
84+
};
85+
}

secrets/freshrss.env.enc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
ADMIN_EMAIL=ENC[AES256_GCM,data:57NFB12OftHg87jKLLPSxUUF,iv:PWkKFATXz5bSu3kETQqlhcMZvPq0vS1y9YoNnkCMcDU=,tag:5Jfcev5TYpoyiExriSiZAw==,type:str]
2+
ADMIN_PASSWORD=ENC[AES256_GCM,data:PpsAsra1dDDYHZuX2nR/vsneofUuoUbhyfUWow24nMY=,iv:Y+kVRjBvzDfc5MoyI5aA4otmATEG2DEvxJcKvUQB18g=,tag:2t4R3ubeeGl57ARffrWIQA==,type:str]
3+
ADMIN_API_PASSWORD=ENC[AES256_GCM,data:B8eD5Fd4qYVGkHmmJQLGDK5F3O3B7k6NHOWjVVmIPoM=,iv:WW6i8VgxSeyZhN7rWPR1mYcq1zM5ZwHf4jMvwqUhI+Q=,tag:QmFudgC9GlefiabV+XXmXA==,type:str]
4+
PUBLISHED_PORT=ENC[AES256_GCM,data:MRNmfQ==,iv:4N78sBmWu6b466aBQzOjT0Lgarf0ODirn6u2xkewPKs=,tag:rjDOATShhxM7C9WZD/azrg==,type:str]
5+
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzajk2QTVaZHBiUlJYcys4\nUjA3Y0NKMEJJVDBlT1VOUXQ3Z01WRFB4MVZNCklxd3BuaXhlSkYyZ1dJZENmVHYr\nZklYcTRGaFN4TnJydnFvYXBlTGhjd1UKLS0tIHl5UmYxYmFHNWhhVkZ5dEk0b0FP\nZjBtZW1lZjYwVFc1MG9zV29MM25tTFkKoYWmsylzXRYfSotYpWkyWxbEdq+KMsy9\n9RruLA8StpNIYPe5f087+G7Ak1OF4JmBbuHyc/M4ONqFs0JwOLdHcA==\n-----END AGE ENCRYPTED FILE-----\n
6+
sops_age__list_0__map_recipient=age1njkfdv4ayqlqak76az6ezhse8hn3gmgt9ntur2edyz3watx2xdqq3jklqm
7+
sops_lastmodified=2025-07-23T12:55:31Z
8+
sops_mac=ENC[AES256_GCM,data:8065sALFyGOPBtRBfS19OKVRInTaweF1qgTfQlO+gV9p8F4V/vQSUwv7/iJe/QZoJPXJ2AHpOQ6hWBHLAqrOOgfcy2u75lUdCxMYiidlI1H6XU/jAxVWlrlE8NIf29kvbitJpQ4HYS+ia5MzMOztdbucUxfsWQTwH3EX7ruKEik=,iv:gqqvlefzG7t8dWqFSt3XOGfdxHBEi6KFErhEyDf1I9o=,tag:lHhVyfWYdNw1PI+Onv9N/g==,type:str]
9+
sops_unencrypted_suffix=_unencrypted
10+
sops_version=3.10.2

0 commit comments

Comments
 (0)