1 { config, lib, pkgs, ... }:
3 gunicorn = pkgs.python3Packages.gunicorn;
4 bepasty = pkgs.bepasty;
5 gevent = pkgs.python3Packages.gevent;
6 python = pkgs.python3Packages.python;
7 cfg = config.services.bepasty;
10 default_home = "/var/lib/bepasty";
13 options.services.bepasty = {
14 enable = lib.mkEnableOption "bepasty, a binary pastebin server";
16 servers = lib.mkOption {
19 configure a number of bepasty servers which will be started with
22 type = with lib.types ; attrsOf (submodule ({ config, ... } : {
29 Bind address to be used for this server.
31 example = "0.0.0.0:8000";
32 default = "127.0.0.1:8000";
35 dataDir = lib.mkOption {
38 Path to the directory where the pastes will be saved to
40 default = default_home+"/data";
43 defaultPermissions = lib.mkOption {
46 default permissions for all unauthenticated accesses.
48 example = "read,create,delete";
52 extraConfig = lib.mkOption {
53 type = lib.types.lines;
55 Extra configuration for bepasty server to be appended on the
57 see https://bepasty-server.readthedocs.org/en/latest/quickstart.html#configuring-bepasty
63 'myadminsecret': 'admin,list,create,read,delete',
65 MAX_ALLOWED_FILE_SIZE = 5 * 1000 * 1000
69 secretKey = lib.mkOption {
72 server secret for safe session cookies, must be set.
74 Warning: this secret is stored in the WORLD-READABLE Nix store!
76 It's recommended to use {option}`secretKeyFile`
77 which takes precedence over {option}`secretKey`.
82 secretKeyFile = lib.mkOption {
83 type = lib.types.nullOr lib.types.str;
86 A file that contains the server secret for safe session cookies, must be set.
88 {option}`secretKeyFile` takes precedence over {option}`secretKey`.
90 Warning: when {option}`secretKey` is non-empty {option}`secretKeyFile`
91 defaults to a file in the WORLD-READABLE Nix store containing that secret.
95 workDir = lib.mkOption {
98 Path to the working directory (used for config and pidfile).
99 Defaults to the users home directory.
101 default = default_home;
106 secretKeyFile = lib.mkDefault (
107 if config.secretKey != ""
108 then toString (pkgs.writeTextFile {
109 name = "bepasty-secret-key";
110 text = config.secretKey;
119 config = lib.mkIf cfg.enable {
121 environment.systemPackages = [ bepasty ];
123 # creates gunicorn systemd service for each configured server
124 systemd.services = lib.mapAttrs' (name: server:
125 lib.nameValuePair ("bepasty-server-${name}-gunicorn")
127 description = "Bepasty Server ${name}";
128 wantedBy = [ "multi-user.target" ];
129 after = [ "network.target" ];
130 restartIfChanged = true;
133 penv = python.buildEnv.override {
134 extraLibs = [ bepasty gevent ];
137 BEPASTY_CONFIG = "${server.workDir}/bepasty-${name}.conf";
138 PYTHONPATH= "${penv}/${python.sitePackages}/";
144 ExecStartPre = assert server.secretKeyFile != null; pkgs.writeScript "bepasty-server.${name}-init" ''
146 mkdir -p "${server.workDir}"
147 mkdir -p "${server.dataDir}"
148 chown ${user}:${group} "${server.workDir}" "${server.dataDir}"
149 cat > ${server.workDir}/bepasty-${name}.conf <<EOF
151 STORAGE_FILESYSTEM_DIRECTORY="${server.dataDir}"
152 SECRET_KEY="$(cat "${server.secretKeyFile}")"
153 DEFAULT_PERMISSIONS="${server.defaultPermissions}"
154 ${server.extraConfig}
157 ExecStart = ''${gunicorn}/bin/gunicorn bepasty.wsgi --name ${name} \
160 --workers 3 --log-level=info \
161 --bind=${server.bind} \
162 --pid ${server.workDir}/gunicorn-${name}.pid \
169 users.users.${user} =
170 { uid = config.ids.uids.bepasty;
175 users.groups.${group}.gid = config.ids.gids.bepasty;