./modules/gitweb.nix
./modules/databases.nix
./modules/websites
+ ./modules/websites/phpfpm
];
services.myGitolite.enable = true;
services.myGitweb.enable = true;
cd ${mypkgs.nextcloud.webRoot}
NEXTCLOUD_CONFIG_DIR="${mypkgs.nextcloud.webRoot}/config" \
exec \
- ${config.services.phpfpm.phpPackage}/bin/php \
- -c ${config.services.phpfpm.phpPackage}/etc/php.ini \
+ ${pkgs.php}/bin/php \
+ -c ${pkgs.php}/etc/php.ini \
occ $*
'';
in [
services.ympd = mypkgs.ympd.config // { enable = false; };
- services.phpfpm = {
- # FIXME: move session files to separate dirs
- # /!\ phppackage is used in nextcloud configuation
+ services.myPhpfpm = {
+ phpPackage = pkgs.php;
phpOptions = ''
session.save_path = "/var/lib/php/sessions"
session.gc_maxlifetime = 60*60*24*15
session.cache_expire = 60*24*30
- ; For nextcloud
- extension=${pkgs.phpPackages.redis}/lib/php/extensions/redis.so
- ; For nextcloud
- extension=${pkgs.phpPackages.apcu}/lib/php/extensions/apcu.so
- ; For nextcloud
- zend_extension=${pkgs.php}/lib/php/extensions/opcache.so
'';
extraConfig = ''
log_level = notice
'';
+ poolPhpConfigs = {
+ nextcloud = mypkgs.nextcloud.phpFpm.phpConfig;
+ };
poolConfigs = {
adminer = mypkgs.adminer.phpFpm.pool;
nextcloud = mypkgs.nextcloud.phpFpm.pool;
};
};
- services.phpfpm.poolConfigs.aten_prod = aten_prod.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.aten_prod = aten_prod.phpFpm.pool;
system.activationScripts.aten_prod = aten_prod.activationScript;
services.myWebsites.apacheConfig.aten_prod.modules = aten_prod.apache.modules;
services.myWebsites.production.modules = aten_prod.apache.modules;
})
(lib.mkIf cfg.integration.enable {
security.acme.certs."eldiron".extraDomains."dev.aten.pro" = null;
- services.phpfpm.poolConfigs.aten_dev = aten_dev.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.aten_dev = aten_dev.phpFpm.pool;
system.activationScripts.aten_dev = aten_dev.activationScript;
services.myWebsites.integration.modules = aten_dev.apache.modules;
services.myWebsites.integration.vhostConfs.aten = {
};
};
- services.phpfpm.poolConfigs.chloe_prod = chloe_prod.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.chloe_prod = chloe_prod.phpFpm.pool;
system.activationScripts.chloe_prod = chloe_prod.activationScript;
services.myWebsites.production.modules = chloe_prod.apache.modules;
services.myWebsites.production.vhostConfs.chloe = {
})
(lib.mkIf cfg.integration.enable {
security.acme.certs."eldiron".extraDomains."chloe.immae.eu" = null;
- services.phpfpm.poolConfigs.chloe_dev = chloe_dev.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.chloe_dev = chloe_dev.phpFpm.pool;
system.activationScripts.chloe_dev = chloe_dev.activationScript;
services.myWebsites.integration.modules = chloe_dev.apache.modules;
services.myWebsites.integration.vhostConfs.chloe = {
};
};
- services.phpfpm.poolConfigs.connexionswing_prod = connexionswing_prod.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.connexionswing_prod = connexionswing_prod.phpFpm.pool;
system.activationScripts.connexionswing_prod = connexionswing_prod.activationScript;
services.myWebsites.production.modules = connexionswing_prod.apache.modules;
services.myWebsites.production.vhostConfs.connexionswing = {
(lib.mkIf cfg.integration.enable {
security.acme.certs."eldiron".extraDomains."sandetludo.immae.eu" = null;
security.acme.certs."eldiron".extraDomains."connexionswing.immae.eu" = null;
- services.phpfpm.poolConfigs.connexionswing_dev = connexionswing_dev.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.connexionswing_dev = connexionswing_dev.phpFpm.pool;
system.activationScripts.connexionswing_dev = connexionswing_dev.activationScript;
services.myWebsites.integration.modules = connexionswing_dev.apache.modules;
services.myWebsites.integration.vhostConfs.connexionswing = {
];
};
+ nixpkgs.config.packageOverrides = oldpkgs: rec {
+ php = php72;
+ php72 = (oldpkgs.php72.override {
+ mysql.connector-c = pkgs.mariadb;
+ config.php.mysqlnd = false;
+ config.php.mysqli = false;
+ }).overrideAttrs(old: rec {
+ # Didn't manage to build with mysqli + mysql_config connector
+ configureFlags = old.configureFlags ++ [
+ "--with-mysqli=mysqlnd"
+ ];
+ # preConfigure = (old.preConfigure or "") + ''
+ # export CPPFLAGS="$CPPFLAGS -I${pkgs.mariadb}/include/mysql/server";
+ # sed -i -e 's/#include "mysqli_priv.h"/#include "mysqli_priv.h"\n#include <mysql_version.h>/' \
+ # ext/mysqli/mysqli.c ext/mysqli/mysqli_prop.c
+ # '';
+ });
+ phpPackages = oldpkgs.php72Packages.override { inherit php; };
+ };
+
services.myWebsites.Chloe.production.enable = cfg.production.enable;
services.myWebsites.Ludivine.production.enable = cfg.production.enable;
services.myWebsites.Aten.production.enable = cfg.production.enable;
};
};
- services.phpfpm.poolConfigs.ludivinecassal_prod = ludivinecassal_prod.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.ludivinecassal_prod = ludivinecassal_prod.phpFpm.pool;
system.activationScripts.ludivinecassal_prod = ludivinecassal_prod.activationScript;
services.myWebsites.production.modules = ludivinecassal_prod.apache.modules;
services.myWebsites.production.vhostConfs.ludivine = {
(lib.mkIf cfg.integration.enable {
security.acme.certs."eldiron".extraDomains."ludivine.immae.eu" = null;
- services.phpfpm.poolConfigs.ludivinecassal_dev = ludivinecassal_dev.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.ludivinecassal_dev = ludivinecassal_dev.phpFpm.pool;
system.activationScripts.ludivinecassal_dev = ludivinecassal_dev.activationScript;
services.myWebsites.apacheConfig.ludivinecassal_dev.modules = ludivinecassal_dev.apache.modules;
services.myWebsites.integration.modules = ludivinecassal_dev.apache.modules;
--- /dev/null
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.myPhpfpm;
+ enabled = cfg.poolConfigs != {} || cfg.pools != {};
+
+ stateDir = "/run/phpfpm";
+
+ poolConfigs = cfg.poolConfigs // mapAttrs mkPool cfg.pools;
+
+ mkPool = n: p: ''
+ listen = ${p.listen}
+ ${p.extraConfig}
+ '';
+
+ fpmCfgFile = pool: poolConfig: pkgs.writeText "phpfpm-${pool}.conf" ''
+ [global]
+ error_log = syslog
+ daemonize = no
+ ${cfg.extraConfig}
+
+ [${pool}]
+ ${poolConfig}
+ '';
+
+ phpIni = poolPhpOptions: (pkgs.runCommand "php.ini" {
+ inherit (cfg) phpPackage phpOptions;
+ inherit poolPhpOptions;
+ nixDefaults = ''
+ sendmail_path = "/run/wrappers/bin/sendmail -t -i"
+ '';
+ passAsFile = [ "nixDefaults" "phpOptions" "poolPhpOptions" ];
+ } ''
+ cat $phpPackage/etc/php.ini $nixDefaultsPath $phpOptionsPath $poolPhpOptionsPath > $out
+ '');
+
+in {
+
+ options = {
+ services.myPhpfpm = {
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Extra configuration that should be put in the global section of
+ the PHP-FPM configuration file. Do not specify the options
+ <literal>error_log</literal> or
+ <literal>daemonize</literal> here, since they are generated by
+ NixOS.
+ '';
+ };
+
+ phpPackage = mkOption {
+ type = types.package;
+ default = pkgs.php;
+ defaultText = "pkgs.php";
+ description = ''
+ The PHP package to use for running the PHP-FPM service.
+ '';
+ };
+
+ phpOptions = mkOption {
+ type = types.lines;
+ default = "";
+ example =
+ ''
+ date.timezone = "CET"
+ '';
+ description =
+ "Options appended to the PHP configuration file <filename>php.ini</filename>.";
+ };
+
+ poolPhpConfigs = mkOption {
+ default = {};
+ type = types.attrsOf types.lines;
+ example = literalExample ''
+ { mypool = '''
+ extension = some_extension.so
+ ''';
+ }
+ '';
+ description = ''
+ Extra lines that go into the php configuration specific to pool.
+ '';
+ };
+
+ poolConfigs = mkOption {
+ default = {};
+ type = types.attrsOf types.lines;
+ example = literalExample ''
+ { mypool = '''
+ listen = /run/phpfpm/mypool
+ user = nobody
+ pm = dynamic
+ pm.max_children = 75
+ pm.start_servers = 10
+ pm.min_spare_servers = 5
+ pm.max_spare_servers = 20
+ pm.max_requests = 500
+ ''';
+ }
+ '';
+ description = ''
+ A mapping between PHP-FPM pool names and their configurations.
+ See the documentation on <literal>php-fpm.conf</literal> for
+ details on configuration directives. If no pools are defined,
+ the phpfpm service is disabled.
+ '';
+ };
+
+ pools = mkOption {
+ type = types.attrsOf (types.submodule (import ./pool-options.nix {
+ inherit lib;
+ }));
+ default = {};
+ example = literalExample ''
+ {
+ mypool = {
+ listen = "/path/to/unix/socket";
+ extraConfig = '''
+ user = nobody
+ pm = dynamic
+ pm.max_children = 75
+ pm.start_servers = 10
+ pm.min_spare_servers = 5
+ pm.max_spare_servers = 20
+ pm.max_requests = 500
+ ''';
+ }
+ }'';
+ description = ''
+ PHP-FPM pools. If no pools or poolConfigs are defined, the PHP-FPM
+ service is disabled.
+ '';
+ };
+ };
+ };
+
+ config = mkIf enabled {
+
+ systemd.slices.phpfpm = {
+ description = "PHP FastCGI Process manager pools slice";
+ };
+
+ systemd.targets.phpfpm = {
+ description = "PHP FastCGI Process manager pools target";
+ wantedBy = [ "multi-user.target" ];
+ };
+
+ systemd.services = flip mapAttrs' poolConfigs (pool: poolConfig:
+ nameValuePair "phpfpm-${pool}" {
+ description = "PHP FastCGI Process Manager service for pool ${pool}";
+ after = [ "network.target" ];
+ wantedBy = [ "phpfpm.target" ];
+ partOf = [ "phpfpm.target" ];
+ preStart = ''
+ mkdir -p ${stateDir}
+ '';
+ serviceConfig = let
+ cfgFile = fpmCfgFile pool poolConfig;
+ poolPhpIni = cfg.poolPhpConfigs.${pool} or "";
+ in {
+ Slice = "phpfpm.slice";
+ PrivateDevices = true;
+ ProtectSystem = "full";
+ ProtectHome = true;
+ # XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work
+ RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK";
+ Type = "notify";
+ ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni poolPhpIni}";
+ ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
+ };
+ }
+ );
+ };
+}
--- /dev/null
+{ lib }:
+
+with lib; {
+
+ options = {
+
+ listen = mkOption {
+ type = types.str;
+ example = "/path/to/unix/socket";
+ description = ''
+ The address on which to accept FastCGI requests.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ example = ''
+ user = nobody
+ pm = dynamic
+ pm.max_children = 75
+ pm.start_servers = 10
+ pm.min_spare_servers = 5
+ pm.max_spare_servers = 20
+ pm.max_requests = 500
+ '';
+
+ description = ''
+ Extra lines that go into the pool configuration.
+ See the documentation on <literal>php-fpm.conf</literal> for
+ details on configuration directives.
+ '';
+ };
+ };
+}
+
};
};
- services.phpfpm.poolConfigs.piedsjaloux_prod = piedsjaloux_prod.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.piedsjaloux_prod = piedsjaloux_prod.phpFpm.pool;
system.activationScripts.piedsjaloux_prod = piedsjaloux_prod.activationScript;
services.myWebsites.production.modules = piedsjaloux_prod.apache.modules;
services.myWebsites.production.vhostConfs.piedsjaloux = {
})
(lib.mkIf cfg.integration.enable {
security.acme.certs."eldiron".extraDomains."piedsjaloux.immae.eu" = null;
- services.phpfpm.poolConfigs.piedsjaloux_dev = piedsjaloux_dev.phpFpm.pool;
+ services.myPhpfpm.poolConfigs.piedsjaloux_dev = piedsjaloux_dev.phpFpm.pool;
system.activationScripts.piedsjaloux_dev = piedsjaloux_dev.activationScript;
services.myWebsites.integration.modules = piedsjaloux_dev.apache.modules;
services.myWebsites.integration.vhostConfs.piedsjaloux = {
-{ stdenv, fetchurl, checkEnv, writeText, lib }:
+{ stdenv, fetchurl, checkEnv, writeText, lib, phpPackages, php }:
let
nextcloud = let
# FIXME: initial sync
[ webRoot varDir config ]
++ lib.attrsets.mapAttrsToList (name: value: value) apps);
socket = "/var/run/phpfpm/nextcloud.sock";
+ phpConfig = ''
+ extension=${phpPackages.redis}/lib/php/extensions/redis.so
+ extension=${phpPackages.apcu}/lib/php/extensions/apcu.so
+ zend_extension=${php}/lib/php/extensions/opcache.so
+ '';
pool = ''
listen = ${socket}
user = ${apache.user}