at 24.11-pre 7.5 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.rabbitmq; 7 8 inherit (builtins) concatStringsSep; 9 10 config_file_content = lib.generators.toKeyValue { } cfg.configItems; 11 config_file = pkgs.writeText "rabbitmq.conf" config_file_content; 12 13 advanced_config_file = pkgs.writeText "advanced.config" cfg.config; 14 15in 16{ 17 18 imports = [ 19 (mkRemovedOptionModule [ "services" "rabbitmq" "cookie" ] '' 20 This option wrote the Erlang cookie to the store, while it should be kept secret. 21 Please remove it from your NixOS configuration and deploy a cookie securely instead. 22 The renamed `unsafeCookie` must ONLY be used in isolated non-production environments such as NixOS VM tests. 23 '') 24 ]; 25 26 ###### interface 27 options = { 28 services.rabbitmq = { 29 enable = mkOption { 30 type = types.bool; 31 default = false; 32 description = '' 33 Whether to enable the RabbitMQ server, an Advanced Message 34 Queuing Protocol (AMQP) broker. 35 ''; 36 }; 37 38 package = mkPackageOption pkgs "rabbitmq-server" { }; 39 40 listenAddress = mkOption { 41 default = "127.0.0.1"; 42 example = ""; 43 description = '' 44 IP address on which RabbitMQ will listen for AMQP 45 connections. Set to the empty string to listen on all 46 interfaces. Note that RabbitMQ creates a user named 47 `guest` with password 48 `guest` by default, so you should delete 49 this user if you intend to allow external access. 50 51 Together with 'port' setting it's mostly an alias for 52 configItems."listeners.tcp.1" and it's left for backwards 53 compatibility with previous version of this module. 54 ''; 55 type = types.str; 56 }; 57 58 port = mkOption { 59 default = 5672; 60 description = '' 61 Port on which RabbitMQ will listen for AMQP connections. 62 ''; 63 type = types.port; 64 }; 65 66 dataDir = mkOption { 67 type = types.path; 68 default = "/var/lib/rabbitmq"; 69 description = '' 70 Data directory for rabbitmq. 71 ''; 72 }; 73 74 unsafeCookie = mkOption { 75 default = ""; 76 type = types.str; 77 description = '' 78 Erlang cookie is a string of arbitrary length which must 79 be the same for several nodes to be allowed to communicate. 80 Leave empty to generate automatically. 81 82 Setting the cookie via this option exposes the cookie to the store, which 83 is not recommended for security reasons. 84 Only use this option in an isolated non-production environment such as 85 NixOS VM tests. 86 ''; 87 }; 88 89 configItems = mkOption { 90 default = { }; 91 type = types.attrsOf types.str; 92 example = literalExpression '' 93 { 94 "auth_backends.1.authn" = "rabbit_auth_backend_ldap"; 95 "auth_backends.1.authz" = "rabbit_auth_backend_internal"; 96 } 97 ''; 98 description = '' 99 Configuration options in RabbitMQ's new config file format, 100 which is a simple key-value format that can not express nested 101 data structures. This is known as the `rabbitmq.conf` file, 102 although outside NixOS that filename may have Erlang syntax, particularly 103 prior to RabbitMQ 3.7.0. 104 105 If you do need to express nested data structures, you can use 106 `config` option. Configuration from `config` 107 will be merged into these options by RabbitMQ at runtime to 108 form the final configuration. 109 110 See https://www.rabbitmq.com/configure.html#config-items 111 For the distinct formats, see https://www.rabbitmq.com/configure.html#config-file-formats 112 ''; 113 }; 114 115 config = mkOption { 116 default = ""; 117 type = types.str; 118 description = '' 119 Verbatim advanced configuration file contents using the Erlang syntax. 120 This is also known as the `advanced.config` file or the old config format. 121 122 `configItems` is preferred whenever possible. However, nested 123 data structures can only be expressed properly using the `config` option. 124 125 The contents of this option will be merged into the `configItems` 126 by RabbitMQ at runtime to form the final configuration. 127 128 See the second table on https://www.rabbitmq.com/configure.html#config-items 129 For the distinct formats, see https://www.rabbitmq.com/configure.html#config-file-formats 130 ''; 131 }; 132 133 plugins = mkOption { 134 default = [ ]; 135 type = types.listOf types.str; 136 description = "The names of plugins to enable"; 137 }; 138 139 pluginDirs = mkOption { 140 default = [ ]; 141 type = types.listOf types.path; 142 description = "The list of directories containing external plugins"; 143 }; 144 145 managementPlugin = { 146 enable = mkEnableOption "the management plugin"; 147 port = mkOption { 148 default = 15672; 149 type = types.port; 150 description = '' 151 On which port to run the management plugin 152 ''; 153 }; 154 }; 155 }; 156 }; 157 158 159 ###### implementation 160 config = mkIf cfg.enable { 161 162 # This is needed so we will have 'rabbitmqctl' in our PATH 163 environment.systemPackages = [ cfg.package ]; 164 165 services.epmd.enable = true; 166 167 users.users.rabbitmq = { 168 description = "RabbitMQ server user"; 169 home = "${cfg.dataDir}"; 170 createHome = true; 171 group = "rabbitmq"; 172 uid = config.ids.uids.rabbitmq; 173 }; 174 175 users.groups.rabbitmq.gid = config.ids.gids.rabbitmq; 176 177 services.rabbitmq.configItems = { 178 "listeners.tcp.1" = mkDefault "${cfg.listenAddress}:${toString cfg.port}"; 179 } // optionalAttrs cfg.managementPlugin.enable { 180 "management.tcp.port" = toString cfg.managementPlugin.port; 181 "management.tcp.ip" = cfg.listenAddress; 182 }; 183 184 services.rabbitmq.plugins = optional cfg.managementPlugin.enable "rabbitmq_management"; 185 186 systemd.services.rabbitmq = { 187 description = "RabbitMQ Server"; 188 189 wantedBy = [ "multi-user.target" ]; 190 after = [ "network.target" "epmd.socket" ]; 191 wants = [ "network.target" "epmd.socket" ]; 192 193 path = [ 194 cfg.package 195 pkgs.coreutils # mkdir/chown/chmod for preStart 196 ]; 197 198 environment = { 199 RABBITMQ_MNESIA_BASE = "${cfg.dataDir}/mnesia"; 200 RABBITMQ_LOGS = "-"; 201 SYS_PREFIX = ""; 202 RABBITMQ_CONFIG_FILE = config_file; 203 RABBITMQ_PLUGINS_DIR = concatStringsSep ":" cfg.pluginDirs; 204 RABBITMQ_ENABLED_PLUGINS_FILE = pkgs.writeText "enabled_plugins" '' 205 [ ${concatStringsSep "," cfg.plugins} ]. 206 ''; 207 } // optionalAttrs (cfg.config != "") { RABBITMQ_ADVANCED_CONFIG_FILE = advanced_config_file; }; 208 209 serviceConfig = { 210 ExecStart = "${cfg.package}/sbin/rabbitmq-server"; 211 ExecStop = "${cfg.package}/sbin/rabbitmqctl shutdown"; 212 User = "rabbitmq"; 213 Group = "rabbitmq"; 214 LogsDirectory = "rabbitmq"; 215 WorkingDirectory = cfg.dataDir; 216 Type = "notify"; 217 NotifyAccess = "all"; 218 UMask = "0027"; 219 LimitNOFILE = "100000"; 220 Restart = "on-failure"; 221 RestartSec = "10"; 222 TimeoutStartSec = "3600"; 223 }; 224 225 preStart = '' 226 ${optionalString (cfg.unsafeCookie != "") '' 227 install -m 600 <(echo -n ${cfg.unsafeCookie}) ${cfg.dataDir}/.erlang.cookie 228 ''} 229 ''; 230 }; 231 232 }; 233 234}