dotfiles/modules/nixos/services/teslamate/default.nix

163 lines
4.2 KiB
Nix
Raw Permalink Normal View History

2024-02-06 04:20:02 +00:00
{
config,
lib,
...
}: let
2024-02-06 04:20:02 +00:00
cfg = config.aa.services.teslamate;
in {
options.aa.services.teslamate = with lib; {
2024-02-06 04:20:02 +00:00
enable = mkEnableOption "teslamate";
acmeCertName = mkOption {
type = types.str;
2024-02-06 04:20:02 +00:00
default = "";
description = ''
If set to a non-empty string, forces SSL with the supplied acme
certificate.
'';
};
user = mkOption {
type = types.str;
2024-02-06 04:20:02 +00:00
default = "teslamate";
description = ''
The user that should run teslamate
'';
};
group = mkOption {
type = types.str;
2024-02-06 04:20:02 +00:00
default = "teslamate";
description = ''
The group that should be assigned to the user running teslamate
'';
};
database = {
host = mkOption {
type = types.str;
2024-02-06 04:20:02 +00:00
default = "127.0.0.1";
description = ''
Database host address
'';
};
name = mkOption {
type = types.str;
2024-02-06 04:20:02 +00:00
default = "teslamate";
description = ''
The database name
'';
};
user = mkOption {
type = types.str;
2024-02-06 04:20:02 +00:00
default = "teslamate";
description = ''
The user that should have access to the database
'';
};
passwordFile = mkOption {
type = types.path;
description = mdDoc ''
2024-02-06 04:20:02 +00:00
A file containing the password corresponding to
{option}`database.user`
'';
};
createDatabase = mkOption {
type = types.bool;
2024-02-06 04:20:02 +00:00
default = false;
description = ''
Whether to create a local database automatically.
'';
};
};
};
config = lib.mkIf cfg.enable {
2024-02-06 04:20:02 +00:00
age.secrets = {
teslamate_encryption.file = ../../../../secrets/teslamate_encryption.age;
teslamate_mqtt.file = ../../../../secrets/teslamate_mqtt.age;
};
# docker-teslamate is the name of the service generated by the
# `virtualisation.oci-contianers` block below
systemd.services."docker-teslamate" = {
preStart = ''
mkdir -p /var/lib/teslamate
# Create file if it doesn't exist, truncate it if does
touch /var/lib/teslamate/env
echo "" > /var/lib/teslamate/env
chmod 600 /var/lib/teslamate/env
echo ENCRYPTION_KEY="$(cat ${config.age.secrets.teslamate_encryption.path})" >> /var/lib/teslamate/env
echo DATABASE_PASS="$(cat ${cfg.database.passwordFile})" >> /var/lib/teslamate/env
echo MQTT_PASSWORD="$(cat ${config.age.secrets.teslamate_mqtt.path})" >> /var/lib/teslamate/env
'';
};
virtualisation.oci-containers = {
backend = "docker";
containers."teslamate" = {
image = "ghcr.io/teslamate-org/teslamate:latest";
environmentFiles = ["/var/lib/teslamate/env"];
environment = {
# TODO: Make this configurable
PORT = "4000";
DATABASE_USER = cfg.database.user;
DATABASE_NAME = cfg.database.name;
DATABASE_HOST = cfg.database.host;
# TODO: Make this configurable.
MQTT_HOST = "192.168.113.42";
MQTT_USERNAME = "teslamate";
TZ = "America/Los_Angeles";
};
extraOptions = ["--cap-drop=all" "--network=host"];
# TODO: Make this configurable
ports = ["4000:4000"];
};
};
users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
};
users.groups.${cfg.group} = {};
services.postgresql = lib.optionalAttrs cfg.database.createDatabase {
enable = lib.mkDefault true;
2024-02-06 04:20:02 +00:00
ensureDatabases = [cfg.database.name];
ensureUsers = [
{
name = cfg.database.user;
ensureDBOwnership = true;
}
];
};
services.nginx = {
enable = true;
virtualHosts."teslamate.kilonull.com" =
{
locations."/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
# TODO: Make port configurable.
proxyPass = "http://127.0.0.1:4000";
};
}
// lib.optionalAttrs (cfg.acmeCertName != "") {
forceSSL = true;
useACMEHost = cfg.acmeCertName;
};
};
networking.firewall.allowedTCPPorts = [4000];
};
}