Personal-use NixOS configuration
1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 cfg = config.services.omnipoly;
10
11 pkgs-internal = import ../packages { inherit pkgs; };
12
13 inherit (lib)
14 types
15 mkIf
16 mkOption
17 mkEnableOption
18 ;
19in
20{
21 options.services.omnipoly = {
22 enable = mkEnableOption "omnipoly";
23
24 package = mkOption {
25 type = types.package;
26 default = pkgs-internal.omnipoly;
27
28 description = "The OmniPoly package to use.";
29 };
30
31 environment = mkOption {
32 type = types.attrsOf types.str;
33 default = { };
34 example = lib.literalExpression ''
35 {
36 LIBRETRANSLATE_LANGUAGES = [ "pl" "en" ]; todo
37 LANGUAGE_TOOL_LANGUAGES = [ "pl-PL" "en-GB" ]; todo
38 }
39 '';
40 description = ''
41 Environment variables to set for the service. Secrets should be
42 specified using {option}`environmentFile`.
43
44 Refer to the [OmniPoly documentation] for the list of available
45 configuration options.
46
47 [OmniPoly documentation]: https://github.com/kWeglinski/OmniPoly/blob/d8fd6efec60fbc8703e2c60cffcc4fc452c76d36/.env.sample
48 '';
49 };
50
51 environmentFile = mkOption {
52 type = types.nullOr types.path;
53 default = null;
54 description = ''
55 File to load environment variables from. Loaded variables override
56 values set in {option}`environment`.
57 '';
58 };
59
60 port = mkOption {
61 type = types.int;
62 default = 5000;
63
64 description = "Port to bind webserver.";
65
66 example = 5000;
67 };
68
69 openFirewall = mkEnableOption "" // {
70 description = "Whether to open the firewall for the port in {option}`services.omnipoly.port`.";
71 };
72 };
73
74 config = mkIf cfg.enable {
75 networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [
76 cfg.port
77 ];
78
79 systemd.services.omnipoly = {
80 description = "OmniPoly frontend for LanguageTool and LibreTranslate";
81
82 wantedBy = [ "multi-user.target" ];
83 after = [
84 "network.target"
85 ]
86 ++ lib.optional config.services.languagetool.enable "languagetool.service"
87 ++ lib.optional config.services.libretranslate.enable "libretranslate.service";
88
89 environment = lib.mkMerge [
90 cfg.environment
91 {
92 PORT = toString cfg.port;
93 }
94 (mkIf config.services.languagetool.enable {
95 LANGUAGE_TOOL = "http://127.0.0.1:${toString config.services.languagetool.port}";
96 })
97 (mkIf config.services.libretranslate.enable {
98 LIBRETRANSLATE = "http://127.0.0.1:${toString config.services.libretranslate.port}";
99 })
100 ];
101
102 serviceConfig = {
103 DynamicUser = true;
104 StateDirectory = "omnipoly";
105 StateDirectoryMode = "0700";
106 UMask = "0077";
107
108 EnvironmentFile = cfg.environmentFile;
109
110 ExecStart = "${pkgs.nodejs}/bin/node ${cfg.package}/share/omnipoly/index.js";
111
112 AmbientCapabilities = "";
113 CapabilityBoundingSet = [ "" ];
114 DevicePolicy = "closed";
115 LockPersonality = true;
116 NoNewPrivileges = true;
117 PrivateDevices = true;
118 PrivateTmp = true;
119 PrivateUsers = true;
120 ProcSubset = "pid";
121 ProtectClock = true;
122 ProtectControlGroups = true;
123 ProtectHome = true;
124 ProtectHostname = true;
125 ProtectKernelLogs = true;
126 ProtectKernelModules = true;
127 ProtectKernelTunables = true;
128 ProtectProc = "invisible";
129 ProtectSystem = "strict";
130 RemoveIPC = true;
131 RestrictAddressFamilies = [
132 "AF_INET AF_INET6"
133 "AF_UNIX"
134 ];
135 RestrictNamespaces = true;
136 RestrictRealtime = true;
137 RestrictSUIDSGID = true;
138 SocketBindAllow = "tcp:${toString cfg.port}";
139 SocketBindDeny = "any";
140 SystemCallArchitectures = "native";
141 SystemCallFilter = [
142 "@system-service"
143 "~@privileged"
144 "~@resources"
145 ];
146 };
147 };
148 };
149}