Compare commits

..

2 Commits

Author SHA1 Message Date
ac004a0e8e refactor 2026-01-04 20:10:13 +00:00
0c6c138da5 refactor(gitea): convert profile to configurable module
- Move gitea.nix from profiles/ to modules/ with mkOption-based config
- Make litestream/restic buckets and secret paths configurable
- Rename secrets to consistent michael-gitea-* naming
- Configure gitea module in hosts/michael/default.nix
2026-01-04 20:10:13 +00:00
17 changed files with 254 additions and 200 deletions

View File

@@ -1,6 +1,6 @@
{
inputs,
pkgs,
inputs,
user,
hostname,
...
@@ -20,7 +20,6 @@
home-manager.users.${user} = {
imports = [
inputs.nixvim.homeModules.nixvim
../../profiles/atuin.nix
../../profiles/bash.nix
../../profiles/bat.nix
@@ -44,6 +43,7 @@
../../profiles/zk.nix
../../profiles/zoxide.nix
../../profiles/zsh.nix
inputs.nixvim.homeModules.nixvim
];
fonts.fontconfig.enable = true;
programs.git.settings.user.email = "christoph@tuist.dev";

View File

@@ -19,7 +19,6 @@
home-manager.users.${user} = {
imports = [
inputs.nixvim.homeModules.nixvim
../../profiles/atuin.nix
../../profiles/bash.nix
../../profiles/bat.nix
@@ -43,6 +42,7 @@
../../profiles/zk.nix
../../profiles/zoxide.nix
../../profiles/zsh.nix
inputs.nixvim.homeModules.nixvim
];
fonts.fontconfig.enable = true;
programs.git.settings.user.email = "christoph@schmatzler.com";

View File

@@ -1,8 +1,9 @@
{
modulesPath,
hostname,
config,
inputs,
user,
hostname,
modulesPath,
...
}: {
imports = [
@@ -11,19 +12,33 @@
./disk-config.nix
./hardware-configuration.nix
./secrets.nix
../../modules/gitea.nix
../../profiles/core.nix
../../profiles/openssh.nix
../../profiles/fail2ban.nix
../../profiles/gitea.nix
../../profiles/nixos.nix
../../profiles/openssh.nix
../../profiles/tailscale.nix
inputs.disko.nixosModules.disko
inputs.sops-nix.nixosModules.sops
];
my.gitea = {
enable = true;
litestream = {
bucket = "michael-gitea-litestream";
secretFile = config.sops.secrets.michael-gitea-litestream.path;
};
restic = {
bucket = "michael-gitea-repositories";
passwordFile = config.sops.secrets.michael-gitea-restic-password.path;
environmentFile = config.sops.secrets.michael-gitea-restic-env.path;
};
};
networking.hostName = hostname;
home-manager.users.${user} = {
imports = [
inputs.nixvim.homeModules.nixvim
../../profiles/bash.nix
../../profiles/bat.nix
../../profiles/direnv.nix
@@ -40,8 +55,7 @@
../../profiles/ssh.nix
../../profiles/starship.nix
../../profiles/zoxide.nix
inputs.nixvim.homeModules.nixvim
];
};
networking.hostName = hostname;
}

View File

@@ -1,20 +1,22 @@
{...}: {
sops.secrets.gitea-litestream = {
sops.secrets = {
michael-gitea-litestream = {
sopsFile = ../../secrets/michael-gitea-litestream;
format = "binary";
owner = "gitea";
group = "gitea";
};
sops.secrets.restic-gitea-password = {
sopsFile = ../../secrets/michael-restic-gitea-password;
michael-gitea-restic-password = {
sopsFile = ../../secrets/michael-gitea-restic-password;
format = "binary";
owner = "gitea";
group = "gitea";
};
sops.secrets.restic-gitea-env = {
sopsFile = ../../secrets/michael-restic-gitea-env;
michael-gitea-restic-env = {
sopsFile = ../../secrets/michael-gitea-restic-env;
format = "binary";
owner = "gitea";
group = "gitea";
};
};
}

View File

@@ -10,15 +10,16 @@
./paperless.nix
./secrets.nix
../../profiles/core.nix
../../profiles/openssh.nix
../../profiles/nixos.nix
../../profiles/openssh.nix
../../profiles/tailscale.nix
inputs.sops-nix.nixosModules.sops
];
networking.hostName = hostname;
home-manager.users.${user} = {
imports = [
inputs.nixvim.homeModules.nixvim
../../profiles/atuin.nix
../../profiles/bash.nix
../../profiles/bat.nix
@@ -41,6 +42,7 @@
../../profiles/zk.nix
../../profiles/zoxide.nix
../../profiles/zsh.nix
inputs.nixvim.homeModules.nixvim
];
programs.git.settings.user.email = "christoph@schmatzler.com";
@@ -54,6 +56,4 @@
size = 16 * 1024;
}
];
networking.hostName = hostname;
}

View File

@@ -1,10 +1,5 @@
{
config,
hostname,
...
}: {
{config, ...}: {
networking = {
hostName = hostname;
useDHCP = false;
interfaces.eno1.ipv4.addresses = [
{

198
modules/gitea.nix Normal file
View File

@@ -0,0 +1,198 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.my.gitea;
in {
options.my.gitea = {
enable = mkEnableOption "Gitea git hosting service";
litestream = {
bucket =
mkOption {
type = types.str;
description = "S3 bucket name for Litestream database replication";
};
secretFile =
mkOption {
type = types.path;
description = "Path to the environment file containing S3 credentials for Litestream";
};
};
restic = {
bucket =
mkOption {
type = types.str;
description = "S3 bucket name for Restic repository backups";
};
passwordFile =
mkOption {
type = types.path;
description = "Path to the file containing the Restic repository password";
};
environmentFile =
mkOption {
type = types.path;
description = "Path to the environment file containing S3 credentials for Restic";
};
};
s3 = {
endpoint =
mkOption {
type = types.str;
default = "s3.eu-central-003.backblazeb2.com";
description = "S3 endpoint URL";
};
};
};
config =
mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [80 443];
services.redis.servers.gitea = {
enable = true;
port = 6380;
bind = "127.0.0.1";
settings = {
maxmemory = "64mb";
maxmemory-policy = "allkeys-lru";
};
};
services.gitea = {
enable = true;
database = {
type = "sqlite3";
path = "/var/lib/gitea/data/gitea.db";
};
settings = {
server = {
ROOT_URL = "https://git.schmatzler.com/";
DOMAIN = "git.schmatzler.com";
HTTP_ADDR = "127.0.0.1";
HTTP_PORT = 3000;
LANDING_PAGE = "explore";
};
service.DISABLE_REGISTRATION = true;
security.INSTALL_LOCK = true;
cache = {
ADAPTER = "redis";
HOST = "redis://127.0.0.1:6380/0?pool_size=100&idle_timeout=180s";
ITEM_TTL = "16h";
};
"cache.last_commit" = {
ITEM_TTL = "8760h";
COMMITS_COUNT = 100;
};
session = {
PROVIDER = "redis";
PROVIDER_CONFIG = "redis://127.0.0.1:6380/1?pool_size=100&idle_timeout=180s";
COOKIE_SECURE = true;
SAME_SITE = "strict";
};
api.ENABLE_SWAGGER = false;
};
};
services.litestream = {
enable = true;
environmentFile = cfg.litestream.secretFile;
settings = {
dbs = [
{
path = "/var/lib/gitea/data/gitea.db";
replicas = [
{
type = "s3";
bucket = cfg.litestream.bucket;
path = "gitea";
endpoint = cfg.s3.endpoint;
}
];
}
];
};
};
systemd.services.litestream = {
serviceConfig = {
User = mkForce "gitea";
Group = mkForce "gitea";
};
};
services.caddy = {
enable = true;
virtualHosts."git.schmatzler.com".extraConfig = ''
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
reverse_proxy localhost:3000
'';
};
services.restic.backups.gitea = {
repository = "s3:${cfg.s3.endpoint}/${cfg.restic.bucket}";
paths = ["/var/lib/gitea"];
exclude = [
"/var/lib/gitea/log"
"/var/lib/gitea/data/gitea.db"
"/var/lib/gitea/data/gitea.db-shm"
"/var/lib/gitea/data/gitea.db-wal"
];
passwordFile = cfg.restic.passwordFile;
environmentFile = cfg.restic.environmentFile;
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 6"
];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
RandomizedDelaySec = "1h";
};
};
systemd.services.restic-backups-gitea = {
wants = ["restic-init-gitea.service"];
after = ["restic-init-gitea.service"];
serviceConfig = {
User = mkForce "gitea";
Group = mkForce "gitea";
};
};
systemd.services.restic-init-gitea = {
description = "Initialize Restic repository for Gitea backups";
wantedBy = ["multi-user.target"];
after = ["network-online.target"];
wants = ["network-online.target"];
path = [pkgs.restic];
serviceConfig = {
Type = "oneshot";
User = "gitea";
Group = "gitea";
RemainAfterExit = true;
EnvironmentFile = cfg.restic.environmentFile;
};
script = ''
export RESTIC_PASSWORD=$(cat ${cfg.restic.passwordFile})
restic -r s3:${cfg.s3.endpoint}/${cfg.restic.bucket} snapshots &>/dev/null || \
restic -r s3:${cfg.s3.endpoint}/${cfg.restic.bucket} init
'';
};
};
}

View File

@@ -34,20 +34,17 @@ in {
default = "s3.eu-central-003.backblazeb2.com";
description = "S3 endpoint URL";
};
bucket =
mkOption {
type = types.str;
description = "S3 bucket name";
};
region =
mkOption {
type = types.str;
default = "eu-central-003";
description = "S3 region";
};
path =
mkOption {
type = types.str;
@@ -71,7 +68,6 @@ in {
default = 7;
description = "Number of full backups to retain";
};
diff =
mkOption {
type = types.int;
@@ -95,7 +91,6 @@ in {
default = "zst";
description = "Compression algorithm (none, gz, lz4, zst)";
};
level =
mkOption {
type = types.int;
@@ -126,7 +121,6 @@ in {
default = "daily";
description = "OnCalendar expression for full backups";
};
diff =
mkOption {
type = types.str;

View File

@@ -1,8 +1,8 @@
{
constants,
inputs,
pkgs,
inputs,
user,
constants,
...
}: {
home-manager.extraSpecialArgs = {inherit user constants inputs;};

View File

@@ -1,7 +1,7 @@
{
config,
pkgs,
lib,
pkgs,
user,
...
}:

View File

@@ -1,145 +0,0 @@
{
lib,
pkgs,
config,
...
}: {
networking.firewall.allowedTCPPorts = [80 443];
services.redis.servers.gitea = {
enable = true;
port = 6380;
bind = "127.0.0.1";
settings = {
maxmemory = "64mb";
maxmemory-policy = "allkeys-lru";
};
};
services.gitea = {
enable = true;
database = {
type = "sqlite3";
path = "/var/lib/gitea/data/gitea.db";
};
settings = {
server = {
ROOT_URL = "https://git.schmatzler.com/";
DOMAIN = "git.schmatzler.com";
HTTP_ADDR = "127.0.0.1";
HTTP_PORT = 3000;
LANDING_PAGE = "explore";
};
service.DISABLE_REGISTRATION = true;
security.INSTALL_LOCK = true;
cache = {
ADAPTER = "redis";
HOST = "redis://127.0.0.1:6380/0?pool_size=100&idle_timeout=180s";
ITEM_TTL = "16h";
};
"cache.last_commit" = {
ITEM_TTL = "8760h";
COMMITS_COUNT = 100;
};
session = {
PROVIDER = "redis";
PROVIDER_CONFIG = "redis://127.0.0.1:6380/1?pool_size=100&idle_timeout=180s";
COOKIE_SECURE = true;
SAME_SITE = "strict";
};
api.ENABLE_SWAGGER = false;
};
};
services.litestream = {
enable = true;
environmentFile = "/run/secrets/gitea-litestream";
settings = {
dbs = [
{
path = "/var/lib/gitea/data/gitea.db";
replicas = [
{
type = "s3";
bucket = "michael-gitea-litestream";
path = "gitea";
endpoint = "s3.eu-central-003.backblazeb2.com";
}
];
}
];
};
};
systemd.services.litestream = {
serviceConfig = {
User = lib.mkForce "gitea";
Group = lib.mkForce "gitea";
};
};
services.caddy = {
enable = true;
virtualHosts."git.schmatzler.com".extraConfig = ''
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
reverse_proxy localhost:3000
'';
};
services.restic.backups.gitea = {
repository = "s3:s3.eu-central-003.backblazeb2.com/michael-gitea-repositories";
paths = ["/var/lib/gitea"];
exclude = [
"/var/lib/gitea/log"
"/var/lib/gitea/data/gitea.db"
"/var/lib/gitea/data/gitea.db-shm"
"/var/lib/gitea/data/gitea.db-wal"
];
passwordFile = "/run/secrets/restic-gitea-password";
environmentFile = "/run/secrets/restic-gitea-env";
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 6"
];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
RandomizedDelaySec = "1h";
};
};
systemd.services.restic-backups-gitea = {
wants = ["restic-init-gitea.service"];
after = ["restic-init-gitea.service"];
serviceConfig = {
User = lib.mkForce "gitea";
Group = lib.mkForce "gitea";
};
};
systemd.services.restic-init-gitea = {
description = "Initialize Restic repository for Gitea backups";
wantedBy = ["multi-user.target"];
after = ["network-online.target"];
wants = ["network-online.target"];
path = [pkgs.restic];
serviceConfig = {
Type = "oneshot";
User = "gitea";
Group = "gitea";
RemainAfterExit = true;
EnvironmentFile = config.sops.secrets.restic-gitea-env.path;
};
script = ''
export RESTIC_PASSWORD=$(cat ${config.sops.secrets.restic-gitea-password.path})
restic -r s3:s3.eu-central-003.backblazeb2.com/gitea-restic snapshots &>/dev/null || \
restic -r s3:s3.eu-central-003.backblazeb2.com/gitea-restic init
'';
};
}

View File

@@ -1,8 +1,8 @@
{
pkgs,
lib,
constants,
pkgs,
inputs,
constants,
...
}: let
setWallpaperScript = import ./wallpaper.nix {inherit pkgs;};

View File

@@ -1,8 +1,8 @@
{
pkgs,
inputs,
user,
constants,
inputs,
...
}: {
security.sudo.enable = true;

View File

@@ -1,6 +1,6 @@
{
lib,
pkgs,
inputs,
...
}:
with pkgs;

View File

@@ -1,8 +1,4 @@
{
lib,
pkgs,
...
}: {
{pkgs, ...}: {
programs.zellij = {
enable = true;
settings = {