{ config, pkgs, ... }: let svc_domain = "wger.${config.mine.shared.settings.domain}"; port = 8000; wger_user = "wger"; statedir = config.mine.zfsMounts."rpool/safe/svcs/wger"; wgerpkgs = pkgs.callPackage ./wgerpkg/default.nix {}; wger_settings = { EMAIL_FROM = "wger Workout Manager "; ALLOW_REGISTRATION = true; ALLOW_GUEST_USERS = true; ALLOW_UPLOAD_VIDEOS = false; MIN_ACCOUNT_AGE_TO_TRUST = 21; EXERCISE_CACHE_TTL = 3600; }; django_settings = rec { # enable debug for now, otherwise it tries # to create a CACHE folder/file in the CWD. # and if I fix that, then static content no # longer wants to load. DEBUG = true; DATABASES.default = { ENGINE = "django.db.backends.postgresql"; NAME = "wger"; USER = "wger"; PASSWORD = ""; HOST = "/run/postgresql"; PORT = ""; }; ADMINS = [["admin" "admin@${config.mine.shared.settings.domain}"]]; MANAGERS = ADMINS; TIME_ZONE = "Europe/Copenhagen"; SECRET_KEY = "$SECRET_KEY"; SITE_URL = "https://${svc_domain}"; MEDIA_ROOT = "${statedir}/media"; MEDIA_URL = "/media/"; # EMAIL EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"; EMAIL_HOST = config.mine.shared.settings.mail.domain_smtp; EMAIL_PORT = config.mine.shared.settings.mail.ports.submissions; EMAIL_USE_SSL = true; EMAIL_HOST_USER = "wger"; EMAIL_HOST_PASSWORD = "$EMAIL_HOST_PASSWORD"; EMAIL_FROM_ADDRESS = wger_settings.EMAIL_FROM; EMAIL_PAGE_DOMAIN = SITE_URL; # setup allowed hosts CSRF_TRUSTED_ORIGINS = [ "https://${svc_domain}" ]; ALLOWED_HOSTS = [ svc_domain ]; # disable recaptcha RECAPTCHA_PUBLIC_KEY = ""; RECAPTCHA_PRIVATE_KEY = ""; USE_RECAPTCHA = false; }; wger_settings_file = pkgs.writeText "settings.json" (builtins.toJSON wger_settings); django_settings_file = pkgs.writeText "settings.json" (builtins.toJSON django_settings); settingsFile = pkgs.writeText "settings.py" '' from wger.settings_global import * import json import os with open("${django_settings_file}") as f: for k, v in json.load(f).items(): if isinstance(v, str) and v.startswith("$"): v = os.environ[v[1:]] globals()[k] = v with open("${wger_settings_file}") as f: for k, v in json.load(f).items(): if isinstance(v, str) and v.startswith("$"): v = os.environ[v[1:]] WGER_SETTINGS[k] = v ''; in { # main service systemd.services.wger = { description = "wger fitness"; wantedBy = [ "multi-user.target" ]; after = [ "networking.target" ]; script = '' # initial setup ${wgerpkgs}/bin/wger migrate-db -s ${settingsFile} || true ${wgerpkgs}/bin/wger load-fixtures -s ${settingsFile} || true # run server ${wgerpkgs}/bin/wger start -s ${settingsFile} ''; serviceConfig = { EnvironmentFile = config.age.secrets.wger-env.path; # ensure it does not try to create `/CACHE` PrivateTmp = "yes"; WorkingDirectory = "/tmp"; User = "wger"; Group = "wger"; }; }; # periodic keep up-to-date systemd.timers."wger-housekeeping" = { wantedBy = [ "timers.target" ]; timerConfig.OnCalendar = "daily"; }; systemd.services."wger-housekeeping" = { after = [ "wger.service" ]; requires = [ "wger.service" ]; script = '' WGER_SETTINGS=${settingsFile} ${wgerpkgs}/bin/manage sync-exercises || true WGER_SETTINGS=${settingsFile} ${wgerpkgs}/bin/manage download-exercise-images || true WGER_SETTINGS=${settingsFile} ${wgerpkgs}/bin/manage download-exercise-videos || true # WGER_SETTINGS=${settingsFile} ${wgerpkgs}/bin/manage sync-ingredients || true ${wgerpkgs}/bin/wger load-online-fixtures -s ${settingsFile} || true WGER_SETTINGS=${settingsFile} ${wgerpkgs}/bin/manage exercises-health-check || true ''; serviceConfig = { EnvironmentFile = config.age.secrets.wger-env.path; # Type = "oneshot"; User = "wger"; Group = "wger"; }; }; services.postgresql = { ensureDatabases = [ wger_user ]; ensureUsers = [{ name = wger_user; ensureDBOwnership = true; }]; }; # setup users users.users."${wger_user}"= { uid = 738; isSystemUser = true; group = wger_user; }; users.groups."${wger_user}".gid = 738; # nginx services.nginx.virtualHosts."${svc_domain}" = config.mine.shared.lib.authelia.mkProtectedWebsite { forceSSL = true; enableACME = true; locations."/" = config.mine.shared.lib.authelia.mkProtectedLocation { proxyPass = "http://localhost:${builtins.toString port}"; }; locations."/api/v2/register" = config.mine.shared.lib.authelia.mkProtectedLocation { proxyPass = "http://localhost:${builtins.toString port}"; }; locations."/static".proxyPass = "http://localhost:${builtins.toString port}"; locations."/media".proxyPass = "http://localhost:${builtins.toString port}"; locations."/api".proxyPass = "http://localhost:${builtins.toString port}"; }; # metadata mine.shared.meta.wger = { name = "Wger"; description = "We host Wger, which is a FLOSS fitness/workout/nutrition and weight tracker, with FLOSS apps, read more [here](https://wger.de/)."; url = "https://${svc_domain}"; package = let pkg = wgerpkgs; in { name = pkg.pname; version = pkg.version; meta = pkg.meta; }; }; }