nixos/zabbixWeb: replace httpd subservice with new module

This commit is contained in:
Aaron Andersen 2019-07-11 18:44:51 -04:00
parent 9a4456fcc0
commit 6891fb4103
5 changed files with 230 additions and 88 deletions

View file

@ -137,9 +137,9 @@
<listitem> <listitem>
<para> <para>
Several of the apache subservices have been replaced with full NixOS Several of the apache subservices have been replaced with full NixOS
modules including LimeSurvey and WordPress. modules including LimeSurvey, WordPress, and Zabbix.
These modules can be enabled using the <option>services.limesurvey.enable</option> These modules can be enabled using the <option>services.limesurvey.enable</option>,
and <option>services.wordpress.enable</option> options. <option>services.wordpress.enable</option>, and <option>services.zabbixWeb.enable</option> options.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>

View file

@ -516,7 +516,7 @@
tss = 176; tss = 176;
#memcached = 177; # unused, removed 2018-01-03 #memcached = 177; # unused, removed 2018-01-03
#ntp = 179; # unused #ntp = 179; # unused
#zabbix = 180; # unused zabbix = 180;
#redis = 181; # unused, removed 2018-01-03 #redis = 181; # unused, removed 2018-01-03
#unifi = 183; # unused #unifi = 183; # unused
#uptimed = 184; # unused #uptimed = 184; # unused

View file

@ -782,6 +782,7 @@
./services/web-apps/virtlyst.nix ./services/web-apps/virtlyst.nix
./services/web-apps/wordpress.nix ./services/web-apps/wordpress.nix
./services/web-apps/youtrack.nix ./services/web-apps/youtrack.nix
./services/web-apps/zabbix.nix
./services/web-servers/apache-httpd/default.nix ./services/web-servers/apache-httpd/default.nix
./services/web-servers/caddy.nix ./services/web-servers/caddy.nix
./services/web-servers/fcgiwrap.nix ./services/web-servers/fcgiwrap.nix

View file

@ -0,0 +1,225 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkDefault mkEnableOption mkForce mkIf mkMerge mkOption types;
inherit (lib) literalExample mapAttrs optionalString;
cfg = config.services.zabbixWeb;
fpm = config.services.phpfpm.pools.zabbix;
user = "zabbix";
group = "zabbix";
stateDir = "/var/lib/zabbix";
zabbixConfig = pkgs.writeText "zabbix.conf.php" ''
<?php
// Zabbix GUI configuration file.
global $DB;
$DB['TYPE'] = '${ { "mysql" = "MYSQL"; "pgsql" = "POSTGRESQL"; "oracle" = "ORACLE"; }.${cfg.database.type} }';
$DB['SERVER'] = '${cfg.database.host}';
$DB['PORT'] = '${toString cfg.database.port}';
$DB['DATABASE'] = '${cfg.database.name}';
$DB['USER'] = '${cfg.database.user}';
$DB['PASSWORD'] = ${if cfg.database.passwordFile != null then "file_get_contents('${cfg.database.passwordFile}')" else "''"};
// Schema name. Used for IBM DB2 and PostgreSQL.
$DB['SCHEMA'] = ''';
$ZBX_SERVER = '${cfg.server.address}';
$ZBX_SERVER_PORT = '${toString cfg.server.port}';
$ZBX_SERVER_NAME = ''';
$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
'';
in
{
# interface
options.services = {
zabbixWeb = {
enable = mkEnableOption "the Zabbix web interface";
package = mkOption {
type = types.package;
default = pkgs.zabbix.web;
defaultText = "zabbix.web";
description = "Which Zabbix package to use.";
};
server = {
port = mkOption {
type = types.int;
description = "The port of the Zabbix server to connect to.";
default = 10051;
};
address = mkOption {
type = types.str;
description = "The IP address or hostname of the Zabbix server to connect to.";
default = "localhost";
};
};
database = {
type = mkOption {
type = types.enum [ "mysql" "pgsql" "oracle" ];
example = "mysql";
default = "pgsql";
description = "Database engine to use.";
};
host = mkOption {
type = types.str;
default = "";
description = "Database host address.";
};
port = mkOption {
type = types.int;
default =
if cfg.database.type == "mysql" then config.services.mysql.port
else if cfg.database.type == "pgsql" then config.services.postgresql.port
else 1521;
description = "Database host port.";
};
name = mkOption {
type = types.str;
default = "zabbix";
description = "Database name.";
};
user = mkOption {
type = types.str;
default = "zabbix";
description = "Database user.";
};
passwordFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/zabbix-dbpassword";
description = ''
A file containing the password corresponding to
<option>database.user</option>.
'';
};
socket = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/postgresql";
description = "Path to the unix socket file to use for authentication.";
};
};
virtualHost = mkOption {
type = types.submodule ({
options = import ../web-servers/apache-httpd/per-server-options.nix {
inherit lib;
forMainServer = false;
};
});
example = {
hostName = "zabbix.example.org";
enableSSL = true;
adminAddr = "webmaster@example.org";
sslServerCert = "/var/lib/acme/zabbix.example.org/full.pem";
sslServerKey = "/var/lib/acme/zabbix.example.org/key.pem";
};
description = ''
Apache configuration can be done by adapting <literal>services.httpd.virtualHosts.&lt;name&gt;</literal>.
See <xref linkend="opt-services.httpd.virtualHosts"/> for further information.
'';
};
poolConfig = mkOption {
type = types.lines;
default = ''
pm = dynamic
pm.max_children = 32
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500
'';
description = ''
Options for the Zabbix PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
'';
};
};
};
# implementation
config = mkIf cfg.enable {
systemd.tmpfiles.rules = [
"d '${stateDir}' 0750 ${user} ${group} - -"
"d '${stateDir}/session' 0750 ${user} ${config.services.httpd.group} - -"
];
services.phpfpm.pools.zabbix = {
phpOptions = ''
# https://www.zabbix.com/documentation/current/manual/installation/install
memory_limit = 128M
post_max_size = 16M
upload_max_filesize = 2M
max_execution_time = 300
max_input_time = 300
session.auto_start = 0
mbstring.func_overload = 0
always_populate_raw_post_data = -1
# https://bbs.archlinux.org/viewtopic.php?pid=1745214#p1745214
session.save_path = ${stateDir}/session
'' + optionalString (config.time.timeZone != null) ''
date.timezone = "${config.time.timeZone}"
'' + optionalString (cfg.database.type == "oracle") ''
extension=${pkgs.phpPackages.oci8}/lib/php/extensions/oci8.so
'';
listen = "/run/phpfpm/zabbix.sock";
extraConfig = ''
listen.owner = ${config.services.httpd.user};
listen.group = ${config.services.httpd.group};
user = ${user};
group = ${config.services.httpd.group};
env[ZABBIX_CONFIG] = ${zabbixConfig}
${cfg.poolConfig}
'';
};
services.httpd = {
enable = true;
adminAddr = mkDefault cfg.virtualHost.adminAddr;
extraModules = [ "proxy_fcgi" ];
virtualHosts = [ (mkMerge [
cfg.virtualHost {
documentRoot = mkForce "${cfg.package}/share/zabbix";
extraConfig = ''
<Directory "${cfg.package}/share/zabbix">
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:unix:${fpm.listen}|fcgi://localhost/"
</If>
</FilesMatch>
AllowOverride all
Options -Indexes
DirectoryIndex index.php
</Directory>
'';
}
]) ];
};
users.users.${user} = mapAttrs (name: mkDefault) {
description = "Zabbix daemon user";
uid = config.ids.uids.zabbix;
inherit group;
};
users.groups.${group} = mapAttrs (name: mkDefault) {
gid = config.ids.gids.zabbix;
};
};
}

View file

@ -1,84 +0,0 @@
{ config, lib, pkgs, serverInfo, ... }:
with lib;
let
# The Zabbix PHP frontend needs to be able to write its
# configuration settings (the connection info to the database) to
# the "conf" subdirectory. So symlink $out/conf to some directory
# outside of the Nix store where we want to keep this stateful info.
# Note that different instances of the frontend will therefore end
# up with their own copies of the PHP sources. !!! Alternatively,
# we could generate zabbix.conf.php declaratively.
zabbixPHP = pkgs.runCommand "${pkgs.zabbix.server.name}-php" {}
''
cp -rs ${pkgs.zabbix.server}/share/zabbix/php "$out"
chmod -R u+w $out
ln -s "${if config.configFile == null
then "${config.stateDir}/zabbix.conf.php"
else config.configFile}" "$out/conf/zabbix.conf.php"
'';
in
{
enablePHP = true;
phpOptions =
''
post_max_size = 32M
max_execution_time = 300
max_input_time = 300
'';
extraConfig = ''
Alias ${config.urlPrefix}/ ${zabbixPHP}/
<Directory ${zabbixPHP}>
DirectoryIndex index.php
Order deny,allow
Allow from *
</Directory>
'';
startupScript = pkgs.writeScript "zabbix-startup-hook" ''
mkdir -p ${config.stateDir}
chown -R ${serverInfo.serverConfig.user} ${config.stateDir}
'';
# The frontend needs "ps" to find out whether zabbix_server is running.
extraServerPath = [ pkgs.procps ];
options = {
urlPrefix = mkOption {
default = "/zabbix";
description = "
The URL prefix under which the Zabbix service appears.
Use the empty string to have it appear in the server root.
";
};
configFile = mkOption {
default = null;
type = types.nullOr types.path;
description = ''
The configuration file (zabbix.conf.php) which contains the database
connection settings. If not set, the configuration settings will created
by the web installer.
'';
};
stateDir = mkOption {
default = "/var/lib/zabbix/frontend";
description = "
Directory where the dynamically generated configuration data
of the PHP frontend will be stored.
";
};
};
}