python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / web-servers / traefik.nix
blob9e5603e0edc33c45573bb3754e01045719c9071e
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.traefik;
7   jsonValue = with types;
8     let
9       valueType = nullOr (oneOf [
10         bool
11         int
12         float
13         str
14         (lazyAttrsOf valueType)
15         (listOf valueType)
16       ]) // {
17         description = "JSON value";
18         emptyValue.value = { };
19       };
20     in valueType;
21   dynamicConfigFile = if cfg.dynamicConfigFile == null then
22     pkgs.runCommand "config.toml" {
23       buildInputs = [ pkgs.remarshal ];
24       preferLocalBuild = true;
25     } ''
26       remarshal -if json -of toml \
27         < ${
28           pkgs.writeText "dynamic_config.json"
29           (builtins.toJSON cfg.dynamicConfigOptions)
30         } \
31         > $out
32     ''
33   else
34     cfg.dynamicConfigFile;
35   staticConfigFile = if cfg.staticConfigFile == null then
36     pkgs.runCommand "config.toml" {
37       buildInputs = [ pkgs.yj ];
38       preferLocalBuild = true;
39     } ''
40       yj -jt -i \
41         < ${
42           pkgs.writeText "static_config.json" (builtins.toJSON
43             (recursiveUpdate cfg.staticConfigOptions {
44               providers.file.filename = "${dynamicConfigFile}";
45             }))
46         } \
47         > $out
48     ''
49   else
50     cfg.staticConfigFile;
51 in {
52   options.services.traefik = {
53     enable = mkEnableOption (lib.mdDoc "Traefik web server");
55     staticConfigFile = mkOption {
56       default = null;
57       example = literalExpression "/path/to/static_config.toml";
58       type = types.nullOr types.path;
59       description = lib.mdDoc ''
60         Path to traefik's static configuration to use.
61         (Using that option has precedence over `staticConfigOptions` and `dynamicConfigOptions`)
62       '';
63     };
65     staticConfigOptions = mkOption {
66       description = lib.mdDoc ''
67         Static configuration for Traefik.
68       '';
69       type = jsonValue;
70       default = { entryPoints.http.address = ":80"; };
71       example = {
72         entryPoints.web.address = ":8080";
73         entryPoints.http.address = ":80";
75         api = { };
76       };
77     };
79     dynamicConfigFile = mkOption {
80       default = null;
81       example = literalExpression "/path/to/dynamic_config.toml";
82       type = types.nullOr types.path;
83       description = lib.mdDoc ''
84         Path to traefik's dynamic configuration to use.
85         (Using that option has precedence over `dynamicConfigOptions`)
86       '';
87     };
89     dynamicConfigOptions = mkOption {
90       description = lib.mdDoc ''
91         Dynamic configuration for Traefik.
92       '';
93       type = jsonValue;
94       default = { };
95       example = {
96         http.routers.router1 = {
97           rule = "Host(`localhost`)";
98           service = "service1";
99         };
101         http.services.service1.loadBalancer.servers =
102           [{ url = "http://localhost:8080"; }];
103       };
104     };
106     dataDir = mkOption {
107       default = "/var/lib/traefik";
108       type = types.path;
109       description = lib.mdDoc ''
110         Location for any persistent data traefik creates, ie. acme
111       '';
112     };
114     group = mkOption {
115       default = "traefik";
116       type = types.str;
117       example = "docker";
118       description = lib.mdDoc ''
119         Set the group that traefik runs under.
120         For the docker backend this needs to be set to `docker` instead.
121       '';
122     };
124     package = mkOption {
125       default = pkgs.traefik;
126       defaultText = literalExpression "pkgs.traefik";
127       type = types.package;
128       description = lib.mdDoc "Traefik package to use.";
129     };
130   };
132   config = mkIf cfg.enable {
133     systemd.tmpfiles.rules = [ "d '${cfg.dataDir}' 0700 traefik traefik - -" ];
135     systemd.services.traefik = {
136       description = "Traefik web server";
137       after = [ "network-online.target" ];
138       wantedBy = [ "multi-user.target" ];
139       startLimitIntervalSec = 86400;
140       startLimitBurst = 5;
141       serviceConfig = {
142         ExecStart =
143           "${cfg.package}/bin/traefik --configfile=${staticConfigFile}";
144         Type = "simple";
145         User = "traefik";
146         Group = cfg.group;
147         Restart = "on-failure";
148         AmbientCapabilities = "cap_net_bind_service";
149         CapabilityBoundingSet = "cap_net_bind_service";
150         NoNewPrivileges = true;
151         LimitNPROC = 64;
152         LimitNOFILE = 1048576;
153         PrivateTmp = true;
154         PrivateDevices = true;
155         ProtectHome = true;
156         ProtectSystem = "full";
157         ReadWriteDirectories = cfg.dataDir;
158       };
159     };
161     users.users.traefik = {
162       group = "traefik";
163       home = cfg.dataDir;
164       createHome = true;
165       isSystemUser = true;
166     };
168     users.groups.traefik = { };
169   };