diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/databases/redis.nix')
-rw-r--r-- | nixpkgs/nixos/modules/services/databases/redis.nix | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/databases/redis.nix b/nixpkgs/nixos/modules/services/databases/redis.nix new file mode 100644 index 000000000000..c04cc1283b2e --- /dev/null +++ b/nixpkgs/nixos/modules/services/databases/redis.nix @@ -0,0 +1,255 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.redis; + redisBool = b: if b then "yes" else "no"; + condOption = name: value: if value != null then "${name} ${toString value}" else ""; + + redisConfig = pkgs.writeText "redis.conf" '' + pidfile ${cfg.pidFile} + port ${toString cfg.port} + ${condOption "bind" cfg.bind} + ${condOption "unixsocket" cfg.unixSocket} + loglevel ${cfg.logLevel} + logfile ${cfg.logfile} + syslog-enabled ${redisBool cfg.syslog} + databases ${toString cfg.databases} + ${concatMapStrings (d: "save ${toString (builtins.elemAt d 0)} ${toString (builtins.elemAt d 1)}\n") cfg.save} + dbfilename ${cfg.dbFilename} + dir ${toString cfg.dbpath} + ${if cfg.slaveOf != null then "slaveof ${cfg.slaveOf.ip} ${toString cfg.slaveOf.port}" else ""} + ${condOption "masterauth" cfg.masterAuth} + ${condOption "requirepass" cfg.requirePass} + appendOnly ${redisBool cfg.appendOnly} + appendfsync ${cfg.appendFsync} + slowlog-log-slower-than ${toString cfg.slowLogLogSlowerThan} + slowlog-max-len ${toString cfg.slowLogMaxLen} + ${cfg.extraConfig} + ''; +in +{ + + ###### interface + + options = { + + services.redis = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable the Redis server."; + }; + + package = mkOption { + type = types.package; + default = pkgs.redis; + defaultText = "pkgs.redis"; + description = "Which Redis derivation to use."; + }; + + user = mkOption { + type = types.str; + default = "redis"; + description = "User account under which Redis runs."; + }; + + pidFile = mkOption { + type = types.path; + default = "/var/lib/redis/redis.pid"; + description = ""; + }; + + port = mkOption { + type = types.int; + default = 6379; + description = "The port for Redis to listen to."; + }; + + vmOverCommit = mkOption { + type = types.bool; + default = false; + description = '' + Set vm.overcommit_memory to 1 (Suggested for Background Saving: http://redis.io/topics/faq) + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Whether to open ports in the firewall for the server. + ''; + }; + + bind = mkOption { + type = with types; nullOr str; + default = null; # All interfaces + description = "The IP interface to bind to."; + example = "127.0.0.1"; + }; + + unixSocket = mkOption { + type = with types; nullOr path; + default = null; + description = "The path to the socket to bind to."; + example = "/run/redis.sock"; + }; + + logLevel = mkOption { + type = types.str; + default = "notice"; # debug, verbose, notice, warning + example = "debug"; + description = "Specify the server verbosity level, options: debug, verbose, notice, warning."; + }; + + logfile = mkOption { + type = types.str; + default = "/dev/null"; + description = "Specify the log file name. Also 'stdout' can be used to force Redis to log on the standard output."; + example = "/var/log/redis.log"; + }; + + syslog = mkOption { + type = types.bool; + default = true; + description = "Enable logging to the system logger."; + }; + + databases = mkOption { + type = types.int; + default = 16; + description = "Set the number of databases."; + }; + + save = mkOption { + type = with types; listOf (listOf int); + default = [ [900 1] [300 10] [60 10000] ]; + description = "The schedule in which data is persisted to disk, represented as a list of lists where the first element represent the amount of seconds and the second the number of changes."; + example = [ [900 1] [300 10] [60 10000] ]; + }; + + dbFilename = mkOption { + type = types.str; + default = "dump.rdb"; + description = "The filename where to dump the DB."; + }; + + dbpath = mkOption { + type = types.path; + default = "/var/lib/redis"; + description = "The DB will be written inside this directory, with the filename specified using the 'dbFilename' configuration."; + }; + + slaveOf = mkOption { + default = null; # { ip, port } + description = "An attribute set with two attributes: ip and port to which this redis instance acts as a slave."; + example = { ip = "192.168.1.100"; port = 6379; }; + }; + + masterAuth = mkOption { + default = null; + description = ''If the master is password protected (using the requirePass configuration) + it is possible to tell the slave to authenticate before starting the replication synchronization + process, otherwise the master will refuse the slave request. + (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE)''; + }; + + requirePass = mkOption { + type = with types; nullOr str; + default = null; + description = "Password for database (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE)"; + example = "letmein!"; + }; + + appendOnly = mkOption { + type = types.bool; + default = false; + description = "By default data is only periodically persisted to disk, enable this option to use an append-only file for improved persistence."; + }; + + appendOnlyFilename = mkOption { + type = types.str; + default = "appendonly.aof"; + description = "Filename for the append-only file (stored inside of dbpath)"; + }; + + appendFsync = mkOption { + type = types.str; + default = "everysec"; # no, always, everysec + description = "How often to fsync the append-only log, options: no, always, everysec."; + }; + + slowLogLogSlowerThan = mkOption { + type = types.int; + default = 10000; + description = "Log queries whose execution take longer than X in milliseconds."; + example = 1000; + }; + + slowLogMaxLen = mkOption { + type = types.int; + default = 128; + description = "Maximum number of items to keep in slow log."; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = "Extra configuration options for redis.conf."; + }; + }; + + }; + + + ###### implementation + + config = mkIf config.services.redis.enable { + + boot.kernel.sysctl = mkIf cfg.vmOverCommit { + "vm.overcommit_memory" = "1"; + }; + + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.port ]; + }; + + users.users.redis = + { name = cfg.user; + description = "Redis database user"; + }; + + environment.systemPackages = [ cfg.package ]; + + systemd.services.redis_init = + { description = "Redis Server Initialisation"; + + wantedBy = [ "redis.service" ]; + before = [ "redis.service" ]; + + serviceConfig.Type = "oneshot"; + + script = '' + install -d -m0700 -o ${cfg.user} ${cfg.dbpath} + chown -R ${cfg.user} ${cfg.dbpath} + ''; + }; + + systemd.services.redis = + { description = "Redis Server"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + ExecStart = "${cfg.package}/bin/redis-server ${redisConfig}"; + User = cfg.user; + }; + }; + + }; + +} |