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