Compare commits

...

5 Commits

Author SHA1 Message Date
fd27d8d985 traccar: route tracking through caddy for tls
All checks were successful
Build and Deploy / deploy (push) Successful in 1m36s
2026-04-12 20:59:19 -04:00
f2ca84ab53 traccar: fix jdbc url escaping for envsubst and xml
Some checks failed
Build and Deploy / deploy (push) Failing after 1m6s
2026-04-12 20:47:20 -04:00
c497986ed0 AGENTS.md: document postgresql-first policy 2026-04-12 20:47:20 -04:00
39a178d59b traccar: use postgresql via unix socket
Some checks failed
Build and Deploy / deploy (push) Failing after 59s
2026-04-12 16:26:46 -04:00
932c9c17f2 traccar: replace owntracks with traccar
Some checks failed
Build and Deploy / deploy (push) Failing after 2m0s
2026-04-12 16:15:52 -04:00
4 changed files with 99 additions and 0 deletions

View File

@@ -112,6 +112,7 @@ Each service file in `services/` follows this structure:
- **Hugepages**: Services needing large pages declare their budget in `service-configs.nix` under `hugepages_2m.services`. The kernel sysctl is set automatically from the total.
- **Domain**: Primary domain is `sigkill.computer`. Old domain `gardling.com` redirects automatically.
- **Hardened kernel**: Uses `_hardened` kernel. Security-sensitive defaults apply.
- **PostgreSQL as central database**: All services that support PostgreSQL MUST use it instead of embedded databases (H2, SQLite, etc.). Connect via Unix socket with peer auth when possible (JDBC services can use junixsocket). The PostgreSQL instance is declared in `services/postgresql.nix` with ZFS-backed storage. Use `ensureDatabases`/`ensureUsers` to auto-create databases and roles.
### Test Pattern
Tests use `pkgs.testers.runNixOSTest` (NixOS VM tests):

View File

@@ -73,6 +73,8 @@
./services/harmonia.nix
./services/ddns-updater.nix
./services/traccar.nix
];
# Hosts entries for CI/CD deploy targets

View File

@@ -197,6 +197,14 @@ rec {
port = 5500;
proto = "tcp";
};
traccar_web = {
port = 8082;
proto = "tcp";
};
traccar_tracking = {
port = 5056;
proto = "tcp";
};
};
};
@@ -330,6 +338,10 @@ rec {
dataDir = services_dir + "/trilium";
};
traccar = {
domain = "traccar.${https.domain}";
};
media = {
moviesDir = torrents_path + "/media/movies";
tvDir = torrents_path + "/media/tv";

84
services/traccar.nix Normal file
View File

@@ -0,0 +1,84 @@
{
pkgs,
service_configs,
lib,
...
}:
{
imports = [
(lib.serviceMountWithZpool "traccar" service_configs.zpool_ssds [
"/var/lib/traccar"
])
(lib.serviceFilePerms "traccar" [
"Z /var/lib/traccar 0700 traccar traccar"
])
];
users.users.traccar = {
isSystemUser = true;
group = "traccar";
home = "/var/lib/traccar";
description = "Traccar GPS Tracking";
};
users.groups.traccar = { };
# PostgreSQL database (auto-created, peer auth via Unix socket)
services.postgresql = {
ensureDatabases = [ "traccar" ];
ensureUsers = [
{
name = "traccar";
ensureDBOwnership = true;
}
];
};
services.traccar = {
enable = true;
# The JDBC URL contains '$' (Java inner class) and '&' (query param
# separator) which break the NixOS module's XML generator + envsubst.
# Route it through environmentFile so envsubst replaces $TRACCAR_DB_URL
# with the literal value, and use & for valid XML (the XML parser
# decodes it back to & for JDBC).
environmentFile = pkgs.writeText "traccar-db-env" ''
TRACCAR_DB_URL=jdbc:postgresql:///traccar?socketFactory=org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg&socketFactoryArg=${service_configs.postgres.socket}/.s.PGSQL.5432
'';
settings = {
web.port = toString service_configs.ports.private.traccar_web.port;
# PostgreSQL via Unix socket (peer auth, junixsocket is bundled)
database = {
driver = "org.postgresql.Driver";
url = "$TRACCAR_DB_URL";
user = "traccar";
password = "";
};
# Only enable OsmAnd protocol (phone app). Prevents Traccar from
# opening 200+ default protocol ports that conflict with other services.
protocols.enable = "osmand";
osmand.port = toString service_configs.ports.private.traccar_tracking.port;
};
};
# Disable DynamicUser so we can use peer auth with PostgreSQL
systemd.services.traccar = {
after = [ "postgresql.service" ];
requires = [ "postgresql.service" ];
serviceConfig = {
DynamicUser = lib.mkForce false;
User = "traccar";
Group = "traccar";
};
};
# Route tracking requests (OsmAnd protocol) through Caddy for TLS.
# The phone app connects via HTTPS instead of a separate plain port.
services.caddy.virtualHosts."${service_configs.traccar.domain}".extraConfig = ''
@tracking query id=*
reverse_proxy @tracking :${toString service_configs.ports.private.traccar_tracking.port}
reverse_proxy :${toString service_configs.ports.private.traccar_web.port}
'';
}