1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.neo4j;
7
8 serverConfig = pkgs.writeText "neo4j-server.properties" ''
9 org.neo4j.server.database.location=${cfg.dataDir}/data/graph.db
10 org.neo4j.server.webserver.address=${cfg.listenAddress}
11 org.neo4j.server.webserver.port=${toString cfg.port}
12 ${optionalString cfg.enableHttps ''
13 org.neo4j.server.webserver.https.enabled=true
14 org.neo4j.server.webserver.https.port=${toString cfg.httpsPort}
15 org.neo4j.server.webserver.https.cert.location=${cfg.cert}
16 org.neo4j.server.webserver.https.key.location=${cfg.key}
17 org.neo4j.server.webserver.https.keystore.location=${cfg.dataDir}/data/keystore
18 ''}
19 org.neo4j.server.webadmin.rrdb.location=${cfg.dataDir}/data/rrd
20 org.neo4j.server.webadmin.data.uri=/db/data/
21 org.neo4j.server.webadmin.management.uri=/db/manage/
22 org.neo4j.server.db.tuning.properties=${cfg.package}/share/neo4j/conf/neo4j.properties
23 org.neo4j.server.manage.console_engines=shell
24 ${cfg.extraServerConfig}
25 '';
26
27 loggingConfig = pkgs.writeText "logging.properties" cfg.loggingConfig;
28
29 wrapperConfig = pkgs.writeText "neo4j-wrapper.conf" ''
30 wrapper.java.additional=-Dorg.neo4j.server.properties=${serverConfig}
31 wrapper.java.additional=-Djava.util.logging.config.file=${loggingConfig}
32 wrapper.java.additional=-XX:+UseConcMarkSweepGC
33 wrapper.java.additional=-XX:+CMSClassUnloadingEnabled
34 wrapper.pidfile=${cfg.dataDir}/neo4j-server.pid
35 wrapper.name=neo4j
36 '';
37
38in {
39
40 ###### interface
41
42 options.services.neo4j = {
43 enable = mkOption {
44 description = "Whether to enable neo4j.";
45 default = false;
46 type = types.bool;
47 };
48
49 package = mkOption {
50 description = "Neo4j package to use.";
51 default = pkgs.neo4j;
52 defaultText = "pkgs.neo4j";
53 type = types.package;
54 };
55
56 listenAddress = mkOption {
57 description = "Neo4j listen address.";
58 default = "127.0.0.1";
59 type = types.str;
60 };
61
62 port = mkOption {
63 description = "Neo4j port to listen for HTTP traffic.";
64 default = 7474;
65 type = types.int;
66 };
67
68 enableHttps = mkOption {
69 description = "Enable https for Neo4j.";
70 default = false;
71 type = types.bool;
72 };
73
74 httpsPort = mkOption {
75 description = "Neo4j port to listen for HTTPS traffic.";
76 default = 7473;
77 type = types.int;
78 };
79
80 cert = mkOption {
81 description = "Neo4j https certificate.";
82 default = "${cfg.dataDir}/conf/ssl/neo4j.cert";
83 type = types.path;
84 };
85
86 key = mkOption {
87 description = "Neo4j https certificate key.";
88 default = "${cfg.dataDir}/conf/ssl/neo4j.key";
89 type = types.path;
90 };
91
92 dataDir = mkOption {
93 description = "Neo4j data directory.";
94 default = "/var/lib/neo4j";
95 type = types.path;
96 };
97
98 loggingConfig = mkOption {
99 description = "Neo4j logging configuration.";
100 default = ''
101 handlers=java.util.logging.ConsoleHandler
102 .level=INFO
103 org.neo4j.server.level=INFO
104
105 java.util.logging.ConsoleHandler.level=INFO
106 java.util.logging.ConsoleHandler.formatter=org.neo4j.server.logging.SimpleConsoleFormatter
107 java.util.logging.ConsoleHandler.filter=org.neo4j.server.logging.NeoLogFilter
108 '';
109 type = types.lines;
110 };
111
112 extraServerConfig = mkOption {
113 description = "Extra configuration for neo4j server.";
114 default = "";
115 type = types.lines;
116 };
117
118 };
119
120 ###### implementation
121
122 config = mkIf cfg.enable {
123 systemd.services.neo4j = {
124 description = "Neo4j Daemon";
125 wantedBy = [ "multi-user.target" ];
126 after = [ "network-interfaces.target" ];
127 environment = { NEO4J_INSTANCE = cfg.dataDir; };
128 serviceConfig = {
129 ExecStart = "${cfg.package}/bin/neo4j console";
130 User = "neo4j";
131 PermissionsStartOnly = true;
132 };
133 preStart = ''
134 mkdir -m 0700 -p ${cfg.dataDir}/{data/graph.db,conf}
135 ln -fs ${wrapperConfig} ${cfg.dataDir}/conf/neo4j-wrapper.conf
136 if [ "$(id -u)" = 0 ]; then chown -R neo4j ${cfg.dataDir}; fi
137 '';
138 };
139
140 environment.systemPackages = [ pkgs.neo4j ];
141
142 users.extraUsers = singleton {
143 name = "neo4j";
144 uid = config.ids.uids.neo4j;
145 description = "Neo4j daemon user";
146 home = cfg.dataDir;
147 };
148 };
149
150}