[gitea] Moves database password into an sops secret

This commit is contained in:
2025-03-18 15:38:49 -07:00
parent 18cb388ebb
commit 8bd3088bcf
16 changed files with 193 additions and 75 deletions

9
.sops.yaml Normal file
View File

@@ -0,0 +1,9 @@
keys:
- &admin_drew age1yvdzvuvu5wqztcx6ll2xk6x547uuyqy735tjjdd7zftkz53jsf9qf5ahue
- &server_mcp age1jrk4h7x4qzhr6z5m4d099mlfyjc4n5n9s52r4gfsdz0slnqlqa9sss735v
creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
key_groups:
- age:
- *admin_drew
- *server_mcp

21
flake.lock generated
View File

@@ -455,9 +455,30 @@
"hyprland": "hyprland", "hyprland": "hyprland",
"nix-darwin": "nix-darwin", "nix-darwin": "nix-darwin",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"sops-nix": "sops-nix",
"split-monitor-workspaces": "split-monitor-workspaces" "split-monitor-workspaces": "split-monitor-workspaces"
} }
}, },
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1742239755,
"narHash": "sha256-ptn8dR4Uat3UUadGYNnB7CIH9SQm8mK69D2A/twBUXQ=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "787afce414bcce803b605c510b60bf43c11f4b55",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"split-monitor-workspaces": { "split-monitor-workspaces": {
"inputs": { "inputs": {
"hyprland": [ "hyprland": [

View File

@@ -25,6 +25,10 @@
url = "github:LnL7/nix-darwin/master"; url = "github:LnL7/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = { self, nixpkgs, ... }@inputs: { outputs = { self, nixpkgs, ... }@inputs: {

30
secrets/mcp.yaml Normal file
View File

@@ -0,0 +1,30 @@
gitea_db_password: ENC[AES256_GCM,data:G2YqiDk0msBRjUJkoPxWmayQ9dI=,iv:FsojIJIi61K7rD2VULDgIx6uSYX3iDiA6W744HlgHl0=,tag:BlmsM7LZHnBCKtfuqlhoKA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1yvdzvuvu5wqztcx6ll2xk6x547uuyqy735tjjdd7zftkz53jsf9qf5ahue
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiL3FoUWN1NWlDQTAvRkFM
TkdCMWVXYThIYVZFSlVEVmxUb1JuQmpESWtrClFlTVlHdGhndFJjUWxUMVFybGtn
bEpJNkFSVnpueXlvR0NkbU90RkZoTzAKLS0tIHdTTnRteWRNbW9MVmdKSVJLeWxB
Zkpxc1lLNVFSUFA2NTJUS0UrOXJCWXMKOuZmbFBdjPIcIUUWHHfGl8TD+HIRa9Hj
Eykvc7Iv5zl61kuJRorE7DWWS1I2C586c+MZtNo6GPQxUasxWRRgJQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jrk4h7x4qzhr6z5m4d099mlfyjc4n5n9s52r4gfsdz0slnqlqa9sss735v
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZck5tK3p6blhxZWp5YkNF
b3lnMWI1dHBnQzlDOG05c0YyZlZDTzA5V2pvCis3N1BhNXlmamRFci9wWTBuRWFv
cC9kdWV3RnpFWTFVRVEwaTVWQVdnZE0KLS0tIEhOTzExRzRLaGdKOTRwRmNXcW5P
by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw
vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-03-18T22:35:18Z"
mac: ENC[AES256_GCM,data:ZmCWMW7NIjBzAxPgoUZp2BpP0q5cnelSVsQ0ccJYHRja1WXfO1d6CuNixcHyVSl02+Cn9eGt/z8dObZafOgGxYq1HwYr7VfIpv2CUb/rg/8/Lu3eB6N1+QQGZUWbm6q9s4v7NomHYd7M4GOd2ZhgSDc23zKCzMkkA7t9hyJbhKw=,iv:XWhYxBsbkTeBlZFum2CkpGpqModabgqrSCouwOh2/Gc=,tag:dBLzSTLTzSQeg820J+fk5A==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.4

View File

@@ -6,6 +6,12 @@
./containers.nix ./containers.nix
]; ];
# Enable flakes
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
# Bootloader. # Bootloader.
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
@@ -108,6 +114,19 @@
# Or disable the firewall altogether. # Or disable the firewall altogether.
# networking.firewall.enable = false; # networking.firewall.enable = false;
### Secrets
sops = {
defaultSopsFile = ../../../secrets/mcp.yaml;
age = {
# Use the host key for sops
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
# Where to store the key
keyFile = "/var/lib/sops-nix/key.txt";
# Generate the key if it doesn't exit
generateKey = true;
};
};
### State version ### State version
# This value determines the NixOS release from which the default # This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions # settings for stateful data, like file locations and database versions

View File

@@ -3,6 +3,7 @@
{ {
# Additional configuration # Additional configuration
imports = [ imports = [
./containers/gitea.nix
./containers/grafana.nix ./containers/grafana.nix
./containers/jobhunt.nix ./containers/jobhunt.nix
./containers/nextcloud.nix ./containers/nextcloud.nix
@@ -60,14 +61,10 @@
virtualisation.oci-containers.backend = "podman"; virtualisation.oci-containers.backend = "podman";
virtualisation.oci-containers.containers = virtualisation.oci-containers.containers =
let let
havenisms = "havenisms.com"; inherit (import ./containers/lib.nix config)
blazestar = "blazestar.net"; hostRuleHavenisms
hostRule = host: domain: "Host(`${host}.${domain}`)"; localHostRuleHavenisms
hostRuleHavenisms = host: hostRule host havenisms; havenisms;
localNet = "192.168.0.0/16";
localNetRule = "ClientIP(`${localNet}`)";
localHostRule = host: domain: "${localNetRule} && ${hostRule host domain}";
localHostRuleHavenisms = host: localHostRule host havenisms;
in in
{ {
traefik = { traefik = {
@@ -373,39 +370,5 @@
"/tank/config/valkey:/usr/local/etc/valkey" "/tank/config/valkey:/usr/local/etc/valkey"
]; ];
}; };
gitea = {
image = "gitea/gitea:latest-rootless";
autoStart = true;
dependsOn = [
"db"
];
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.gitea.rule=${hostRule "git" blazestar}"
"-l=traefik.http.services.gitea.loadbalancer.server.port=3000"
"-l=homepage.group=Apps"
"-l=homepage.name=Gitea"
"-l=homepage.icon=gitea.png"
"-l=homepage.href=https://git.${blazestar}"
"-l=homepage.description=Git Server"
];
ports = [
"2222:2222"
];
volumes = [
"/tank/git:/var/lib/gitea"
"/tank/config/gitea:/etc/gitea"
];
user = toString config.users.users.gitea.uid;
environment = {
USER_UID = toString config.users.users.gitea.uid;
USER_GID = toString config.users.groups.git.gid;
GITEA__database__DB_TYPE = "postgres";
GITEA__database__HOST = "db";
GITEA__database__NAME = "gitea";
GITEA__database__USER = "gitea";
GITEA__database__PASSWD = "gitea123";
};
};
}; };
} }

View File

@@ -0,0 +1,49 @@
{ config, ... }:
let
inherit (import ./lib.nix config) hostRule blazestar;
in
{
virtualisation.oci-containers.containers.gitea = {
image = "gitea/gitea:latest-rootless";
autoStart = true;
dependsOn = [
"db"
];
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.gitea.rule=${hostRule "git" blazestar}"
"-l=traefik.http.services.gitea.loadbalancer.server.port=3000"
"-l=homepage.group=Apps"
"-l=homepage.name=Gitea"
"-l=homepage.icon=gitea.png"
"-l=homepage.href=https://git.${blazestar}"
"-l=homepage.description=Git Server"
];
ports = [
"2222:2222"
];
volumes = [
"/tank/git:/var/lib/gitea"
"/tank/config/gitea:/etc/gitea"
];
user = toString config.users.users.gitea.uid;
environment = {
USER_UID = toString config.users.users.gitea.uid;
USER_GID = toString config.users.groups.git.gid;
};
environmentFiles = [
config.sops.templates."gitea.env".path
];
};
sops.secrets."gitea_db_password" = {
restartUnits = [ "podman-gitea.service" ];
};
sops.templates."gitea.env".content = ''
GITEA__database__DB_TYPE="postgres"
GITEA__database__HOST="db"
GITEA__database__NAME="gitea"
GITEA__database__USER="gitea"
GITEA__database__PASSWD="${config.sops.placeholder."gitea_db_password"}"
'';
}

View File

@@ -21,6 +21,7 @@ in
DB_HOST = "db"; DB_HOST = "db";
DB_USER = "jobhunt"; DB_USER = "jobhunt";
DB_DATABSE = "jobhunt"; DB_DATABSE = "jobhunt";
# TODO: Store secret
DB_PASSWORD = "jobhunt123"; DB_PASSWORD = "jobhunt123";
}; };
}; };

View File

@@ -1,14 +1,36 @@
config: config:
let let
hostRule = host: "Host(`${host}.${config.domainName}`)"; havenisms = "havenisms.com";
localNetRule = "ClientIP(`${config.localNet}`)"; blazestar = "blazestar.net";
localHostRule = host: "${localNetRule} && ${hostRule host}"; hostRule = host: domain: "Host(`${host}.${domain}`)";
hostRuleHavenisms = host: hostRule host havenisms;
localNet = "192.168.0.0/16";
localNetRule = "ClientIP(`${localNet}`)";
localHostRule = host: domain: "${localNetRule} && ${hostRule host domain}";
localHostRuleHavenisms = host: localHostRule host havenisms;
in in
{ {
inherit hostRule localNetRule localHostRule; inherit
hostRule
localHostRule
hostRuleHavenisms
localHostRuleHavenisms
havenisms
blazestar;
mkContainer = { image, dependsOn ? [], hostName, port, volumes ? [], environment ? [], homepageOpts, public ? false}:
let routerRule = if public then hostRule hostName else localHostRule hostName; mkContainer = {
image,
hostName,
port,
homepageOpts,
dependsOn ? [],
domain ? havenisms,
volumes ? [],
environment ? [],
public ? false
}:
let routerRule = if public then hostRule hostName domain else localHostRule hostName domain;
in in
{ {
image = image; image = image;
@@ -21,7 +43,7 @@ in
"-l=homepage.group=${homepageOpts.group}" "-l=homepage.group=${homepageOpts.group}"
"-l=homepage.name=${homepageOpts.name}" "-l=homepage.name=${homepageOpts.name}"
"-l=homepage.icon=${homepageOpts.icon}" "-l=homepage.icon=${homepageOpts.icon}"
"-l=homepage.href=https://${hostName}.${config.domainName}" "-l=homepage.href=https://${hostName}.${domain}"
"-l=homepage.description=${homepageOpts.description}" "-l=homepage.description=${homepageOpts.description}"
]; ];
volumes = volumes; volumes = volumes;

View File

@@ -1,5 +1,4 @@
{ config, pkgs, ... }: { ... }:
let inherit (import ./lib.nix config) mkContainer; in
{ {
virtualisation.oci-containers.containers.mariadb = { virtualisation.oci-containers.containers.mariadb = {
image = "mariadb:11"; image = "mariadb:11";
@@ -20,6 +19,7 @@ let inherit (import ./lib.nix config) mkContainer; in
]; ];
environment = { environment = {
MARIADB_DATABASE = "mariadb"; MARIADB_DATABASE = "mariadb";
# TODO: Secrets
MARIADB_ROOT_PASSWORD = "root123"; MARIADB_ROOT_PASSWORD = "root123";
}; };
}; };

View File

@@ -1,6 +1,6 @@
{ config, pkgs, ... }: { config, ... }:
let let
inherit (import ./lib.nix config) localHostRule; inherit (import ./lib.nix config) blazestar localHostRule;
inherit (import ./secrets.nix) minioAdminPassword; inherit (import ./secrets.nix) minioAdminPassword;
in in
{ {
@@ -12,7 +12,7 @@ in
]; ];
cmd = [ "server" "/data" "--console-address" ":9001" ]; cmd = [ "server" "/data" "--console-address" ":9001" ];
environment = { environment = {
MINIO_BROWSER_REDIRECT_URL = "https://console.minio.havenisms.com/"; MINIO_BROWSER_REDIRECT_URL = "https://console.minio.${blazestar}/";
MINIO_ROOT_USER = "minioadmin"; MINIO_ROOT_USER = "minioadmin";
MINIO_ROOT_PASSWORD = minioAdminPassword; MINIO_ROOT_PASSWORD = minioAdminPassword;
}; };
@@ -27,7 +27,7 @@ in
"-l=homepage.group=Infra" "-l=homepage.group=Infra"
"-l=homepage.name=Minio" "-l=homepage.name=Minio"
"-l=homepage.icon=mino.svg" "-l=homepage.icon=mino.svg"
"-l=homepage.href=https://minio-admin.${config.domainName}" "-l=homepage.href=https://minio-admin.${blazestar}"
"-l=homepage.description=Reverse proxy" "-l=homepage.description=Reverse proxy"
]; ];
}; };

View File

@@ -1,18 +1,18 @@
{ config, ... }: { config, ... }:
let let
inherit (import ./lib.nix config) hostRule; inherit (import ./lib.nix config) havenisms hostRule;
in in
{ {
virtualisation.oci-containers.containers.nextcloud = { virtualisation.oci-containers.containers.nextcloud = {
image = "docker.io/library/nextcloud:latest"; image = "docker.io/library/nextcloud:latest";
extraOptions = [ extraOptions = [
"-l=traefik.enable=true" "-l=traefik.enable=true"
"-l=traefik.http.routers.nextcloud.rule=${hostRule "cloud"}" "-l=traefik.http.routers.nextcloud.rule=${hostRule "cloud" havenisms}"
"-l=traefik.http.services.nextcloud.loadbalancer.server.port=80" "-l=traefik.http.services.nextcloud.loadbalancer.server.port=80"
"-l=homepage.group=Apps" "-l=homepage.group=Apps"
"-l=homepage.name=NextCloud" "-l=homepage.name=NextCloud"
"-l=homepage.icon=nextcloud.png" "-l=homepage.icon=nextcloud.png"
"-l=homepage.href=https://cloud.${config.domainName}" "-l=homepage.href=https://cloud.${havenisms}"
"-l=homepage.description=Productivity suite" "-l=homepage.description=Productivity suite"
"-l=homepage.widget.type=nextcloud" "-l=homepage.widget.type=nextcloud"
"-l=homepage.widget.url=http://nextcloud.havenisms.com:8080" "-l=homepage.widget.url=http://nextcloud.havenisms.com:8080"
@@ -24,6 +24,7 @@ in
POSTGRES_HOST = "db"; POSTGRES_HOST = "db";
POSTGRES_DB = "nextcloud"; POSTGRES_DB = "nextcloud";
POSTGRES_USER = "nextcloud"; POSTGRES_USER = "nextcloud";
# TODO: Secrets
POSTGRES_PASSWORD = "nextcloud123"; POSTGRES_PASSWORD = "nextcloud123";
}; };
}; };

View File

@@ -1,6 +1,6 @@
{ config, pkgs, ... }: { config, ... }:
let inherit (import ./lib.nix config) mkContainer; in let inherit (import ./lib.nix config) havenisms mkContainer; in
{ {
virtualisation.oci-containers.containers.searxng = mkContainer { virtualisation.oci-containers.containers.searxng = mkContainer {
hostName = "search"; hostName = "search";
@@ -20,7 +20,7 @@ let inherit (import ./lib.nix config) mkContainer; in
"/tank/config/searxng:/etc/searxng" "/tank/config/searxng:/etc/searxng"
]; ];
environment = { environment = {
SEARXNG_BASE_URL = "https://search.${config.domainName}"; SEARXNG_BASE_URL = "https://search.${havenisms}";
SEARXNG_REDIS_URL = "redis://valkey:6379/0"; SEARXNG_REDIS_URL = "redis://valkey:6379/0";
}; };
}; };

View File

@@ -1,5 +1,5 @@
{ config, pkgs, ... }: { config, ... }:
let inherit (import ./lib.nix config) hostRule; let inherit (import ./lib.nix config) hostRule havenisms;
syncRule = "(PathPrefix(`/client/`) || PathPrefix(`/_matrix/client/unstable/org.matrix.msc3575/sync`))"; syncRule = "(PathPrefix(`/client/`) || PathPrefix(`/_matrix/client/unstable/org.matrix.msc3575/sync`))";
wellKnownRule = "PathPrefix(`/.well-known`)"; wellKnownRule = "PathPrefix(`/.well-known`)";
in in
@@ -19,7 +19,7 @@ in
]; ];
extraOptions = [ extraOptions = [
"-l=traefik.enable=true" "-l=traefik.enable=true"
"-l=traefik.http.routers.synapse.rule=${hostRule "chat"} && !(${syncRule} || ${wellKnownRule})" "-l=traefik.http.routers.synapse.rule=${hostRule "chat" havenisms} && !(${syncRule} || ${wellKnownRule})"
"-l=traefik.http.services.synapse.loadbalancer.server.port=8008" "-l=traefik.http.services.synapse.loadbalancer.server.port=8008"
]; ];
}; };
@@ -39,7 +39,7 @@ in
}; };
extraOptions = [ extraOptions = [
"-l=traefik.enable=true" "-l=traefik.enable=true"
"-l=traefik.http.routers.syncv3.rule=${hostRule "chat"} && ${syncRule}" "-l=traefik.http.routers.syncv3.rule=${hostRule "chat" havenisms} && ${syncRule}"
"-l=traefik.http.services.syncv3.loadbalancer.server.port=8009" "-l=traefik.http.services.syncv3.loadbalancer.server.port=8009"
]; ];
}; };
@@ -52,7 +52,7 @@ in
]; ];
extraOptions = [ extraOptions = [
"-l=traefik.enable=true" "-l=traefik.enable=true"
"-l=traefik.http.routers.matrix-static.rule=${hostRule "chat"} && ${wellKnownRule}" "-l=traefik.http.routers.matrix-static.rule=${hostRule "chat" havenisms} && ${wellKnownRule}"
"-l=traefik.http.services.matrix-static.loadbalancer.server.port=80" "-l=traefik.http.services.matrix-static.loadbalancer.server.port=80"
]; ];
}; };

View File

@@ -5,6 +5,7 @@ nixpkgs.lib.nixosSystem {
./configuration.nix ./configuration.nix
./hardware-configuration.nix ./hardware-configuration.nix
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
inputs.sops-nix.nixosModules.sops
{ {
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
home-manager.users.drew = home-manager.users.drew =

View File

@@ -1,12 +1,10 @@
{ config, lib, ...}: { lib, ...}:
{ {
options = with lib; with types; { options = with lib; with types; {
domainName = mkOption { type = str; };
localNet = mkOption { type = str; }; localNet = mkOption { type = str; };
}; };
config = { config = {
domainName = "havenisms.com";
localNet = "192.168.0.0/16"; localNet = "192.168.0.0/16";
}; };
} }