Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/traefik create service #29865

Merged
merged 2 commits into from
Oct 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@
./services/web-servers/phpfpm/default.nix
./services/web-servers/shellinabox.nix
./services/web-servers/tomcat.nix
./services/web-servers/traefik.nix
./services/web-servers/uwsgi.nix
./services/web-servers/varnish/default.nix
./services/web-servers/winstone.nix
Expand Down
114 changes: 114 additions & 0 deletions nixos/modules/services/web-servers/traefik.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{ config, lib, pkgs, ... }:

with lib;

let
cfg = config.services.traefik;
configFile =
if cfg.configFile == null then
pkgs.runCommand "config.toml" {
buildInputs = [ pkgs.remarshal ];
} ''
remarshal -if json -of toml \
< ${pkgs.writeText "config.json" (builtins.toJSON cfg.configOptions)} \
> $out
''
else cfg.configFile;

in {
options.services.traefik = {
enable = mkEnableOption "Traefik web server";

configFile = mkOption {
Copy link
Member

@Mic92 Mic92 Oct 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is your use case for this option?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had forgotten to update the example to accurately portray the expected type: https://github.com/NixOS/nixpkgs/pull/29865/files#diff-beb91534bbf628b6e0727a0bb7d14c4aR25

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean in which case it is necessary to specify a toml path directly rather then using the configOptions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to have it if I am doing an incremental change over to nixos from my current orchestration system for configuration files.

The other issue is secrets, which one may want to store in a separate store. This can be worked around for sure, but this gives people an alternative, less invasive route to initially integrating Traefik.

Are there any specific reasons why you think we shouldn't have this option?
Reasons that come to mind:

  • complexity
  • against the ethos of NixOs
  • allowing bad habits & configuration drift

For:

  • already complex setups with templates & config-file generation.
  • lower barrier for entry to users wanting to keep using traefik as-is with minimal overhead.

These issues aren't unsolvable, in fact nix is very good at solving them.
I'm happy to remove it if you think it won't find any use.

Copy link
Member

@Mic92 Mic92 Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just want keep the API we expose simple as we have to deal every option stable in future to not break configuration. But secrets is a good point for storing the configuration outside of nix store: https://docs.traefik.io/configuration/backends/web/#basic-authentication

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think then? We can keep it in pending #8 and deprecate it when secrets are properly managed within Nix

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, #24288. Wrong link

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can stay then, I would say.

default = null;
example = /path/to/config.toml;
type = types.nullOr types.path;
description = ''
Path to verbatim traefik.toml to use.
(Using that option has precedence over <literal>configOptions</literal>)
'';
};

configOptions = mkOption {
description = ''
Config for Traefik.
'';
type = types.attrs;
default = {
defaultEntryPoints = ["http"];
entryPoints.http.address = ":80";
};
example = {
defaultEntrypoints = [ "http" ];
web.address = ":8080";
entryPoints.http.address = ":80";

file = {};
frontends = {
frontend1 = {
backend = "backend1";
routes.test_1.rule = "Host:localhost";
};
};
backends.backend1 = {
servers.server1.url = "http://localhost:8000";
};
};
};

dataDir = mkOption {
default = "/var/lib/traefik";
type = types.path;
description = ''
Location for any persistent data traefik creates, ie. acme
'';
};

package = mkOption {
default = pkgs.traefik;
defaultText = "pkgs.traefik";
type = types.package;
description = "Traefik package to use.";
};
};

config = mkIf cfg.enable {
systemd.services.traefik = {
description = "Traefik web server";
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
PermissionsStartOnly = true;
ExecStart = ''${cfg.package.bin}/bin/traefik --configfile=${configFile}'';
ExecStartPre = [
''${pkgs.coreutils}/bin/mkdir -p "${cfg.dataDir}"''
''${pkgs.coreutils}/bin/install -d -m700 --owner traefik --group traefik "${cfg.dataDir}"''
];
Type = "simple";
User = "traefik";
Group = "traefik";
Restart = "on-failure";
StartLimitInterval = 86400;
StartLimitBurst = 5;
AmbientCapabilities = "cap_net_bind_service";
CapabilityBoundingSet = "cap_net_bind_service";
NoNewPrivileges = true;
LimitNPROC = 64;
LimitNOFILE = 1048576;
PrivateTmp = true;
PrivateDevices = true;
ProtectHome = true;
ProtectSystem = "full";
ReadWriteDirectories = cfg.dataDir;
};
};

users.extraUsers.traefik = {
group = "traefik";
home = cfg.dataDir;
createHome = true;
};

users.extraGroups.traefik = {};
};
}