infrastructure/machines/nixos/compute01/dgsi/default.nix

227 lines
5.3 KiB
Nix
Raw Normal View History

# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
#
# SPDX-License-Identifier: EUPL-1.2
2024-09-24 20:54:22 +02:00
{
config,
lib,
pkgs,
2024-09-25 13:57:55 +02:00
utils,
2024-09-24 20:54:22 +02:00
sources,
...
}:
let
inherit (lib) toLower;
2024-09-24 20:54:22 +02:00
python =
let
python3 = pkgs.python312;
nix-pkgs = import sources.nix-pkgs { inherit pkgs python3; };
in
python3.override {
packageOverrides = _: _: {
inherit (nix-pkgs)
django-allauth
django-allauth-cas
django-browser-reload
django-bulma-forms
django-sass-processor
django-sass-processor-dart-sass
django-unfold
pykanidm
python-cas
loadcredential
2024-09-27 13:23:55 +02:00
xlwt
2024-09-24 20:54:22 +02:00
;
};
};
pythonEnv = python.withPackages (
ps:
[
ps.django
ps.gunicorn
ps.psycopg
ps.django-compressor
ps.django-import-export
2024-09-24 20:54:22 +02:00
# Local packages
ps.django-allauth
ps.django-allauth-cas
ps.django-browser-reload
ps.django-bulma-forms
ps.django-sass-processor
ps.django-sass-processor-dart-sass
ps.django-unfold
ps.loadcredential
ps.pykanidm
ps.python-cas
]
++ ps.django-allauth.optional-dependencies.saml
);
2024-09-24 20:54:22 +02:00
staticDrv = pkgs.stdenv.mkDerivation {
name = "dgsi-static";
src = sources.dgsi;
sourceRoot = "source/src";
nativeBuildInputs = [
pkgs.dart-sass
pythonEnv
];
configurePhase = ''
export DGSI_STATIC_ROOT=$out/static
export CREDENTIALS_DIRECTORY=$(pwd)/../.credentials
export DGSI_KANIDM_CLIENT="dgsi_test"
export DGSI_KANIDM_AUTH_TOKEN="fake.token"
export DGSI_X509_KEY=""
export DGSI_X509_CERT=""
2024-09-24 20:54:22 +02:00
'';
doBuild = false;
installPhase = ''
mkdir -p $out/static
python3 manage.py compilescss
python3 manage.py collectstatic
'';
};
in
{
users = {
users.nginx.extraGroups = [ "django-apps" ];
groups.django-apps = { };
};
systemd = {
services = {
dj-dgsi = {
description = "DGSI web app";
requires = [ "dj-dgsi.socket" ];
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"postgresql.service"
];
serviceConfig = {
DynamicUser = true;
LoadCredential = map (name: "${name}:${config.age.secrets."dgsi-${toLower name}_file".path}") [
"EMAIL_HOST_PASSWORD"
"KANIDM_AUTH_TOKEN"
"KANIDM_SECRET"
"SECRET_KEY"
"X509_CERT"
"X509_KEY"
];
2024-09-24 20:54:22 +02:00
RuntimeDirectory = "django-apps/dgsi";
2024-09-25 13:57:55 +02:00
StateDirectory = "django-apps/dgsi";
2024-09-24 20:54:22 +02:00
UMask = "0027";
User = "dj-dgsi";
2024-09-25 13:57:55 +02:00
Group = "django-apps";
WorkingDirectory = sources.dgsi;
ExecReload = "${lib.getExe' pkgs.coreutils "kill"} -s HUP $MAINPID";
KillMode = "mixed";
Type = "notify";
ExecStart = utils.escapeSystemdExecArgs [
(lib.getExe' pythonEnv "gunicorn")
"--workers"
4
"--bind"
"unix:/run/django-apps/dgsi.sock"
"--pythonpath"
"src"
"app.wsgi"
];
2024-09-24 20:54:22 +02:00
};
environment = {
DGSI_ALLOWED_HOSTS = builtins.toJSON [
"profil.dgnum.eu"
"dgsi.dgnum.eu"
];
2024-09-26 15:23:43 +02:00
DGSI_EMAIL_HOST = "kurisu.lahfa.xyz";
2024-09-25 13:57:55 +02:00
DGSI_EMAIL_HOST_USER = "web-services@infra.dgnum.eu";
DGSI_EMAIL_USE_SSL = builtins.toJSON true;
2024-09-26 15:23:43 +02:00
DGSI_FROM_EMAIL = "La Délégation Générale Numérique <noreply@infra.dgnum.eu>";
2024-09-25 13:57:55 +02:00
DGSI_SERVER_EMAIL = "dgsi@infra.dgnum.eu";
2024-09-26 15:23:43 +02:00
DGSI_KANIDM_CLIENT = "dgsi";
2024-09-25 13:57:55 +02:00
DGSI_KANIDM_URI = "https://sso.dgnum.eu";
2024-09-26 15:23:43 +02:00
2024-09-24 20:54:22 +02:00
DGSI_MEDIA_ROOT = "/var/lib/django-apps/dgsi/media";
2024-09-25 13:57:55 +02:00
DGSI_STATIC_ROOT = "${staticDrv}/static";
2024-09-26 15:23:43 +02:00
2024-09-25 13:57:55 +02:00
DGSI_DATABASES = builtins.toJSON {
default = {
ENGINE = "django.db.backends.postgresql";
NAME = "dj-dgsi";
};
};
DJANGO_SETTINGS_MODULE = "app.settings";
2024-09-24 20:54:22 +02:00
};
path = [ pythonEnv ];
2024-09-25 13:57:55 +02:00
preStart = ''
python3 src/manage.py migrate --no-input
2024-09-24 20:54:22 +02:00
'';
};
};
sockets."dj-dgsi" = {
description = "Socket for the DGSI Django Application";
wantedBy = [ "sockets.target" ];
socketConfig = {
ListenStream = "/run/django-apps/dgsi.sock";
SocketMode = "600";
SocketUser = config.services.nginx.user;
};
};
mounts = [
{
where = "/run/django-apps/dgsi/media";
what = "/var/lib/django-apps/dgsi/media";
options = "bind";
after = [ "dj-dgsi.service" ];
partOf = [ "dj-dgsi.service" ];
upheldBy = [ "dj-dgsi.service" ];
}
];
};
dgn-redirections.permanent."dgsi.dgnum.eu" = "profil.dgnum.eu";
2024-09-24 20:54:22 +02:00
services = {
postgresql = {
2024-09-25 13:57:55 +02:00
ensureDatabases = [ "dj-dgsi" ];
2024-09-24 20:54:22 +02:00
ensureUsers = [
{
2024-09-25 13:57:55 +02:00
name = "dj-dgsi";
2024-09-24 20:54:22 +02:00
ensureDBOwnership = true;
}
];
};
nginx.virtualHosts."profil.dgnum.eu" = {
enableACME = true;
forceSSL = true;
locations = {
"/".proxyPass = "http://unix:/run/django-apps/dgsi.sock";
"/static/".root = staticDrv;
"/media/".root = "/run/django-apps/dgsi";
};
};
};
}