{ lib, pkgs, config, mypackages-lib, grocy, ... }: let composerEnv = mypackages-lib.composerEnv; adminer = pkgs.callPackage ./adminer.nix { inherit config; }; ympd = pkgs.callPackage ./ympd.nix { env = config.myEnv.tools.ympd; inherit config; }; ttrss = pkgs.callPackage ./ttrss.nix { ttrss = pkgs.webapps-ttrss; ttrss-plugins = pkgs.webapps-ttrss-plugins; env = config.myEnv.tools.ttrss; php = pkgs.php72; inherit config; }; kanboard = pkgs.callPackage ./kanboard.nix { inherit config; env = config.myEnv.tools.kanboard; }; wallabag = pkgs.callPackage ./wallabag.nix { wallabag = pkgs.webapps-wallabag.override { composerEnv = composerEnv.override { php = pkgs.php73.withExtensions({ enabled, all }: enabled ++ [all.tidy]); }; }; env = config.myEnv.tools.wallabag; inherit config; }; yourls = pkgs.callPackage ./yourls.nix { yourls = pkgs.webapps-yourls; yourls-plugins = pkgs.webapps-yourls-plugins; env = config.myEnv.tools.yourls; inherit config; }; rompr = pkgs.callPackage ./rompr.nix { rompr = pkgs.webapps-rompr; env = config.myEnv.tools.rompr; inherit config; }; shaarli = pkgs.callPackage ./shaarli.nix { env = config.myEnv.tools.shaarli; inherit config; }; dokuwiki = pkgs.callPackage ./dokuwiki.nix { dokuwiki = pkgs.webapps-dokuwiki; dokuwiki-plugins = pkgs.webapps-dokuwiki-plugins; inherit config; }; ldap = pkgs.callPackage ./ldap.nix { phpldapadmin = pkgs.webapps-phpldapadmin; env = config.myEnv.tools.phpldapadmin; inherit config; }; grocy' = pkgs.callPackage ./grocy.nix { grocy = grocy.override { composerEnv = composerEnv.override { php = pkgs.php72; }; }; }; phpbb = pkgs.callPackage ./phpbb.nix { phpbb = (pkgs.webapps-phpbb.withLangs (l: [ l.fr ])).withExts (e: [ e.alfredoramos.markdown e.davidiq.mailinglist e.dmzx.mchat e.empteintesduweb.monitoranswers e.lr94.autosubscribe e.phpbbmodders.adduser ]); }; webhooks-bin-env = pkgs.buildEnv { name = "webhook-env"; paths = [ pkgs.apprise ]; pathsToLink = [ "/bin" ]; }; webhooks = pkgs.callPackage ./webhooks.nix { env = config.myEnv.tools.webhooks; binEnv = webhooks-bin-env; }; dmarc-reports = pkgs.callPackage ./dmarc_reports.nix { env = config.myEnv.tools.dmarc_reports; inherit config; }; landing = pkgs.callPackage ./landing.nix { }; matrix = pkgs.element-web.override { conf = { default_server_config."m.homeserver" = { base_url = "https://synapse.immae.eu"; server_name = "immae.eu"; }; default_server_config."m.identity_server" = { base_url = "https://vector.im"; }; room_directory.servers = [ "immae.eu" "matrix.org" ]; }; }; cfg = config.myServices.websites.tools.tools; pcfg = config.services.phpfpm.pools; in { options.myServices.websites.tools.tools = { enable = lib.mkEnableOption "enable tools website"; }; config = lib.mkIf cfg.enable { # Services needing to send e-mails myServices.dns.zones."immae.eu".emailPolicies."tools".receive = true; myServices.dns.zones."immae.eu".subdomains = with config.myServices.dns.helpers; { outils = ips servers.eldiron.ips.main; tools = lib.mkMerge [ (mailCommon "immae.eu" true) mailSend (ips servers.eldiron.ips.main) ]; }; myServices.chatonsProperties.services = { adminer = adminer.chatonsProperties; dokuwiki = dokuwiki.chatonsProperties; shaarli = shaarli.chatonsProperties; ttrss = ttrss.chatonsProperties; wallabag = wallabag.chatonsProperties; paste = { file.datetime = "2022-08-22T00:15:00"; service = { name = "Paste"; description = "A simple paster script with syntax highlight"; website = "https://tools.immae.eu/paste/"; logo = "https://assets.immae.eu/logo.jpg"; status.level = "OK"; status.description = "OK"; registration."" = ["MEMBER" "CLIENT"]; registration.load = "OPEN"; install.type = "PACKAGE"; guide.user = "https://tools.immae.eu/paste/"; }; software = { name = "Paste"; website = "https://tools.immae.eu/paste/"; license.url = "https://tools.immae.eu/paste/license"; license.name = "MIT License"; version = "Unversioned"; source.url = "https://tools.immae.eu/paste/abcd123/py"; }; }; }; myServices.chatonsProperties.hostings = { dokuwiki = dokuwiki.chatonsHostingProperties; phpbb = phpbb.chatonsHostingProperties; }; secrets.keys = kanboard.keys // ldap.keys // shaarli.keys // ttrss.keys // wallabag.keys // yourls.keys // dmarc-reports.keys // webhooks.keys // ({ "webapps/tools-landing-sql-rw" = { user = "wwwrun"; group = "wwwrun"; permissions = "0400"; text = let env = config.myEnv.tools.landing; in '' SetEnv PGUSER "${env.postgresql.user}" SetEnv PGPASSWORD "${env.postgresql.password}" SetEnv PGDATABASE "${env.postgresql.database}" SetEnv PGHOST "${env.postgresql.socket}" ''; }; }); services.websites.env.tools.modules = [ "proxy_fcgi" ] ++ adminer.apache.modules ++ ympd.apache.modules ++ ttrss.apache.modules ++ wallabag.apache.modules ++ yourls.apache.modules ++ rompr.apache.modules ++ shaarli.apache.modules ++ dokuwiki.apache.modules ++ dmarc-reports.apache.modules ++ phpbb.apache.modules ++ ldap.apache.modules ++ kanboard.apache.modules; myServices.dns.zones."immae.dev" = with config.myServices.dns.helpers; { subdomains.tools = ips servers.eldiron.ips.integration; }; security.acme.certs.integration.domain = "tools.immae.dev"; services.websites.env.integration.vhostConfs.devtools = { certName = "integration"; hosts = [ "tools.immae.dev" ]; root = "/var/lib/ftp/immae/devtools"; extraConfig = [ '' Use Apaxy "/var/lib/ftp/immae/devtools" "title" Timeout 600 ProxyTimeout 600 Header always set Content-Security-Policy-Report-Only "${config.myEnv.tools.csp_reports.policies.inline}" DirectoryIndex index.php index.htm index.html AllowOverride all Require all granted SetHandler "proxy:unix:${pcfg.devtools.socket}|fcgi://localhost" '' ]; }; security.acme.certs.eldiron.extraDomainNames = [ "outils.immae.eu" "tools.immae.eu" ]; services.websites.env.tools.vhostConfs.tools = { certName = "eldiron"; hosts = ["tools.immae.eu" ]; root = landing; extraConfig = [ '' RedirectMatch 301 ^/vpn(.*)$ https://vpn.immae.eu$1 RedirectMatch 301 ^/roundcube(.*)$ https://mail.immae.eu/roundcube$1 RedirectMatch 301 ^/jappix(.*)$ https://im.immae.fr/converse Include ${config.secrets.fullPaths."webapps/tools-landing-sql-rw"} DirectoryIndex index.html AllowOverride None Require all granted SetHandler "proxy:unix:${pcfg.tools.socket}|fcgi://localhost" '' (adminer.apache.vhostConf pcfg.adminer.socket) ympd.apache.vhostConf (ttrss.apache.vhostConf pcfg.ttrss.socket) (wallabag.apache.vhostConf pcfg.wallabag.socket) (yourls.apache.vhostConf pcfg.yourls.socket) (rompr.apache.vhostConf pcfg.rompr.socket) (shaarli.apache.vhostConf pcfg.shaarli.socket) (dokuwiki.apache.vhostConf pcfg.dokuwiki.socket) (ldap.apache.vhostConf pcfg.ldap.socket) (kanboard.apache.vhostConf pcfg.kanboard.socket) (grocy'.apache.vhostConf pcfg.grocy.socket) (phpbb.apache.vhostConf pcfg.phpbb.socket) (dmarc-reports.apache.vhostConf pcfg.dmarc-reports.socket) '' ProxyPass unix://${config.services.paste.sockets.gunicorn}|http://tools.immae.eu/paste/ ProxyPassReverse unix://${config.services.paste.sockets.gunicorn}|http://tools.immae.eu/paste/ ProxyPreserveHost on ProxyPass unix://${config.services.paste.sockets.gunicorn}|http://tools.immae.eu/paste/ ProxyPassReverse unix://${config.services.paste.sockets.gunicorn}|http://tools.immae.eu/paste/ ProxyPreserveHost on SetEnv proxy-nokeepalive 1 SetEnv proxy-sendchunked 1 LimitRequestBody 102400 RewriteEngine On # FIXME: why is landing prefixed in the url? RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^(${landing}/ntfy)?/?(.*) unix:///run/ntfy/ntfy.sock|ws://tools.immae.eu/$2 [P,NE,QSA,L] RewriteRule ^(${landing}/ntfy)?/?(.*) unix:///run/ntfy/ntfy.sock|http://tools.immae.eu/$2 [P,NE,QSA,L] Alias /BIP39 /var/lib/buildbot/outputs/immae/bip39 DirectoryIndex index.html AllowOverride None Require all granted Alias /webhooks ${config.secrets.fullPaths."webapps/webhooks"} Options -Indexes DirectoryIndex index.php Require all granted AllowOverride None SetHandler "proxy:unix:${pcfg.tools.socket}|fcgi://localhost" Alias /matrix ${matrix} DirectoryIndex index.html AllowOverride None Require all granted '' ]; }; services.websites.env.tools.vhostConfs.outils = { certName = "eldiron"; hosts = [ "outils.immae.eu" ]; root = null; extraConfig = [ '' RedirectMatch 301 ^/mediagoblin(.*)$ https://mgoblin.immae.eu$1 RedirectMatch 301 ^/ether(.*)$ https://ether.immae.eu$1 RedirectMatch 301 ^/nextcloud(.*)$ https://cloud.immae.eu$1 RedirectMatch 301 ^/owncloud(.*)$ https://cloud.immae.eu$1 RedirectMatch 301 ^/carddavmate(.*)$ https://dav.immae.eu/infcloud$1 RedirectMatch 301 ^/caldavzap(.*)$ https://dav.immae.eu/infcloud$1 RedirectMatch 301 ^/caldav.php(.*)$ https://dav.immae.eu/caldav.php$1 RedirectMatch 301 ^/davical(.*)$ https://dav.immae.eu/davical$1 RedirectMatch 301 ^/taskweb(.*)$ https://task.immae.eu/taskweb$1 RedirectMatch 301 ^/roundcube(.*)$ https://mail.immae.eu/roundcube$1 RedirectMatch 301 ^/jappix(.*)$ https://im.immae.fr/converse RedirectMatch 301 ^/vpn(.*)$ https://vpn.immae.eu$1 RedirectMatch 301 ^/(.*)$ https://tools.immae.eu/$1 '' ]; }; systemd.services = { phpfpm-dokuwiki = { after = lib.mkAfter dokuwiki.phpFpm.serviceDeps; wants = dokuwiki.phpFpm.serviceDeps; }; phpfpm-phpbb = { after = lib.mkAfter phpbb.phpFpm.serviceDeps; wants = phpbb.phpFpm.serviceDeps; }; phpfpm-kanboard = { after = lib.mkAfter kanboard.phpFpm.serviceDeps; wants = kanboard.phpFpm.serviceDeps; }; phpfpm-ldap = { after = lib.mkAfter ldap.phpFpm.serviceDeps; wants = ldap.phpFpm.serviceDeps; }; phpfpm-shaarli = { after = lib.mkAfter shaarli.phpFpm.serviceDeps; wants = shaarli.phpFpm.serviceDeps; }; phpfpm-ttrss = { after = lib.mkAfter ttrss.phpFpm.serviceDeps; wants = ttrss.phpFpm.serviceDeps; }; phpfpm-wallabag = { after = lib.mkAfter wallabag.phpFpm.serviceDeps; wants = wallabag.phpFpm.serviceDeps; preStart = lib.mkAfter wallabag.phpFpm.preStart; }; phpfpm-yourls = { after = lib.mkAfter yourls.phpFpm.serviceDeps; wants = yourls.phpFpm.serviceDeps; }; ntfy = { description = "send push notifications to your phone or desktop via scripts from any computer"; wantedBy = [ "multi-user.target" ]; serviceConfig = { ExecStart = "${pkgs.ntfy-sh}/bin/ntfy serve --listen-http '' --listen-unix %t/ntfy/ntfy.sock --cache-file %S/ntfy/cache.db --cache-duration 120h --behind-proxy --attachment-cache-dir %S/ntfy/attachments --base-url https://tools.immae.eu/ntfy"; Type = "simple"; WorkingDirectory = "%S/ntfy"; RuntimeDirectory = "ntfy"; StateDirectory = "ntfy"; User = "wwwrun"; }; }; ympd = { description = "Standalone MPD Web GUI written in C"; wantedBy = [ "multi-user.target" ]; script = '' export MPD_PASSWORD=$(cat ${config.secrets.fullPaths."mpd"}) ${pkgs.ympd}/bin/ympd --host ${ympd.config.host} --port ${toString ympd.config.port} --webport ${ympd.config.webPort} --user nobody ''; }; tt-rss = { description = "Tiny Tiny RSS feeds update daemon"; serviceConfig = { User = "wwwrun"; ExecStart = "${pkgs.php72}/bin/php ${ttrss.webRoot}/update.php --daemon"; StandardOutput = "syslog"; StandardError = "syslog"; PermissionsStartOnly = true; }; wantedBy = [ "multi-user.target" ]; requires = ["postgresql.service"]; after = ["network.target" "postgresql.service"]; }; }; services.filesWatcher.ympd = { restart = true; paths = [ config.secrets.fullPaths."mpd" ]; }; services.paste = { enable = true; webDirectory = "/paste"; }; services.phpfpm.pools = { tools = { user = "wwwrun"; group = "wwwrun"; settings = { "listen.owner" = "wwwrun"; "listen.group" = "wwwrun"; "pm" = "dynamic"; "pm.max_children" = "60"; "pm.start_servers" = "2"; "pm.min_spare_servers" = "1"; "pm.max_spare_servers" = "10"; "php_admin_value[sendmail_path]" = "/run/wrappers/bin/sendmail -t -i"; "php_admin_value[session.save_handler]" = "redis"; "php_admin_value[session.save_path]" = "'unix:///run/redis-php-sessions/redis.sock?persistent=1&prefix=Tools:Tools:'"; # Needed to avoid clashes in browser cookies (same domain) "php_value[session.name]" = "ToolsPHPSESSID"; "php_admin_value[open_basedir]" = builtins.concatStringsSep ":" [ "/run/wrappers/bin/sendmail" landing "/tmp" config.secrets.fullPaths."webapps/webhooks" "${webhooks-bin-env}/bin" ]; }; phpEnv = { CONTACT_EMAIL = config.myEnv.tools.contact; }; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [ all.redis ]); }; devtools = { user = "wwwrun"; group = "wwwrun"; settings = { "listen.owner" = "wwwrun"; "listen.group" = "wwwrun"; "pm" = "dynamic"; "pm.max_children" = "60"; "pm.start_servers" = "2"; "pm.min_spare_servers" = "1"; "pm.max_spare_servers" = "10"; "php_admin_value[sendmail_path]" = "/run/wrappers/bin/sendmail -t -i"; "php_admin_value[session.save_handler]" = "redis"; "php_admin_value[session.save_path]" = "'unix:///run/redis-php-sessions/redis.sock?persistent=1&prefix=Tools:Devtools:'"; "php_admin_value[open_basedir]" = "/run/wrappers/bin/sendmail:/var/lib/ftp/immae/devtools:/tmp"; }; phpPackage = pkgs.php82.withExtensions({ enabled, all }: enabled ++ [all.mysqli all.sqlite3 all.redis all.apcu all.opcache ]); }; adminer = adminer.phpFpm; ttrss = { user = "wwwrun"; group = "wwwrun"; settings = ttrss.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; wallabag = { user = "wwwrun"; group = "wwwrun"; settings = wallabag.phpFpm.pool; phpPackage = pkgs.php73.withExtensions({ enabled, all }: enabled ++ [all.tidy all.redis]); }; yourls = { user = "wwwrun"; group = "wwwrun"; settings = yourls.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; rompr = { user = "wwwrun"; group = "wwwrun"; settings = rompr.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; shaarli = { user = "wwwrun"; group = "wwwrun"; settings = shaarli.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; dmarc-reports = { user = "wwwrun"; group = "wwwrun"; settings = dmarc-reports.phpFpm.pool; phpEnv = dmarc-reports.phpFpm.phpEnv; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; dokuwiki = { user = "wwwrun"; group = "wwwrun"; settings = dokuwiki.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; phpbb = { user = "wwwrun"; group = "wwwrun"; settings = phpbb.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; ldap = { user = "wwwrun"; group = "wwwrun"; settings = ldap.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; kanboard = { user = "wwwrun"; group = "wwwrun"; settings = kanboard.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; grocy = { user = "wwwrun"; group = "wwwrun"; settings = grocy'.phpFpm.pool; phpPackage = pkgs.php72.withExtensions({ enabled, all }: enabled ++ [all.redis]); }; }; system.activationScripts = { grocy = grocy'.activationScript; ttrss = ttrss.activationScript; wallabag = wallabag.activationScript; rompr = rompr.activationScript; shaarli = shaarli.activationScript; dokuwiki = dokuwiki.activationScript; phpbb = phpbb.activationScript; kanboard = kanboard.activationScript; }; services.websites.env.tools.watchPaths = [ config.secrets.fullPaths."webapps/tools-shaarli" ]; services.filesWatcher.phpfpm-wallabag = { restart = true; paths = [ config.secrets.fullPaths."webapps/tools-wallabag" ]; }; myServices.monitoring.fromMasterActivatedPlugins = lib.mkMerge [ ttrss.monitoringPlugins rompr.monitoringPlugins wallabag.monitoringPlugins yourls.monitoringPlugins ympd.monitoringPlugins dokuwiki.monitoringPlugins shaarli.monitoringPlugins ldap.monitoringPlugins adminer.monitoringPlugins ]; myServices.monitoring.fromMasterObjects = lib.mkMerge [ ttrss.monitoringObjects rompr.monitoringObjects wallabag.monitoringObjects yourls.monitoringObjects ympd.monitoringObjects dokuwiki.monitoringObjects shaarli.monitoringObjects ldap.monitoringObjects adminer.monitoringObjects ]; }; }