1{ config, pkgs, lib, ... }:
2
3with lib;
4
5let
6 cfg = config.services.dgraph;
7 settingsFormat = pkgs.formats.json {};
8 configFile = settingsFormat.generate "config.json" cfg.settings;
9 dgraphWithNode = pkgs.runCommand "dgraph" {
10 nativeBuildInputs = [ pkgs.makeWrapper ];
11 }
12 ''
13 mkdir -p $out/bin
14 makeWrapper ${cfg.package}/bin/dgraph $out/bin/dgraph \
15 --prefix PATH : "${lib.makeBinPath [ pkgs.nodejs ]}" \
16 '';
17 securityOptions = {
18 NoNewPrivileges = true;
19
20 AmbientCapabilities = "";
21 CapabilityBoundingSet = "";
22
23 DeviceAllow = "";
24
25 LockPersonality = true;
26
27 PrivateTmp = true;
28 PrivateDevices = true;
29 PrivateUsers = true;
30
31 ProtectClock = true;
32 ProtectControlGroups = true;
33 ProtectHostname = true;
34 ProtectKernelLogs = true;
35 ProtectKernelModules = true;
36 ProtectKernelTunables = true;
37
38 RemoveIPC = true;
39
40 RestrictNamespaces = true;
41 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
42 RestrictRealtime = true;
43 RestrictSUIDSGID = true;
44
45 SystemCallArchitectures = "native";
46 SystemCallErrorNumber = "EPERM";
47 SystemCallFilter = [
48 "@system-service"
49 "~@cpu-emulation" "~@debug" "~@keyring" "~@memlock" "~@obsolete" "~@privileged" "~@setuid"
50 ];
51 };
52in
53{
54 options = {
55 services.dgraph = {
56 enable = mkEnableOption (lib.mdDoc "Dgraph native GraphQL database with a graph backend");
57
58 package = lib.mkPackageOptionMD pkgs "dgraph" { };
59
60 settings = mkOption {
61 type = settingsFormat.type;
62 default = {};
63 description = lib.mdDoc ''
64 Contents of the dgraph config. For more details see https://dgraph.io/docs/deploy/config
65 '';
66 };
67
68 alpha = {
69 host = mkOption {
70 type = types.str;
71 default = "localhost";
72 description = lib.mdDoc ''
73 The host which dgraph alpha will be run on.
74 '';
75 };
76 port = mkOption {
77 type = types.port;
78 default = 7080;
79 description = lib.mdDoc ''
80 The port which to run dgraph alpha on.
81 '';
82 };
83
84 };
85
86 zero = {
87 host = mkOption {
88 type = types.str;
89 default = "localhost";
90 description = lib.mdDoc ''
91 The host which dgraph zero will be run on.
92 '';
93 };
94 port = mkOption {
95 type = types.port;
96 default = 5080;
97 description = lib.mdDoc ''
98 The port which to run dgraph zero on.
99 '';
100 };
101 };
102
103 };
104 };
105
106 config = mkIf cfg.enable {
107 services.dgraph.settings = {
108 badger.compression = mkDefault "zstd:3";
109 };
110
111 systemd.services.dgraph-zero = {
112 description = "Dgraph native GraphQL database with a graph backend. Zero controls node clustering";
113 after = [ "network.target" ];
114 wantedBy = [ "multi-user.target" ];
115
116 serviceConfig = {
117 StateDirectory = "dgraph-zero";
118 WorkingDirectory = "/var/lib/dgraph-zero";
119 DynamicUser = true;
120 ExecStart = "${cfg.package}/bin/dgraph zero --my ${cfg.zero.host}:${toString cfg.zero.port}";
121 Restart = "on-failure";
122 } // securityOptions;
123 };
124
125 systemd.services.dgraph-alpha = {
126 description = "Dgraph native GraphQL database with a graph backend. Alpha serves data";
127 after = [ "network.target" "dgraph-zero.service" ];
128 requires = [ "dgraph-zero.service" ];
129 wantedBy = [ "multi-user.target" ];
130
131 serviceConfig = {
132 StateDirectory = "dgraph-alpha";
133 WorkingDirectory = "/var/lib/dgraph-alpha";
134 DynamicUser = true;
135 ExecStart = "${dgraphWithNode}/bin/dgraph alpha --config ${configFile} --my ${cfg.alpha.host}:${toString cfg.alpha.port} --zero ${cfg.zero.host}:${toString cfg.zero.port}";
136 ExecStop = ''
137 ${pkgs.curl}/bin/curl --data "mutation { shutdown { response { message code } } }" \
138 --header 'Content-Type: application/graphql' \
139 -X POST \
140 http://localhost:8080/admin
141 '';
142 Restart = "on-failure";
143 } // securityOptions;
144 };
145 };
146
147 meta.maintainers = with lib.maintainers; [ happysalada ];
148}