frab module: init

+225
+1
nixos/modules/module-list.nix
··· 521 521 ./services/web-apps/atlassian/confluence.nix 522 522 ./services/web-apps/atlassian/crowd.nix 523 523 ./services/web-apps/atlassian/jira.nix 524 + ./services/web-apps/frab.nix 524 525 ./services/web-apps/mattermost.nix 525 526 ./services/web-apps/nixbot.nix 526 527 ./services/web-apps/pump.io.nix
+224
nixos/modules/services/web-apps/frab.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + let 6 + cfg = config.services.frab; 7 + 8 + package = pkgs.frab; 9 + ruby = package.ruby; 10 + 11 + databaseConfig = builtins.toJSON { production = cfg.database; }; 12 + 13 + frabEnv = { 14 + RAILS_ENV = "production"; 15 + RACK_ENV = "production"; 16 + SECRET_KEY_BASE = cfg.secretKeyBase; 17 + FRAB_HOST = cfg.host; 18 + FRAB_PROTOCOL = cfg.protocol; 19 + FROM_EMAIL = cfg.fromEmail; 20 + RAILS_SERVE_STATIC_FILES = "1"; 21 + } // cfg.extraEnvironment; 22 + 23 + frab-rake = pkgs.stdenv.mkDerivation rec { 24 + name = "frab-rake"; 25 + buildInputs = [ package.env pkgs.makeWrapper ]; 26 + phases = "installPhase fixupPhase"; 27 + installPhase = '' 28 + mkdir -p $out/bin 29 + makeWrapper ${package.env}/bin/bundle $out/bin/frab-bundle \ 30 + ${concatStrings (mapAttrsToList (name: value: "--set ${name} '${value}' ") frabEnv)} \ 31 + --set PATH '${lib.makeBinPath (with pkgs; [ nodejs file imagemagick ])}:$PATH' \ 32 + --set RAKEOPT '-f ${package}/share/frab/Rakefile' \ 33 + --run 'cd ${package}/share/frab' 34 + makeWrapper $out/bin/frab-bundle $out/bin/frab-rake \ 35 + --add-flags "exec rake" 36 + ''; 37 + }; 38 + 39 + in 40 + 41 + { 42 + options = { 43 + services.frab = { 44 + enable = mkOption { 45 + type = types.bool; 46 + default = false; 47 + description = '' 48 + Enable the frab service. 49 + ''; 50 + }; 51 + 52 + host = mkOption { 53 + type = types.str; 54 + example = "frab.example.com"; 55 + description = '' 56 + Hostname under which this frab instance can be reached. 57 + ''; 58 + }; 59 + 60 + protocol = mkOption { 61 + type = types.str; 62 + default = "https"; 63 + example = "http"; 64 + description = '' 65 + Either http or https, depending on how your Frab instance 66 + will be exposed to the public. 67 + ''; 68 + }; 69 + 70 + fromEmail = mkOption { 71 + type = types.str; 72 + default = "frab@localhost"; 73 + description = '' 74 + Email address used by frab. 75 + ''; 76 + }; 77 + 78 + listenAddress = mkOption { 79 + type = types.str; 80 + default = "localhost"; 81 + description = '' 82 + Address or hostname frab should listen on. 83 + ''; 84 + }; 85 + 86 + listenPort = mkOption { 87 + type = types.int; 88 + default = 3000; 89 + description = '' 90 + Port frab should listen on. 91 + ''; 92 + }; 93 + 94 + statePath = mkOption { 95 + type = types.str; 96 + default = "/var/lib/frab"; 97 + description = '' 98 + Directory where frab keeps its state. 99 + ''; 100 + }; 101 + 102 + user = mkOption { 103 + type = types.str; 104 + default = "frab"; 105 + description = '' 106 + User to run frab. 107 + ''; 108 + }; 109 + 110 + group = mkOption { 111 + type = types.str; 112 + default = "frab"; 113 + description = '' 114 + Group to run frab. 115 + ''; 116 + }; 117 + 118 + secretKeyBase = mkOption { 119 + type = types.str; 120 + description = '' 121 + Your secret key is used for verifying the integrity of signed cookies. 122 + If you change this key, all old signed cookies will become invalid! 123 + 124 + Make sure the secret is at least 30 characters and all random, 125 + no regular words or you'll be exposed to dictionary attacks. 126 + ''; 127 + }; 128 + 129 + database = mkOption { 130 + type = types.attrs; 131 + default = { 132 + adapter = "sqlite3"; 133 + database = "/var/lib/frab/db.sqlite3"; 134 + pool = 5; 135 + timeout = 5000; 136 + }; 137 + example = { 138 + adapter = "postgresql"; 139 + database = "frab"; 140 + host = "localhost"; 141 + username = "frabuser"; 142 + password = "supersecret"; 143 + encoding = "utf8"; 144 + pool = 5; 145 + }; 146 + description = '' 147 + Rails database configuration for Frab as Nix attribute set. 148 + ''; 149 + }; 150 + 151 + extraEnvironment = mkOption { 152 + type = types.attrs; 153 + default = {}; 154 + example = { 155 + FRAB_CURRENCY_UNIT = "€"; 156 + FRAB_CURRENCY_FORMAT = "%n%u"; 157 + EXCEPTION_EMAIL = "frab-owner@example.com"; 158 + SMTP_ADDRESS = "localhost"; 159 + SMTP_PORT = "587"; 160 + SMTP_DOMAIN = "localdomain"; 161 + SMTP_USER_NAME = "root"; 162 + SMTP_PASSWORD = "toor"; 163 + SMTP_AUTHENTICATION = "1"; 164 + SMTP_NOTLS = "1"; 165 + }; 166 + description = '' 167 + Additional environment variables to set for frab for further 168 + configuration. See the frab documentation for more information. 169 + ''; 170 + }; 171 + }; 172 + }; 173 + 174 + config = mkIf cfg.enable { 175 + environment.systemPackages = [ frab-rake ]; 176 + 177 + users.extraUsers = [ 178 + { name = cfg.user; 179 + group = cfg.group; 180 + home = "${cfg.statePath}"; 181 + } 182 + ]; 183 + 184 + users.extraGroups = [ { name = cfg.group; } ]; 185 + 186 + systemd.services.frab = { 187 + after = [ "network.target" "gitlab.service" ]; 188 + wantedBy = [ "multi-user.target" ]; 189 + environment = frabEnv; 190 + 191 + preStart = '' 192 + mkdir -p ${cfg.statePath}/system/attachments 193 + chown ${cfg.user}:${cfg.group} -R ${cfg.statePath} 194 + 195 + mkdir /run/frab -p 196 + ln -sf ${pkgs.writeText "frab-database.yml" databaseConfig} /run/frab/database.yml 197 + ln -sf ${cfg.statePath}/system /run/frab/system 198 + 199 + if ! test -e "${cfg.statePath}/db-setup-done"; then 200 + ${frab-rake}/bin/frab-rake db:setup 201 + touch ${cfg.statePath}/db-setup-done 202 + else 203 + ${frab-rake}/bin/frab-rake db:migrate 204 + fi 205 + ''; 206 + 207 + serviceConfig = { 208 + PermissionsStartOnly = true; 209 + PrivateTmp = true; 210 + PrivateDevices = true; 211 + Type = "simple"; 212 + User = cfg.user; 213 + Group = cfg.group; 214 + TimeoutSec = "300s"; 215 + Restart = "on-failure"; 216 + RestartSec = "10s"; 217 + WorkingDirectory = "${package}/share/frab"; 218 + ExecStart = "${frab-rake}/bin/frab-bundle exec rails server " + 219 + "--binding=${cfg.listenAddress} --port=${toString cfg.listenPort}"; 220 + }; 221 + }; 222 + 223 + }; 224 + }