]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - virtual/eldiron.nix
Move websites to their own modules: php config and scripts
[perso/Immae/Config/Nix.git] / virtual / eldiron.nix
CommitLineData
a1bb33c4
IB
1{
2 network = {
3 description = "Immae's network";
4 enableRollback = true;
5 };
6
4d4f13f4
IB
7 eldiron = { config, pkgs, mylibs, ... }:
8 with mylibs;
5c101474 9 let
712ccefd 10 mypkgs = pkgs.callPackage ./packages.nix {
eb770e14 11 inherit checkEnv fetchedGit fetchedGitPrivate fetchedGithub;
5c101474 12 };
ab5d04b8
IB
13 in
14 {
4d4f13f4
IB
15 _module.args = {
16 mylibs = import ../libs.nix;
17 };
18
19 imports = [
3013caf1 20 ./modules/certificates.nix
4d4f13f4
IB
21 ./modules/gitolite.nix
22 ./modules/gitweb.nix
23 ./modules/databases.nix
3013caf1
IB
24 ./modules/websites/chloe.nix
25 ./modules/websites/ludivine.nix
26 ./modules/websites/aten.nix
27 ./modules/websites/piedsjaloux.nix
28 ./modules/websites/connexionswing.nix
4d4f13f4
IB
29 ];
30 services.myGitolite.enable = true;
31 services.myGitweb.enable = true;
32 services.myDatabases.enable = true;
3013caf1
IB
33 services.myWebsites.Chloe.production.enable = true;
34 services.myWebsites.Chloe.integration.enable = true;
35 services.myWebsites.Ludivine.production.enable = true;
36 services.myWebsites.Ludivine.integration.enable = true;
37 services.myWebsites.Aten.production.enable = true;
38 services.myWebsites.Aten.integration.enable = true;
39 services.myWebsites.PiedsJaloux.production.enable = true;
40 services.myWebsites.PiedsJaloux.integration.enable = true;
41 services.myWebsites.Connexionswing.production.enable = true;
42 services.myWebsites.Connexionswing.integration.enable = true;
4d4f13f4 43
91493dc0 44 nixpkgs.config.packageOverrides = oldpkgs: rec {
6f0d92b4
IB
45 goaccess = oldpkgs.goaccess.overrideAttrs(old: rec {
46 name = "goaccess-${version}";
47 version = "1.3";
48 src = pkgs.fetchurl {
49 url = "https://tar.goaccess.io/${name}.tar.gz";
50 sha256 = "16vv3pj7pbraq173wlxa89jjsd279004j4kgzlrsk1dz4if5qxwc";
51 };
52 configureFlags = old.configureFlags ++ [ "--enable-tcb=btree" ];
53 buildInputs = old.buildInputs ++ [ pkgs.tokyocabinet pkgs.bzip2 ];
54 });
91493dc0
IB
55 };
56
a1bb33c4
IB
57 networking = {
58 firewall = {
59 enable = true;
4d4f13f4 60 allowedTCPPorts = [ 22 80 443 9418 ];
a1bb33c4
IB
61 };
62 };
63
64 deployment = {
65 targetEnv = "hetzner";
66 hetzner = {
67 #robotUser = "defined in HETZNER_ROBOT_USER";
68 #robotPass = "defined in HETZNER_ROBOT_PASS";
69 mainIPv4 = "176.9.151.89";
70 partitions = ''
71 clearpart --all --initlabel --drives=sda,sdb
72
73 part swap1 --recommended --label=swap1 --fstype=swap --ondisk=sda
74 part swap2 --recommended --label=swap2 --fstype=swap --ondisk=sdb
75
76 part raid.1 --grow --ondisk=sda
77 part raid.2 --grow --ondisk=sdb
78
79 raid / --level=1 --device=md0 --fstype=ext4 --label=root raid.1 raid.2
80 '';
81 };
82 };
83
66b5bbf6
IB
84 environment.systemPackages = let
85 # FIXME: move it to nextcloud
86 occ = pkgs.writeScriptBin "nextcloud-occ" ''
87 #! ${pkgs.stdenv.shell}
88 cd ${mypkgs.nextcloud.webRoot}
89 NEXTCLOUD_CONFIG_DIR="${mypkgs.nextcloud.webRoot}/config" \
90 exec \
91 ${config.services.phpfpm.phpPackage}/bin/php \
92 -c ${config.services.phpfpm.phpPackage}/etc/php.ini \
93 occ $*
94 '';
95 in [
ce6ee3b8 96 pkgs.telnet
beeed847 97 pkgs.htop
ce6ee3b8 98 pkgs.vim
6f0d92b4 99 pkgs.goaccess
66b5bbf6 100 occ
ce6ee3b8
IB
101 ];
102
3013caf1
IB
103 security.acme.certs."eldiron".extraDomains = {
104 "db-1.immae.eu" = null;
105 "tools.immae.eu" = null;
106 "cloud.immae.eu" = null;
107 "dav.immae.eu" = null;
a1bb33c4
IB
108 };
109
5566d26d
IB
110 services.openssh.extraConfig = ''
111 AuthorizedKeysCommand /etc/ssh/ldap_authorized_keys
112 AuthorizedKeysCommandUser nobody
113 '';
114
beeed847 115 services.ympd = mypkgs.ympd.config // { enable = false; };
a05f8abe 116
58d1a782 117 services.phpfpm = {
beeed847 118 # FIXME: move session files to separate dirs
66b5bbf6
IB
119 # /!\ phppackage is used in nextcloud configuation
120 phpOptions = ''
c8e019b6
IB
121 session.save_path = "/var/lib/php/sessions"
122 session.gc_maxlifetime = 60*60*24*15
123 session.cache_expire = 60*24*30
66b5bbf6
IB
124 ; For nextcloud
125 extension=${pkgs.phpPackages.redis}/lib/php/extensions/redis.so
126 ; For nextcloud
127 extension=${pkgs.phpPackages.apcu}/lib/php/extensions/apcu.so
ec9ff2b8
IB
128 ; For nextcloud
129 zend_extension=${pkgs.php}/lib/php/extensions/opcache.so
66b5bbf6 130 '';
58d1a782
IB
131 extraConfig = ''
132 log_level = notice
133 '';
134 poolConfigs = {
27e22b76 135 adminer = mypkgs.adminer.phpFpm.pool;
66b5bbf6 136 nextcloud = mypkgs.nextcloud.phpFpm.pool;
50d8fa14 137 mantisbt = mypkgs.mantisbt.phpFpm.pool;
eb770e14 138 ttrss = mypkgs.ttrss.phpFpm.pool;
d252d718 139 roundcubemail = mypkgs.roundcubemail.phpFpm.pool;
d9998b44 140 davical = mypkgs.davical.phpFpm.pool;
58d1a782
IB
141 };
142 };
143
65fe7543 144 system.activationScripts = {
66b5bbf6 145 nextcloud = mypkgs.nextcloud.activationScript;
eb770e14 146 ttrss = mypkgs.ttrss.activationScript;
d252d718 147 roundcubemail = mypkgs.roundcubemail.activationScript;
5dd28b43
IB
148 httpd = ''
149 install -d -m 0755 /var/lib/acme/acme-challenge
c8e019b6
IB
150 install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions
151 install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/adminer
152 install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/mantisbt
eb770e14 153 install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/ttrss
1635a4ae 154 install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions/davical
5dd28b43 155 '';
60f67ae3
IB
156 redis = ''
157 mkdir -p /run/redis
158 chown redis /run/redis
159 '';
6bd6d033 160 # FIXME: initial sync
6f0d92b4
IB
161 goaccess = ''
162 mkdir -p /var/lib/goaccess
163 mkdir -p /var/lib/goaccess/aten.pro
34e2fd14
IB
164 mkdir -p /var/lib/goaccess/ludivinecassal.com
165 mkdir -p /var/lib/goaccess/piedsjaloux.fr
6bd6d033 166 mkdir -p /var/lib/goaccess/osteopathe-cc.fr
527e32ad 167 mkdir -p /var/lib/goaccess/connexionswing.com
6f0d92b4 168 '';
5566d26d
IB
169 };
170
171 environment.etc."ssh/ldap_authorized_keys" = let
172 ldap_authorized_keys =
5c101474
IB
173 assert checkEnv "NIXOPS_SSHD_LDAP_PASSWORD";
174 wrap {
5566d26d
IB
175 name = "ldap_authorized_keys";
176 file = ./ldap_authorized_keys.sh;
177 vars = {
178 LDAP_PASS = builtins.getEnv "NIXOPS_SSHD_LDAP_PASSWORD";
179 GITOLITE_SHELL = "${pkgs.gitolite}/bin/gitolite-shell";
180 ECHO = "${pkgs.coreutils}/bin/echo";
181 };
182 paths = [ pkgs.openldap pkgs.stdenv.shellPackage pkgs.gnugrep pkgs.gnused pkgs.coreutils ];
183 };
184 in {
185 enable = true;
186 mode = "0755";
187 user = "root";
188 source = ldap_authorized_keys;
65fe7543
IB
189 };
190
7611e4e2
IB
191 services.gitDaemon = {
192 enable = true;
193 user = "gitolite";
194 group = "gitolite";
195 basePath = "${mypkgs.git.web.varDir}/repositories";
196 };
197
beeed847 198 # FIXME: logrotate
58d1a782 199 services.httpd = let
b7cd7e4b 200 withConf = domain: {
58d1a782 201 enableSSL = true;
5dd28b43 202 sslServerCert = "/var/lib/acme/${domain}/cert.pem";
58d1a782
IB
203 sslServerKey = "/var/lib/acme/${domain}/key.pem";
204 sslServerChain = "/var/lib/acme/${domain}/fullchain.pem";
b7cd7e4b
IB
205 logFormat = "combinedVhost";
206 listen = [ { ip = "*"; port = 443; } ];
58d1a782 207 };
94818b75
IB
208 apacheConfig = {
209 gzip = {
210 modules = [ "deflate" "filter" ];
211 extraConfig = ''
212 AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
213 '';
214 };
215 ldap = {
216 modules = [ "ldap" "authnz_ldap" ];
5c101474 217 extraConfig = assert checkEnv "NIXOPS_HTTP_LDAP_PASSWORD"; ''
94818b75
IB
218 <IfModule ldap_module>
219 LDAPSharedCacheSize 500000
220 LDAPCacheEntries 1024
221 LDAPCacheTTL 600
222 LDAPOpCacheEntries 1024
223 LDAPOpCacheTTL 600
224 </IfModule>
225
226 <Macro LDAPConnect>
227 <IfModule authnz_ldap_module>
228 AuthLDAPURL ldap://ldap.immae.eu:389/dc=immae,dc=eu
229 AuthLDAPBindDN cn=httpd,ou=services,dc=immae,dc=eu
230 AuthLDAPBindPassword "${builtins.getEnv "NIXOPS_HTTP_LDAP_PASSWORD"}"
231 AuthType Basic
232 AuthName "Authentification requise (Acces LDAP)"
233 AuthBasicProvider ldap
234 </IfModule>
235 </Macro>
6f0d92b4
IB
236
237 <Macro Stats %{domain}>
238 Alias /awstats /var/lib/goaccess/%{domain}
239 <Directory /var/lib/goaccess/%{domain}>
240 DirectoryIndex index.html
241 AllowOverride None
242 Require all granted
243 </Directory>
244 <Location /awstats>
245 Use LDAPConnect
246 Require ldap-group cn=%{domain},ou=stats,cn=httpd,ou=services,dc=immae,dc=eu
247 </Location>
248 </Macro>
94818b75
IB
249 '';
250 };
b7cd7e4b
IB
251 http2 = {
252 modules = [ "http2" ];
253 extraConfig = ''
254 Protocols h2 http/1.1
255 '';
256 };
257 customLog = {
258 modules = [];
259 extraConfig = ''
6f0d92b4 260 LogFormat "%v:%p %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedVhost
b7cd7e4b
IB
261 '';
262 };
94818b75 263 };
58d1a782 264 in rec {
a1bb33c4 265 enable = true;
58d1a782
IB
266 logPerVirtualHost = true;
267 multiProcessingModule = "worker";
268 adminAddr = "httpd@immae.eu";
b7cd7e4b 269 logFormat = "combinedVhost";
25fd1d16
IB
270 extraModules = pkgs.lib.lists.unique (
271 mypkgs.adminer.apache.modules ++
66b5bbf6 272 mypkgs.nextcloud.apache.modules ++
65fe7543 273 mypkgs.connexionswing_dev.apache.modules ++
e273ef92 274 mypkgs.connexionswing_prod.apache.modules ++
e42ba74f
IB
275 mypkgs.ludivinecassal_dev.apache.modules ++
276 mypkgs.ludivinecassal_prod.apache.modules ++
34e2fd14
IB
277 mypkgs.piedsjaloux_dev.apache.modules ++
278 mypkgs.piedsjaloux_prod.apache.modules ++
7d8b50d3
IB
279 mypkgs.chloe_dev.apache.modules ++
280 mypkgs.chloe_prod.apache.modules ++
6c672f34
IB
281 mypkgs.aten_dev.apache.modules ++
282 mypkgs.aten_prod.apache.modules ++
5f3e023d 283 mypkgs.ympd.apache.modules ++
cf80b4f2 284 mypkgs.git.web.apache.modules ++
50d8fa14 285 mypkgs.mantisbt.apache.modules ++
eb770e14 286 mypkgs.ttrss.apache.modules ++
d252d718 287 mypkgs.roundcubemail.apache.modules ++
94818b75
IB
288 pkgs.lib.lists.flatten (pkgs.lib.attrsets.mapAttrsToList (n: v: v.modules) apacheConfig) ++
289 [ "macro" ]);
290 extraConfig = builtins.concatStringsSep "\n"
291 (pkgs.lib.attrsets.mapAttrsToList (n: v: v.extraConfig) apacheConfig);
58d1a782 292 virtualHosts = [
b7cd7e4b 293 (withConf "eldiron" // {
58d1a782 294 hostName = "eldiron.immae.eu";
1d4ccb2c
IB
295 documentRoot = ./www;
296 extraConfig = ''
297 DirectoryIndex index.htm
298 '';
58d1a782 299 })
b7cd7e4b 300 (withConf "eldiron" // {
58d1a782
IB
301 hostName = "db-1.immae.eu";
302 documentRoot = null;
27e22b76 303 extraConfig = builtins.concatStringsSep "\n" [
1bb2ff2c 304 mypkgs.adminer.apache.vhostConf
27e22b76 305 ];
58d1a782 306 })
b7cd7e4b 307 (withConf "eldiron" // {
e379fd29
IB
308 hostName = "tools.immae.eu";
309 documentRoot = null;
310 extraConfig = builtins.concatStringsSep "\n" [
1bb2ff2c 311 mypkgs.adminer.apache.vhostConf
a05f8abe 312 mypkgs.ympd.apache.vhostConf
eb770e14 313 mypkgs.ttrss.apache.vhostConf
d252d718 314 mypkgs.roundcubemail.apache.vhostConf
43b726ed
IB
315 ];
316 })
317 (withConf "eldiron" // {
318 hostName = "dav.immae.eu";
319 documentRoot = null;
320 extraConfig = builtins.concatStringsSep "\n" [
1635a4ae 321 mypkgs.infcloud.apache.vhostConf
d9998b44 322 mypkgs.davical.apache.vhostConf
e379fd29
IB
323 ];
324 })
b7cd7e4b 325 (withConf "eldiron" // {
65fe7543
IB
326 hostName = "connexionswing.immae.eu";
327 serverAliases = [ "sandetludo.immae.eu" ];
328 documentRoot = mypkgs.connexionswing_dev.webRoot;
329 extraConfig = builtins.concatStringsSep "\n" [
330 mypkgs.connexionswing_dev.apache.vhostConf
331 ];
332 })
527e32ad
IB
333 (withConf "connexionswing" // {
334 hostName = "connexionswing.com";
335 serverAliases = [ "sandetludo.com" "www.connexionswing.com" "www.sandetludo.com" ];
336 documentRoot = mypkgs.connexionswing_prod.webRoot;
337 extraConfig = builtins.concatStringsSep "\n" [
338 mypkgs.connexionswing_prod.apache.vhostConf
339 ];
340 })
e42ba74f
IB
341 (withConf "eldiron" // {
342 hostName = "ludivine.immae.eu";
343 documentRoot = mypkgs.ludivinecassal_dev.webRoot;
344 extraConfig = builtins.concatStringsSep "\n" [
345 mypkgs.ludivinecassal_dev.apache.vhostConf
346 ];
347 })
348 (withConf "ludivinecassal" // {
349 hostName = "ludivinecassal.com";
350 serverAliases = [ "www.ludivinecassal.com" ];
351 documentRoot = mypkgs.ludivinecassal_prod.webRoot;
352 extraConfig = builtins.concatStringsSep "\n" [
353 mypkgs.ludivinecassal_prod.apache.vhostConf
354 ];
355 })
34e2fd14
IB
356 (withConf "eldiron" // {
357 hostName = "piedsjaloux.immae.eu";
358 documentRoot = mypkgs.piedsjaloux_dev.webRoot;
359 extraConfig = builtins.concatStringsSep "\n" [
360 mypkgs.piedsjaloux_dev.apache.vhostConf
361 ];
362 })
363 (withConf "piedsjaloux" // {
364 hostName = "piedsjaloux.fr";
365 serverAliases = [ "www.piedsjaloux.fr" ];
366 documentRoot = mypkgs.piedsjaloux_prod.webRoot;
367 extraConfig = builtins.concatStringsSep "\n" [
368 mypkgs.piedsjaloux_prod.apache.vhostConf
369 ];
370 })
7d8b50d3
IB
371 (withConf "eldiron" // {
372 hostName = "chloe.immae.eu";
373 documentRoot = mypkgs.chloe_dev.webRoot;
374 extraConfig = builtins.concatStringsSep "\n" [
375 mypkgs.chloe_dev.apache.vhostConf
376 ];
377 })
6bd6d033 378 (withConf "chloe" // {
7d8b50d3
IB
379 hostName = "osteopathe-cc.fr";
380 serverAliases = [ "www.osteopathe-cc.fr" ];
381 documentRoot = mypkgs.chloe_prod.webRoot;
382 extraConfig = builtins.concatStringsSep "\n" [
383 mypkgs.chloe_prod.apache.vhostConf
384 ];
385 })
6c672f34
IB
386 (withConf "eldiron" // {
387 hostName = "dev.aten.pro";
388 documentRoot = mypkgs.aten_dev.webRoot;
389 extraConfig = builtins.concatStringsSep "\n" [
390 mypkgs.aten_dev.apache.vhostConf
391 ];
392 })
393 (withConf "aten" // {
394 hostName = "aten.pro";
395 serverAliases = [ "www.aten.pro" ];
396 documentRoot = mypkgs.aten_prod.webRoot;
397 extraConfig = builtins.concatStringsSep "\n" [
398 mypkgs.aten_prod.apache.vhostConf
399 ];
400 })
b7cd7e4b 401 (withConf "eldiron" // {
66b5bbf6
IB
402 hostName = "cloud.immae.eu";
403 documentRoot = mypkgs.nextcloud.webRoot;
404 extraConfig = builtins.concatStringsSep "\n" [
405 mypkgs.nextcloud.apache.vhostConf
406 ];
407 })
b7cd7e4b 408 (withConf "eldiron" // {
cf80b4f2
IB
409 hostName = "git.immae.eu";
410 documentRoot = mypkgs.git.web.webRoot;
411 extraConfig = builtins.concatStringsSep "\n" [
412 mypkgs.git.web.apache.vhostConf
50d8fa14 413 mypkgs.mantisbt.apache.vhostConf
cf80b4f2
IB
414 ] + ''
415 RewriteEngine on
416 RewriteCond %{REQUEST_URI} ^/releases
417 RewriteRule /releases(.*) https://release.immae.eu$1 [P,L]
418 '';
419 })
58d1a782
IB
420 { # Should go last, default fallback
421 listen = [ { ip = "*"; port = 80; } ];
422 hostName = "redirectSSL";
423 serverAliases = [ "*" ];
424 enableSSL = false;
b7cd7e4b 425 logFormat = "combinedVhost";
58d1a782
IB
426 documentRoot = "/var/lib/acme/acme-challenge";
427 extraConfig = ''
428 RewriteEngine on
429 RewriteCond "%{REQUEST_URI}" "!^/\.well-known"
430 RewriteRule ^(.+) https://%{HTTP_HOST}$1 [R=301]
431 # To redirect in specific "VirtualHost *:80", do
432 # RedirectMatch 301 ^/((?!\.well-known.*$).*)$ https://host/$1
433 # rather than rewrite
434 '';
435 }
43b726ed 436 ];
58d1a782
IB
437 };
438
6f0d92b4
IB
439 services.cron = {
440 enable = true;
441 systemCronJobs = let
6bd6d033 442 stats = domain: conf: let
0facadb8
IB
443 d = pkgs.writeScriptBin "stats-${domain}" ''
444 #!${pkgs.stdenv.shell}
445 set -e
446 shopt -s nullglob
447 date_regex=$(LC_ALL=C date -d yesterday +'%d\/%b\/%Y')
448 TMPFILE=$(mktemp)
449 trap "rm -f $TMPFILE" EXIT
450
451 cat /var/log/httpd/access_log-${domain} | sed -n "/\\[$date_regex/ p" > $TMPFILE
452 for i in /var/log/httpd/access_log-${domain}*.gz; do
453 zcat "$i" | sed -n "/\\[$date_regex/ p" >> $TMPFILE
454 done
455 goaccess $TMPFILE --no-progress -o /var/lib/goaccess/${domain}/index.html -p ${conf}
456 '';
6bd6d033 457 in "${d}/bin/stats-${domain}";
56991aa7
IB
458 # FIXME: running several goaccess simultaneously seems to be
459 # bugged?
6f0d92b4
IB
460 in [
461 "5 0 * * * root ${stats "aten.pro" ./packages/aten_goaccess.conf}"
56991aa7
IB
462 "6 0 * * * root ${stats "ludivinecassal.com" ./packages/ludivinecassal_goaccess.conf}"
463 "7 0 * * * root ${stats "piedsjaloux.fr" ./packages/piedsjaloux_goaccess.conf}"
464 "8 0 * * * root ${stats "osteopathe-cc.fr" ./packages/chloe_goaccess.conf}"
465 "9 0 * * * root ${stats "connexionswing.com" ./packages/connexionswing_goaccess.conf}"
6f0d92b4
IB
466 ];
467 };
eb770e14
IB
468
469 systemd.services.tt-rss = {
470 description = "Tiny Tiny RSS feeds update daemon";
471 serviceConfig = {
472 User = "wwwrun";
473 ExecStart = "${pkgs.php}/bin/php ${mypkgs.ttrss.webRoot}/update.php --daemon";
474 StandardOutput = "syslog";
475 StandardError = "syslog";
476 PermissionsStartOnly = true;
477 };
478
479 wantedBy = [ "multi-user.target" ];
480 requires = ["postgresql.service"];
481 after = ["network.target" "postgresql.service"];
482 };
a1bb33c4
IB
483 };
484}