1 { config, pkgs, lib, ... }:
5 cfg = config.services.tandoor-recipes;
8 # SECRET_KEY through an env file
10 GUNICORN_CMD_ARGS = "--bind=${cfg.address}:${toString cfg.port}";
12 MEDIA_ROOT = "/var/lib/tandoor-recipes";
13 } // optionalAttrs (config.time.timeZone != null) {
14 TIMEZONE = config.time.timeZone;
16 lib.mapAttrs (_: toString) cfg.extraConfig
21 setupEnv = lib.concatStringsSep "\n" (mapAttrsToList (name: val: "export ${name}=\"${val}\"") env);
23 pkgs.writeShellScript "manage" ''
25 exec ${pkg}/bin/tandoor-recipes "$@"
29 meta.maintainers = with maintainers; [ ambroisie ];
31 options.services.tandoor-recipes = {
33 type = lib.types.bool;
35 description = lib.mdDoc ''
36 Enable Tandoor Recipes.
38 When started, the Tandoor Recipes database is automatically created if
39 it doesn't exist and updated if the package has changed. Both tasks are
40 achieved by running a Django migration.
42 A script to manage the instance (by wrapping Django's manage.py) is linked to
43 `/var/lib/tandoor-recipes/tandoor-recipes-manage`.
49 default = "localhost";
50 description = lib.mdDoc "Web interface address.";
56 description = lib.mdDoc "Web interface port.";
59 extraConfig = mkOption {
62 description = lib.mdDoc ''
63 Extra tandoor recipes config options.
65 See [the example dot-env file](https://raw.githubusercontent.com/vabene1111/recipes/master/.env.template)
66 for available options.
75 default = pkgs.tandoor-recipes;
76 defaultText = literalExpression "pkgs.tandoor-recipes";
77 description = lib.mdDoc "The Tandoor Recipes package to use.";
81 config = mkIf cfg.enable {
82 systemd.services.tandoor-recipes = {
83 description = "Tandoor Recipes server";
87 ${pkg.python.pkgs.gunicorn}/bin/gunicorn recipes.wsgi
89 Restart = "on-failure";
91 User = "tandoor_recipes";
93 StateDirectory = "tandoor-recipes";
94 WorkingDirectory = "/var/lib/tandoor-recipes";
95 RuntimeDirectory = "tandoor-recipes";
98 "${config.environment.etc."ssl/certs/ca-certificates.crt".source}:/etc/ssl/certs/ca-certificates.crt"
101 "-/etc/nsswitch.conf"
106 CapabilityBoundingSet = "";
107 LockPersonality = true;
108 MemoryDenyWriteExecute = true;
109 PrivateDevices = true;
112 ProtectControlGroups = true;
114 ProtectHostname = true;
115 ProtectKernelLogs = true;
116 ProtectKernelModules = true;
117 ProtectKernelTunables = true;
118 RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
119 RestrictNamespaces = true;
120 RestrictRealtime = true;
121 SystemCallArchitectures = "native";
122 # gunicorn needs setuid
123 SystemCallFilter = [ "@system-service" "~@privileged" "@resources" "@setuid" "@keyring" ];
125 } // lib.optionalAttrs (cfg.port < 1024) {
126 AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
127 CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
130 wantedBy = [ "multi-user.target" ];
133 ln -sf ${manage} tandoor-recipes-manage
135 # Let django migrate the DB as needed
136 ${pkg}/bin/tandoor-recipes migrate
139 environment = env // {
140 PYTHONPATH = "${pkg.python.pkgs.makePythonPath pkg.propagatedBuildInputs}:${pkg}/lib/tandoor-recipes";