at 25.11-pre 4.5 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10let 11 cfg = config.services.traefik; 12 13 format = pkgs.formats.toml { }; 14 15 dynamicConfigFile = 16 if cfg.dynamicConfigFile == null then 17 format.generate "config.toml" cfg.dynamicConfigOptions 18 else 19 cfg.dynamicConfigFile; 20 21 staticConfigFile = 22 if cfg.staticConfigFile == null then 23 format.generate "config.toml" ( 24 recursiveUpdate cfg.staticConfigOptions { 25 providers.file.filename = "${dynamicConfigFile}"; 26 } 27 ) 28 else 29 cfg.staticConfigFile; 30 31 finalStaticConfigFile = 32 if cfg.environmentFiles == [ ] then staticConfigFile else "/run/traefik/config.toml"; 33in 34{ 35 options.services.traefik = { 36 enable = mkEnableOption "Traefik web server"; 37 38 staticConfigFile = mkOption { 39 default = null; 40 example = literalExpression "/path/to/static_config.toml"; 41 type = types.nullOr types.path; 42 description = '' 43 Path to traefik's static configuration to use. 44 (Using that option has precedence over `staticConfigOptions` and `dynamicConfigOptions`) 45 ''; 46 }; 47 48 staticConfigOptions = mkOption { 49 description = '' 50 Static configuration for Traefik. 51 ''; 52 type = format.type; 53 default = { 54 entryPoints.http.address = ":80"; 55 }; 56 example = { 57 entryPoints.web.address = ":8080"; 58 entryPoints.http.address = ":80"; 59 60 api = { }; 61 }; 62 }; 63 64 dynamicConfigFile = mkOption { 65 default = null; 66 example = literalExpression "/path/to/dynamic_config.toml"; 67 type = types.nullOr types.path; 68 description = '' 69 Path to traefik's dynamic configuration to use. 70 (Using that option has precedence over `dynamicConfigOptions`) 71 ''; 72 }; 73 74 dynamicConfigOptions = mkOption { 75 description = '' 76 Dynamic configuration for Traefik. 77 ''; 78 type = format.type; 79 default = { }; 80 example = { 81 http.routers.router1 = { 82 rule = "Host(`localhost`)"; 83 service = "service1"; 84 }; 85 86 http.services.service1.loadBalancer.servers = [ { url = "http://localhost:8080"; } ]; 87 }; 88 }; 89 90 dataDir = mkOption { 91 default = "/var/lib/traefik"; 92 type = types.path; 93 description = '' 94 Location for any persistent data traefik creates, ie. acme 95 ''; 96 }; 97 98 group = mkOption { 99 default = "traefik"; 100 type = types.str; 101 example = "docker"; 102 description = '' 103 Set the group that traefik runs under. 104 For the docker backend this needs to be set to `docker` instead. 105 ''; 106 }; 107 108 package = mkPackageOption pkgs "traefik" { }; 109 110 environmentFiles = mkOption { 111 default = [ ]; 112 type = types.listOf types.path; 113 example = [ "/run/secrets/traefik.env" ]; 114 description = '' 115 Files to load as environment file. Environment variables from this file 116 will be substituted into the static configuration file using envsubst. 117 ''; 118 }; 119 }; 120 121 config = mkIf cfg.enable { 122 systemd.tmpfiles.rules = [ "d '${cfg.dataDir}' 0700 traefik traefik - -" ]; 123 124 systemd.services.traefik = { 125 description = "Traefik web server"; 126 wants = [ "network-online.target" ]; 127 after = [ "network-online.target" ]; 128 wantedBy = [ "multi-user.target" ]; 129 startLimitIntervalSec = 86400; 130 startLimitBurst = 5; 131 serviceConfig = { 132 EnvironmentFile = cfg.environmentFiles; 133 ExecStartPre = lib.optional (cfg.environmentFiles != [ ]) ( 134 pkgs.writeShellScript "pre-start" '' 135 umask 077 136 ${pkgs.envsubst}/bin/envsubst -i "${staticConfigFile}" > "${finalStaticConfigFile}" 137 '' 138 ); 139 ExecStart = "${cfg.package}/bin/traefik --configfile=${finalStaticConfigFile}"; 140 Type = "simple"; 141 User = "traefik"; 142 Group = cfg.group; 143 Restart = "on-failure"; 144 AmbientCapabilities = "cap_net_bind_service"; 145 CapabilityBoundingSet = "cap_net_bind_service"; 146 NoNewPrivileges = true; 147 LimitNPROC = 64; 148 LimitNOFILE = 1048576; 149 PrivateTmp = true; 150 PrivateDevices = true; 151 ProtectHome = true; 152 ProtectSystem = "full"; 153 ReadWritePaths = [ cfg.dataDir ]; 154 RuntimeDirectory = "traefik"; 155 }; 156 }; 157 158 users.users.traefik = { 159 group = "traefik"; 160 home = cfg.dataDir; 161 createHome = true; 162 isSystemUser = true; 163 }; 164 165 users.groups.traefik = { }; 166 }; 167}