Compare commits

...

7 commits

10 changed files with 222 additions and 9 deletions

10
.sops.yaml Normal file
View file

@ -0,0 +1,10 @@
keys:
- &tdpeuter_Tibo-NixFatDesk age1fva6s64s884z0q2w7de024sp69ucvqu0pg9shrhhqsn3ewlpjfpsh6md7y
- &tdpeuter_Tibo-NixTop age1qzutny0mqpcccqw6myyfntu6wcskruu9ghzvt6r4te7afkqwnguq05ex37
creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
key_groups:
- age:
- *tdpeuter_Tibo-NixFatDesk
- *tdpeuter_Tibo-NixTop

27
flake.lock generated
View file

@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1756787288,
"narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=",
"lastModified": 1759381078,
"narHash": "sha256-gTrEEp5gEspIcCOx9PD8kMaF1iEmfBcTbO0Jag2QhQs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1",
"rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee",
"type": "github"
},
"original": {
@ -37,9 +37,30 @@
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"sops-nix": "sops-nix",
"utils": "utils"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1759188042,
"narHash": "sha256-f9QC2KKiNReZDG2yyKAtDZh0rSK2Xp1wkPzKbHeQVRU=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "9fcfabe085281dd793589bdc770a2e577a3caa5d",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,

View file

@ -5,6 +5,10 @@
nixpkgs.url = "nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
utils = {
url = "github:gytis-ivaskevicius/flake-utils-plus";
inputs.flake-utils.follows = "flake-utils";
@ -13,11 +17,11 @@
outputs = inputs@{
self, nixpkgs,
flake-utils, utils,
flake-utils, sops-nix, utils,
...
}:
let
system = "x86_64-linux";
system = utils.lib.system.x86_64-linux;
in
utils.lib.mkFlake {
inherit self inputs;
@ -28,6 +32,8 @@
modules = [
./modules
./users
sops-nix.nixosModules.sops
];
};

View file

@ -7,6 +7,11 @@
bind9.enable = true;
traefik.enable = true;
plex.enable = true;
coder = {
enable = true;
accessUrl = "https://code.depeuter.dev";
wildcardAccessUrl = "*.code.depeuter.dev";
};
};
virtualisation.guest.enable = true;
};

View file

@ -1,6 +1,6 @@
$TTL 604800
@ IN SOA ns1 admin (
15 ; Serial
18 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
@ -40,6 +40,9 @@ sonarr IN A 192.168.0.33
; Development VM
plex IN A 192.168.0.91
code IN A 192.168.0.91
*.code IN A 192.168.0.91
; Catchalls
*.production IN A 192.168.0.31
*.development IN A 192.168.0.91

View file

@ -0,0 +1,148 @@
{ config, lib, pkgs, ... }:
let
cfg = config.homelab.apps.coder;
postgresUser = "coder";
postgresPassword = "ChangeMe";
postgresDb = "coder";
networkName = "coder";
proxyNet = config.homelab.apps.traefik.sharedNetworkName;
coderVersion = "v2.25.3";
coderDbVersion = "17.6";
in {
options.homelab.apps.coder = {
enable = lib.mkEnableOption "Coder (Docker)";
port = lib.mkOption {
type = lib.types.port;
default = 7080;
description = "Port to expose Coder on.";
};
accessUrl = lib.mkOption {
type = lib.types.str;
description = "The URL to access Coder at.";
};
wildcardAccessUrl = lib.mkOption {
type = lib.types.str;
description = "A wildcard URL to access Coder at (e.g. for workspaces).";
};
db.port = lib.mkOption {
type = lib.types.either lib.types.bool lib.types.port;
default = false;
description = "Port to expose the database on. Set to false to not expose.";
};
};
config = lib.mkIf cfg.enable {
homelab.virtualisation.containers.enable = true;
systemd.services."docker-${networkName}-create-network" = {
description = "Create Docker network for ${networkName}";
requiredBy = [
"docker-coder.service"
"docker-coderDb.service"
];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
if ! ${pkgs.docker}/bin/docker network ls | grep -q ${networkName}; then
${pkgs.docker}/bin/docker network create ${networkName}
fi
'';
};
virtualisation.oci-containers.containers = {
coder = let
coderPort = 7080;
in {
hostname = "coder";
image = "ghcr.io/coder/coder:${coderVersion}";
autoStart = true;
dependsOn = [
"coderDb"
];
extraOptions = [
"--group-add" "131" # Add docker group to access the socket
# Modify DNS
"--dns=192.168.0.91"
];
ports = [
"${toString cfg.port}:${toString coderPort}/tcp"
];
networks = [
networkName
proxyNet
];
volumes = [
"/var/run/docker.sock:/var/run/docker.sock"
];
labels = {
"traefik.enable" = "true";
"traefik.docker.network" = proxyNet;
"traefik.http.routers.coder.rule" = "HostRegexp(`.+\.code\.depeuter\.dev`) || Host(`code.depeuter.dev`)";
"traefik.http.services.coder.loadbalancer.server.port" = toString coderPort;
};
environment = {
CODER_PG_CONNECTION_URL = "postgresql://${postgresUser}:${postgresPassword}@coder-db/${postgresDb}?sslmode=disable";
# Required if you are not using the tunnel
CODER_ACCESS_URL = cfg.accessUrl;
CODER_WILDCARD_ACCESS_URL = cfg.wildcardAccessUrl;
CODER_DISABLE_PATH_APPS = "false"; # TODO Enable me!
CODER_HTTP_ADDRESS = "0.0.0.0:${toString coderPort}";
CODER_TLS_ENABLE = "false";
# TODO Enable me!
#CODER_REDIRECT_TO_ACCESS_URL = "true";
# Disable telemetry
CODER_TELEMETRY_ENABLED = "false";
};
};
coderDb = {
hostname = "coder-db";
image = "postgres:${coderDbVersion}";
autoStart = true;
extraOptions = [
''--health-cmd="pg_isready -U ${postgresUser} -d ${postgresDb}"''
"--health-interval=5s"
"--health-timeout=5s"
"--health-retries=5"
];
ports = lib.mkIf cfg.db.port [
"${toString cfg.db.port}:5432/tcp"
];
networks = [
networkName
];
volumes = [
"coder_data:/var/lib/postgresql/data"
];
environment = {
POSTGRES_USER = postgresUser;
POSTGRES_PASSWORD = postgresPassword;
POSTGRES_DB = postgresDb;
};
};
traefik.cmd = [
"--entrypoints.websecure.http.tls.domains[2].main=code.depeuter.dev"
"--entrypoints.websecure.http.tls.domains[2].sans=*.code.depeuter.dev"
];
};
virtualisation.docker.daemon.settings = {
dns = [
"192.168.0.91"
];
};
};
}

View file

@ -4,6 +4,7 @@
./bind9
./calibre
./changedetection
./coder
./freshrss
./gitea
./jellyfin

View file

@ -8,7 +8,7 @@ in {
options.homelab.apps.vaultwarden = {
enable = lib.mkEnableOption "Vaultwarden";
port = lib.mkOption {
type = lib.types.int;
type = lib.types.port;
default = 10102;
description = "Vaultwarden WebUI port";
};

19
secrets/secrets.yaml Normal file
View file

@ -0,0 +1,19 @@
users:
admin:
authorized_keys:
NixOS: ENC[AES256_GCM,data:sj2hkUkWp628KuXp+AnncLdawHpxb9fH1ZHnIisP0x9Tght9+/X2sWHpuMSeqi2i/R8B+Wgte66QkuwAOB0j+oB9N+66EhehmWZlK5hD/22p,iv:z18U+LvAQgPDfBBewE3lJmWZd0NGCPwJIe/h3tupuZc=,tag:ZJar3spO66JbDXygdTHh2w==,type:str]
sops:
age:
- recipient: age1qzutny0mqpcccqw6myyfntu6wcskruu9ghzvt6r4te7afkqwnguq05ex37
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjUSt2REk2Mmd0bk9ubjJk
dXFiY2JNR1dyZW9qTUdzaWZhY3c3amVwQzA0CkZHNVpZVjhsWXhVQVNaR0xONzhh
Y0lQaWNaNmpYYVdrRnZIZUhvUFUzcWMKLS0tIDAvSmF0VmpxcnZEQStXUjNCUE5Z
RnA2Lzk2WHFxOEh6dHN0aGhVSVpLTW8KA7IOvGDMBtgo4pe0Sw3Lol243xCDAJ4i
PhcJFiUObVRFZN7ISlULnOlTO3pT9jWvvmC5rDZWId3PQ8qjPvnOUg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-10-04T17:33:22Z"
mac: ENC[AES256_GCM,data:I7I7uDFEWfw9+4KROtjHMVhaxYrVK5QmLfFZShSajF0A2Zxu9lg+fDGiMHk40JC5zD31P70QS/ipye1mBGQbCbLEA7uBUhNzZ7G1g58cIXF6vSGmt0fovm0MVSxEJ44r05fx6uT4OJu5BYVxYSlG84gTj9rCFXxxcBJMrh+6yaI=,iv:c1vudsp9bg0Pc2ddRyvWn6Tf0LhqNuEjxG9D4PpHqxs=,tag:K/1PSHhrTdsNPcPmRv/2Ew==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View file

@ -18,8 +18,8 @@ in {
];
initialPassword = "ChangeMe";
openssh.authorizedKeys.keys = [
# TODO ChangeMe
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPrG+ldRBdCeHEXrsy/qHXIJYg8xQXVuiUR0DxhFjYNg"
# HomeLab > NixOS > admin > ssh
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGWIOOEqTy8cWKpENVbzD4p7bsQgQb/Dgpzk8i0dZ00T"
];
packages = with pkgs; [
curl