{ config, pkgs, siteConfig, ... }: let dbName = siteConfig.database.name; wikiUser = siteConfig.database.mediawikiUser; replicationUser = siteConfig.database.replicationUser; mysqlCli = "${pkgs.mariadb}/bin/mysql -u root"; bootstrapSql = pkgs.writeText "mysql-bootstrap.sql" '' SET @wiki_pass = FROM_BASE64('$wiki_pass_b64'); SET @repl_pass = FROM_BASE64('$repl_pass_b64'); CREATE DATABASE IF NOT EXISTS \`${dbName}\`; SET @create_wiki_user = CONCAT( "CREATE USER IF NOT EXISTS '${wikiUser}'@'localhost' IDENTIFIED BY ", QUOTE(@wiki_pass) ); PREPARE stmt FROM @create_wiki_user; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET @alter_wiki_user = CONCAT( "ALTER USER '${wikiUser}'@'localhost' IDENTIFIED BY ", QUOTE(@wiki_pass) ); PREPARE stmt FROM @alter_wiki_user; EXECUTE stmt; DEALLOCATE PREPARE stmt; GRANT ALL PRIVILEGES ON \`${dbName}\`.* TO '${wikiUser}'@'localhost'; SET @create_repl_user = CONCAT( "CREATE USER IF NOT EXISTS '${replicationUser}'@'%' IDENTIFIED BY ", QUOTE(@repl_pass) ); PREPARE stmt FROM @create_repl_user; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET @alter_repl_user = CONCAT( "ALTER USER '${replicationUser}'@'%' IDENTIFIED BY ", QUOTE(@repl_pass) ); PREPARE stmt FROM @alter_repl_user; EXECUTE stmt; DEALLOCATE PREPARE stmt; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO '${replicationUser}'@'%'; FLUSH PRIVILEGES; ''; in { services.mysql = { enable = true; package = pkgs.mariadb; settings.mysqld = { bind-address = "0.0.0.0"; server-id = 1; log_bin = "mysql-bin"; log_slave_updates = 1; binlog_format = "ROW"; gtid_strict_mode = 1; innodb_file_per_table = 1; innodb_buffer_pool_size = "4G"; innodb_log_file_size = "512M"; innodb_flush_method = "O_DIRECT"; innodb_flush_neighbors = 0; innodb_io_capacity = 1000; innodb_io_capacity_max = 2000; max_connections = 80; thread_cache_size = 100; table_open_cache = 4000; tmp_table_size = "64M"; max_heap_table_size = "64M"; performance_schema = true; slow_query_log = 1; long_query_time = 1; skip_name_resolve = 1; }; }; age.secrets.mysql-replication = { file = ../../secrets/mysql-replication.age; owner = "mysql"; group = "mysql"; mode = "0400"; }; systemd.services.mysql-bootstrap = { description = "Create MediaWiki database and users"; after = [ "mysql.service" ]; requires = [ "mysql.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; script = '' set -euo pipefail read_secret_b64() { tr -d '\n' < "$1" | base64 -w0 } wiki_pass_b64="$(read_secret_b64 ${config.age.secrets.mysql-mediawiki.path})" repl_pass_b64="$(read_secret_b64 ${config.age.secrets.mysql-replication.path})" ${mysqlCli} <