Add pretix module

This commit is contained in:
Jakob Lechner 2023-02-22 23:47:16 +00:00
parent 2a9eadaee0
commit 88d37fbee4
No known key found for this signature in database
GPG key ID: 996082EFB5906C10
3 changed files with 224 additions and 0 deletions

View file

@ -7,6 +7,7 @@
};
imports = [
../pkgs/modules.nix
./autologin.nix
./aws.nix
./bootloader

7
pkgs/modules.nix Normal file
View file

@ -0,0 +1,7 @@
{ pkgs, ... }:
{
imports = [
./pretix/module.nix
];
}

216
pkgs/pretix/module.nix Normal file
View file

@ -0,0 +1,216 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.pretix;
name = "pretix";
user = "pretix";
group = "pretix";
bind = {
host = "127.0.0.1";
port = 8000;
};
postgresql = {
database = "pretix";
user = "pretix";
password = "pretix";
};
redisPort = 6379;
urlScheme = if cfg.enableTls then "https" else "http";
url = "${urlScheme}://${cfg.domain}";
toBool = x: if x then "on" else "off";
hstsHeader = if cfg.enableTls then "add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\" always;" else "";
pythonPackages = pkgs.pretix.passthru.pythonModule.passthru.pkgs;
python = pkgs.pretix.passthru.python;
runCommandArgs = {
# Sets PYTHONPATH in derivation
buildInputs = [
pkgs.pretix
pythonPackages.gunicorn
pythonPackages.celery
];
};
staticRoot = pkgs.pretix-static;
environmentFile = pkgs.runCommand "pretix-environ" runCommandArgs ''
cat > $out <<EOF
DATA_DIR = /var/pretix
DJANGO_SETTINGS_MODULE=pretix_wrapper.settings
PRETIX_CELERY_BACKEND=redis://127.0.0.1:${toString redisPort}/2
PRETIX_CELERY_BROKER=redis://127.0.0.1:${toString redisPort}/1
PRETIX_DATABASE_BACKEND=postgresql
PRETIX_DATABASE_HOST=localhost
PRETIX_DATABASE_NAME=${postgresql.database}
PRETIX_DATABASE_PASSWORD=${postgresql.password}
PRETIX_DATABASE_USER=${postgresql.user}
PRETIX_LOCALE_DEFAULT=${cfg.locale}
PRETIX_LOCALE_TIMEZONE=${cfg.timezone}
PRETIX_PRETIX_INSTANCE_NAME=${cfg.instanceName}
PRETIX_PRETIX_PASSWORD_RESET=${toBool cfg.passwordReset}
PRETIX_PRETIX_REGISTRATION=${toBool cfg.enableRegistration}
PRETIX_PRETIX_URL=${url}
PRETIX_REDIS_LOCATION=redis://127.0.0.1:${toString redisPort}/0
PRETIX_REDIS_SESSIONS=true
PRETIX_STATIC_ROOT=${staticRoot}
PYTHONPATH=$PYTHONPATH
EOF
'';
mkTimer = { description, unit, onCalendar }: {
inherit description;
requires = [ "pretix-migrate.service" ];
after = [ "network.target" ];
wantedBy = [ "timers.target" ];
timerConfig = {
Persistent = true;
OnCalendar = onCalendar;
Unit = unit;
};
};
in
{
options.services.pretix = with lib; {
enable = mkEnableOption "Enable pretix ticket shop application";
instanceName = mkOption {
type = types.str;
description = "The name of this installation.";
};
domain = mkOption {
type = types.str;
description = "The installations domain";
};
enableTls = mkEnableOption "Whether to use TLS or not";
enableRegistration = mkEnableOption "Enables or disables the registration of new admin users.";
passwordReset = mkEnableOption "Enables or disables password reset.";
locale = mkOption {
type = types.str;
description = "The systems default locale.";
};
timezone = mkOption {
type = types.str;
description = "The systems default timezone as a pytz name.";
};
secretsFile = mkOption {
type = types.path;
description = "Path to the sops secrets file which stores pretix.cfg settings.";
};
};
config = lib.mkIf cfg.enable {
sops.secrets.pretix-cfg = {
sopsFile = cfg.secretsFile;
};
users.users."${user}" = {
createHome = true;
description = "Pretix user";
home = "/var/pretix";
isNormalUser = false;
isSystemUser = true;
group = group;
};
users.groups."${group}" = { };
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."${cfg.domain}" = {
enableACME = cfg.enableTls;
forceSSL = cfg.enableTls;
kTLS = cfg.enableTls;
locations."/" = {
proxyPass = "http://${bind.host}:${toString bind.port}";
};
extraConfig = ''
${hstsHeader}
'';
};
};
services.postgresql = {
enable = true;
enableTCPIP = true;
authentication = pkgs.lib.mkOverride 10 ''
local all all trust
host all all ::1/128 trust
'';
initialScript = pkgs.writeText "backend-initScript" ''
CREATE ROLE ${postgresql.user} WITH LOGIN PASSWORD '${postgresql.password}' CREATEDB;
CREATE DATABASE ${postgresql.database};
GRANT ALL PRIVILEGES ON DATABASE ${postgresql.database} TO ${postgresql.user};
'';
};
services.redis.servers.pretix = {
enable = true;
port = redisPort;
databases = 3;
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
environment.etc."pretix/pretix.cfg".source = config.sops.secrets.pretix-cfg.path;
systemd.services.pretix-migrate = {
description = "Pretix DB Migrations";
serviceConfig = {
Type = "oneshot";
EnvironmentFile = environmentFile;
User = user;
};
script = "${pkgs.pretix}/bin/pretix migrate";
};
systemd.services.pretix-web = {
description = "Pretix Web Service";
serviceConfig = {
Type = "simple";
Restart = "on-failure";
EnvironmentFile = environmentFile;
User = user;
ExecStart = pkgs.writeScript "webserver" ''
#!${pkgs.runtimeShell}
set -euo pipefail
exec ${pythonPackages.gunicorn}/bin/gunicorn pretix.wsgi --name ${name} \
--workers 3 \
--log-level=info \
--bind=${bind.host}:${toString bind.port}
'';
};
wantedBy = [ "multi-user.target" ];
requires = [ "pretix-migrate.service" ];
after = [ "network.target" ];
};
systemd.services.pretix-worker = {
description = "Pretix Celery (Worker) Service";
serviceConfig = {
Type = "simple";
Restart = "on-failure";
EnvironmentFile = environmentFile;
User = user;
ExecStart = "${pythonPackages.celery}/bin/celery -A pretix.celery_app worker -l info";
};
wantedBy = [ "multi-user.target" ];
requires = [ "pretix-migrate.service" ];
after = [ "network.target" ];
};
systemd.services.pretix-runperiodic = {
description = "Pretix periodic tasks";
serviceConfig = {
Type = "oneshot";
EnvironmentFile = environmentFile;
User = user;
};
script = "${pkgs.pretix}/bin/pretix runperiodic";
};
# Once every 5 minutes
systemd.timers.pretix-runperiodic = mkTimer {
description = "Run pretix tasks";
unit = "pretix-runperiodic.service";
onCalendar = "*:0/5";
};
};
}