lenticular_cloud2/module.nix

170 lines
5.2 KiB
Nix
Raw Normal View History

2023-09-30 10:58:24 +00:00
{ config, pkgs, lib, ... }:
2023-03-18 11:00:49 +00:00
let
2023-09-30 10:58:24 +00:00
cfg = config.services.lenticular-cloud;
python = pkgs.python3;
2023-12-17 13:47:38 +00:00
format = pkgs.formats.json {};
types = lib.types;
2023-12-23 01:41:26 +00:00
config_oauth_secret = "${cfg.settings.DATA_FOLDER}/lenticular_oauth_secret.toml";
2023-03-18 11:00:49 +00:00
in
{
options = with lib.options; {
2023-10-20 07:58:32 +00:00
services.lenticular-cloud = {
2023-03-18 11:00:49 +00:00
enable = mkEnableOption "lenticluar service enable";
2023-10-09 19:58:44 +00:00
domain = mkOption {
2023-11-13 14:15:39 +00:00
type = lib.types.str;
example = "example.com";
};
2023-12-17 13:47:38 +00:00
username = mkOption {
type = lib.types.str;
description = mdDoc "user to run the service";
2023-12-17 14:31:19 +00:00
default = "lenticular_cloud";
2023-12-17 13:47:38 +00:00
};
2023-11-13 14:15:39 +00:00
service_domain = mkOption {
2023-10-09 19:58:44 +00:00
type = lib.types.str;
example = "account.example.com";
};
settings = mkOption {
2023-12-17 13:47:38 +00:00
description = mdDoc ''
Lenticular cloud settings
'';
2023-10-09 19:58:44 +00:00
2023-12-17 13:47:38 +00:00
default = { };
type = types.submodule {
freeformType = format.type;
options = {
DOMAIN = mkOption {
type = types.str;
description = mdDoc "Top level Domain of the service";
default = cfg.domain;
};
PUBLIC_URL = mkOption {
type = types.str;
description = mdDoc "public service url";
default = "https://${cfg.service_domain}";
};
2023-12-24 10:09:41 +00:00
ADMINS = mkOption {
type = types.listOf types.str;
description = mdDoc "list of admin users";
example = [ "tuxcoder" ];
};
2023-12-17 13:47:38 +00:00
DATA_FOLDER = mkOption {
type = types.str;
default = "/var/lib/${cfg.username}";
};
PKI_PATH = mkOption {
type = types.str;
default = "${cfg.settings.DATA_FOLDER}/pki";
};
SQLALCHEMY_DATABASE_URI = mkOption {
type = types.str;
2023-12-17 14:31:19 +00:00
default = "postgresql://${cfg.username}@/${cfg.username}?host=/run/postgresql";
2023-12-17 13:47:38 +00:00
};
HYDRA_ADMIN_URL = mkOption {
type = types.str;
default = "https://${config.services.ory-hydra.admin_domain}";
};
HYDRA_PUBLIC_URL = mkOption {
type = types.str;
default = "https://${config.services.ory-hydra.public_domain}";
};
};
};
2023-10-09 19:58:44 +00:00
};
2023-03-18 11:00:49 +00:00
};
};
config = {
2023-09-30 10:58:24 +00:00
environment.systemPackages = [ pkgs.lenticular-cloud ];
nixpkgs.overlays = [
(import ./overlay.nix)
];
2023-03-18 11:00:49 +00:00
users = {
2023-12-17 14:31:19 +00:00
groups."${cfg.username}" = {
2023-03-18 11:00:49 +00:00
};
2023-12-17 14:31:19 +00:00
users."${cfg.username}" = {
2023-03-18 11:00:49 +00:00
createHome = true;
2023-12-17 14:31:19 +00:00
home = "/var/lib/${cfg.username}";
2023-03-18 11:00:49 +00:00
description = "web server";
extraGroups = [
2023-10-09 19:58:44 +00:00
# "ory-hydra"
2023-03-18 11:00:49 +00:00
];
2023-12-17 14:31:19 +00:00
group = cfg.username;
2023-03-18 11:00:49 +00:00
isSystemUser = true;
};
};
2023-10-09 19:58:44 +00:00
services.postgresql = {
enable = true;
2023-12-17 14:31:19 +00:00
ensureDatabases = [ cfg.username ];
2023-10-09 19:58:44 +00:00
ensureUsers = [
{
2023-12-17 14:31:19 +00:00
name = cfg.username;
2023-12-17 13:47:38 +00:00
ensureDBOwnership = true;
2023-10-09 19:58:44 +00:00
}
];
2023-12-17 13:47:38 +00:00
};
services.ory-hydra.settings = {
urls = {
login = "${cfg.settings.PUBLIC_URL}/auth/login";
logout = "${cfg.settings.PUBLIC_URL}/auth/logout";
consent = "${cfg.settings.PUBLIC_URL}/auth/consent";
error = "${cfg.settings.PUBLIC_URL}/auth/error";
};
2023-10-09 19:58:44 +00:00
};
services.nginx.enable = true;
2023-11-13 14:15:39 +00:00
services.nginx.virtualHosts."${cfg.service_domain}" = {
2023-10-09 19:58:44 +00:00
addSSL = true;
enableACME = true;
2023-11-13 14:15:39 +00:00
serverName = cfg.service_domain;
2023-10-09 19:58:44 +00:00
locations."/" = {
recommendedProxySettings = true;
2023-12-17 14:31:19 +00:00
proxyPass = "http://unix:/run/${cfg.username}/web.sock";
2023-10-09 19:58:44 +00:00
};
};
2023-12-17 14:31:19 +00:00
users.users.nginx.extraGroups = [ cfg.username ];
2023-10-09 19:58:44 +00:00
2023-03-18 11:00:49 +00:00
systemd.services.lenticular-cloud = {
description = "lenticular account";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
2023-10-20 07:58:32 +00:00
requires = [ "ory-hydra.service" "postgresql.service" ];
2023-09-30 10:58:24 +00:00
enable = cfg.enable;
2023-03-18 11:00:49 +00:00
environment = let
2023-10-20 07:58:32 +00:00
python_path = with python.pkgs; makePythonPath [ pkgs.lenticular-cloud gevent setuptools ];
2023-12-23 01:41:26 +00:00
config_file = format.generate "lenticular-cloud.json" cfg.settings;
2023-03-18 11:00:49 +00:00
in {
2023-10-09 19:58:44 +00:00
# CONFIG_FILE = "/etc/lenticular_cloud/production.conf";
2023-12-23 01:41:26 +00:00
CONFIG_FILE = "${config_file}:${config_oauth_secret}";
2023-09-30 10:58:24 +00:00
PYTHONPATH = "${python_path}";
# PYTHONPATH = "${lenticular-pkg.pythonPath}:${lenticular-pkg}/lib/python3.10/site-packages:${python_path}";
2023-03-18 11:00:49 +00:00
};
2023-10-09 19:58:44 +00:00
preStart = ''
2023-12-23 01:41:26 +00:00
if [[ ! -e "${config_oauth_secret}" ]]; then
SECRET_KEY=`${pkgs.openssl}/bin/openssl rand --hex 16`
echo 'OAUTH_SECRET="$${SECRET_KEY}"' > ${config_oauth_secret}
echo "oauth secreted generated"
fi
2023-10-09 19:58:44 +00:00
${pkgs.lenticular-cloud}/bin/lenticular_cloud-cli db_upgrade
'';
2023-03-18 11:00:49 +00:00
serviceConfig = {
Type = "simple";
2023-12-17 14:31:19 +00:00
WorkingDirectory = cfg.settings.DATA_FOLDER;
User = cfg.username;
2023-09-30 10:58:24 +00:00
ExecStart = ''${python.pkgs.gunicorn}/bin/gunicorn lenticular_cloud.wsgi --name lenticular_cloud \
2023-12-23 01:41:26 +00:00
--workers 2 --log-level=info \
2023-12-17 14:31:19 +00:00
--bind=unix:/run/${cfg.username}/web.sock \
2023-03-18 11:00:49 +00:00
-k gevent'';
Restart = "on-failure";
2023-12-17 14:31:19 +00:00
RuntimeDirectory = cfg.username;
2023-03-18 11:00:49 +00:00
};
};
};
}