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