[gitea] Moves database password into an sops secret

This commit is contained in:
Drew Haven 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

View File

@ -455,9 +455,30 @@
"hyprland": "hyprland",
"nix-darwin": "nix-darwin",
"nixpkgs": "nixpkgs",
"sops-nix": "sops-nix",
"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": {
"inputs": {
"hyprland": [

View File

@ -25,6 +25,10 @@
url = "github:LnL7/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs";
};
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
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
];
# Enable flakes
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
@ -107,6 +113,19 @@
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# 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
# This value determines the NixOS release from which the default

View File

@ -3,6 +3,7 @@
{
# Additional configuration
imports = [
./containers/gitea.nix
./containers/grafana.nix
./containers/jobhunt.nix
./containers/nextcloud.nix
@ -60,14 +61,10 @@
virtualisation.oci-containers.backend = "podman";
virtualisation.oci-containers.containers =
let
havenisms = "havenisms.com";
blazestar = "blazestar.net";
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;
inherit (import ./containers/lib.nix config)
hostRuleHavenisms
localHostRuleHavenisms
havenisms;
in
{
traefik = {
@ -373,39 +370,5 @@
"/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_USER = "jobhunt";
DB_DATABSE = "jobhunt";
# TODO: Store secret
DB_PASSWORD = "jobhunt123";
};
};

View File

@ -1,14 +1,36 @@
config:
let
hostRule = host: "Host(`${host}.${config.domainName}`)";
localNetRule = "ClientIP(`${config.localNet}`)";
localHostRule = host: "${localNetRule} && ${hostRule host}";
havenisms = "havenisms.com";
blazestar = "blazestar.net";
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
{
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
{
image = image;
@ -21,10 +43,10 @@ in
"-l=homepage.group=${homepageOpts.group}"
"-l=homepage.name=${homepageOpts.name}"
"-l=homepage.icon=${homepageOpts.icon}"
"-l=homepage.href=https://${hostName}.${config.domainName}"
"-l=homepage.href=https://${hostName}.${domain}"
"-l=homepage.description=${homepageOpts.description}"
];
volumes = volumes;
environment = environment;
};
}
}

View File

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

View File

@ -1,6 +1,6 @@
{ config, pkgs, ... }:
{ config, ... }:
let
inherit (import ./lib.nix config) localHostRule;
inherit (import ./lib.nix config) blazestar localHostRule;
inherit (import ./secrets.nix) minioAdminPassword;
in
{
@ -12,7 +12,7 @@ in
];
cmd = [ "server" "/data" "--console-address" ":9001" ];
environment = {
MINIO_BROWSER_REDIRECT_URL = "https://console.minio.havenisms.com/";
MINIO_BROWSER_REDIRECT_URL = "https://console.minio.${blazestar}/";
MINIO_ROOT_USER = "minioadmin";
MINIO_ROOT_PASSWORD = minioAdminPassword;
};
@ -27,8 +27,8 @@ in
"-l=homepage.group=Infra"
"-l=homepage.name=Minio"
"-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"
];
};
}
}

View File

@ -1,18 +1,18 @@
{ config, ... }:
let
inherit (import ./lib.nix config) hostRule;
inherit (import ./lib.nix config) havenisms hostRule;
in
{
virtualisation.oci-containers.containers.nextcloud = {
image = "docker.io/library/nextcloud:latest";
extraOptions = [
"-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=homepage.group=Apps"
"-l=homepage.name=NextCloud"
"-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.widget.type=nextcloud"
"-l=homepage.widget.url=http://nextcloud.havenisms.com:8080"
@ -24,6 +24,7 @@ in
POSTGRES_HOST = "db";
POSTGRES_DB = "nextcloud";
POSTGRES_USER = "nextcloud";
# TODO: Secrets
POSTGRES_PASSWORD = "nextcloud123";
};
};

View File

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

View File

@ -1,5 +1,5 @@
{ config, pkgs, ... }:
let inherit (import ./lib.nix config) hostRule;
{ config, ... }:
let inherit (import ./lib.nix config) hostRule havenisms;
syncRule = "(PathPrefix(`/client/`) || PathPrefix(`/_matrix/client/unstable/org.matrix.msc3575/sync`))";
wellKnownRule = "PathPrefix(`/.well-known`)";
in
@ -19,7 +19,7 @@ in
];
extraOptions = [
"-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"
];
};
@ -39,7 +39,7 @@ in
};
extraOptions = [
"-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"
];
};
@ -52,9 +52,9 @@ in
];
extraOptions = [
"-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"
];
};
};
}
}

View File

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

View File

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