noisebridge-wiki/modules/wiki-primary/mysql.nix
Jet 642869ce9b
Some checks failed
CI / check (push) Has been cancelled
CI / deploy (push) Has been cancelled
init
2026-03-21 02:27:44 -07:00

123 lines
3.2 KiB
Nix

{
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} <<SQL
$(< ${bootstrapSql})
SQL
'';
};
systemd.services.mediawiki-init = {
after = [ "mysql-bootstrap.service" ];
requires = [ "mysql-bootstrap.service" ];
};
}