NixOS configurations for server and desktop systems, including user specific config using Home Manager https://nixos.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

459 lines
13 KiB

{ config, pkgs, lib, ... }:
let
pubkey = import ../../services/pubkey.nix;
secrets = import ./secrets.nix;
in
{
imports =
[
/etc/nixos/hardware-configuration.nix
../../profiles/server.nix
../../modules/satzgenerator.nix
../../services/drone-runner
];
boot.loader.grub.device = "/dev/sda";
boot.kernel.sysctl = {
# recommended by mysqltuner
"vm.swappiness" = 10;
"fs.aio-max-nr" = 1048576;
};
networking = rec {
# hostname from mnemonic encoding word list
# http://web.archive.org/web/20091003023412/http://tothink.com/mnemonic/wordlist.txt
# you could also consider one of these lists https://namingschemes.com/
hostName = "atomic";
domain = "davidak.de";
interfaces = {
ens3.ipv4.addresses = [
# external 138.201.246.37
{ address = "172.31.1.100"; prefixLength = 24; }
];
ens3.ipv6.addresses = [
# davidak
{ address = "2a01:04f8:0c17:5c0e::1"; prefixLength = 64; }
# aquaregia
{ address = "2a01:04f8:0c17:5c0e::2"; prefixLength = 64; }
# brennblatt
{ address = "2a01:04f8:0c17:5c0e::4"; prefixLength = 64; }
# meinsack
{ address = "2a01:04f8:0c17:5c0e::8"; prefixLength = 64; }
# kf
{ address = "2a01:04f8:0c17:5c0e::16"; prefixLength = 64; }
# satzgenerator
{ address = "2a01:04f8:0c17:5c0e::32"; prefixLength = 64; }
# chan
{ address = "2a01:04f8:0c17:5c0e::64"; prefixLength = 64; }
# gutesoftware
{ address = "2a01:04f8:0c17:5c0e::128"; prefixLength = 64; }
];
};
nameservers = [ "213.133.99.99" "213.133.98.98" "213.133.100.100" ];
defaultGateway = { address = "172.31.1.1"; interface = "ens3"; };
defaultGateway6 = { address = "fe80::1"; interface = "ens3"; };
firewall = {
enable = true;
allowPing = true;
allowedTCPPorts = [ 80 443 19999 64738 ];
allowedUDPPorts = [];
};
useDHCP = false;
};
# Monitoring
services.netdata = {
enable = true;
config = {
global = {
"default port" = "19999";
"bind to" = "*";
"memory mode" = "dbengine";
"page cache size" = "64";
"dbengine disk space" = "512";
"error log" = "syslog";
"debug log" = "syslog";
};
};
};
systemd.enableCgroupAccounting = true;
services.vnstat.enable = true;
# MariaDB
services.mysql = {
enable = true;
package = pkgs.mariadb;
bind = "127.0.0.1";
settings = {
mysqld = {
query_cache_type = 1;
query_cache_limit = "2M";
query_cache_size = "4M";
thread_cache_size = 4;
innodb_buffer_pool_size = "325M";
innodb_buffer_pool_instances = 1;
# smallest value since it's not used
aria_pagecache_buffer_size = "128K";
# values should be equal
tmp_table_size = "30M";
max_heap_table_size = "30M";
};
};
};
services.mysqlBackup = {
enable = true;
databases = [ "mysql" "piwik" "satzgenerator" ];
user = "root";
calendar = "04:00:00";
singleTransaction = true;
};
# Create webspaces and users
system.activationScripts.create-varwww = "mkdir -p -m 0755 /var/www";
users.mutableUsers = false;
users.extraUsers = lib.genAttrs [
"aquaregia"
"aww"
"brennblatt"
"chan"
"davidak"
"default"
"gnaclan"
"kf"
"meinsack"
"personen"
"piwik"
"gutesoftware"
] (user: {
isNormalUser = true;
home = "/var/www/${user}";
openssh.authorizedKeys.keys = [ pubkey.davidak ];
});
system.activationScripts.webspace = "for dir in /var/www/*/; do chmod 0755 \${dir}; mkdir -p -m 0755 \${dir}/{web,log}; chown \$(stat -c \"%U:%G\" \${dir}) \${dir}/web; chown caddy:users \${dir}/log; done";
system.activationScripts.default-site = "touch /var/www/default/web/index.html";
# PHP-FPM
services.phpfpm = {
#phpPackage = pkgs.php56;
phpOptions =
''
date.timezone = "Europe/Berlin"
;memory_limit = 256M
;max_execution_time = 60
zend_extension = ${pkgs.php}/lib/php/extensions/opcache.so
opcache.enable = 1
opcache.memory_consumption = 64
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.max_wasted_percentage = 5
opcache.use_cwd = 1
opcache.validate_timestamps = 1
opcache.revalidate_freq = 2
opcache.fast_shutdown = 1
'';
pools = {
piwik = {
user = "piwik";
group = "users";
settings = {
"listen.owner" = "caddy";
"listen.group" = "caddy";
"listen.mode" = "0660";
"pm" = "dynamic";
"pm.max_children" = "10";
"pm.start_servers" = "2";
"pm.min_spare_servers" = "1";
"pm.max_spare_servers" = "3";
"pm.max_requests" = "500";
"php_admin_value[always_populate_raw_post_data]" = "-1";
};
};
gnaclan = {
user = "gnaclan";
group = "users";
settings = {
"listen.owner" = "caddy";
"listen.group" = "caddy";
"listen.mode" = "0660";
"pm" = "dynamic";
"pm.max_children" = "10";
"pm.start_servers" = "2";
"pm.min_spare_servers" = "1";
"pm.max_spare_servers" = "3";
"pm.max_requests" = "500";
};
};
chan = {
user = "chan";
group = "users";
settings = {
"listen.owner" = "caddy";
"listen.group" = "caddy";
"listen.mode" = "0660";
"pm" = "dynamic";
"pm.max_children" = "10";
"pm.start_servers" = "2";
"pm.min_spare_servers" = "1";
"pm.max_spare_servers" = "3";
"pm.max_requests" = "500";
};
};
};
};
# Caddy Webserver
services.caddy = {
enable = true;
email = "post@davidak.de";
config = ''
satzgenerator.net www.satzgenerator.net www.satzgenerator.de {
redir https://satzgenerator.de{uri}
}
satzgenerator.de {
reverse_proxy ${config.services.satzgenerator.bind}
}
ci.gutesoftware.de {
reverse_proxy 127.0.0.1:8080
}
s3.gutesoftware.de {
reverse_proxy 127.0.0.1:9000
}
www.aquaregia.de {
redir https://aquaregia.de{uri}
}
aquaregia.de {
file_server
root * /var/www/aquaregia/web/
encode gzip
}
aww.davidak.de {
file_server
root * /var/www/aww/web
encode gzip
}
www.brennblatt.de {
redir https://brennblatt.de{uri}
}
brennblatt.de {
file_server
root * /var/www/brennblatt/web/
encode gzip
}
# Does not work https://github.com/NixOS/nixpkgs/issues/113534
#import /var/www/davidak/web/Caddyfile
www.davidak.de {
redir https://davidak.de{uri}
}
davidak.de {
file_server
root * /var/www/davidak/web/
encode gzip
handle_path /personen/* {
root * /var/www/personen/web/
}
handle_path /stats/* {
root * /var/www/piwik/web/
respond /config/* "Access denied" 403 {
close
}
php_fastcgi unix//run/phpfpm/piwik.sock
header /piwik.js Cache-Control max-age=2592000
}
# Redirect old URLs
redir /blog/wp-content/uploads/2010/12/Bildschirmfoto-2010-12-14-um-19.47.29-1024x640.png /images/celtx_auf_osx_wortspiele_polysemia.thumbnail.png permanent
redir /blog/wp-content/uploads/2010/12/Bildschirmfoto-2010-12-14-um-19.47.29.png /images/celtx_auf_osx_wortspiele_polysemia.png permanent
redir /fotos https://www.flickr.com/photos/davidak permanent
redir /blog/feed /rss.xml permanent
redir /blog/feed/ /rss.xml permanent
redir /wiki/python/satzgenerator https://github.com/davidak/satzgenerator permanent
redir /wiki/sonstiges/towerdefense-flash /towerdefense-flashgames/ permanent
redir /wiki/html/javaprojects /javaprojects-html-template/ permanent
redir /wiki/batch/shutdown-virus /shutdown-virus/ permanent
redir /wiki/batch/fork /batch-forkbomb/ permanent
redir /wiki/batch/counter /batch-counter/ permanent
redir /wiki/batch/crrafooyouh /crrafooyouh/ permanent
redir /wiki/java/sprechstunde /java-sprechstunde/ permanent
redir /wiki/java/photoshop-game /photoshop-text-game/ permanent
redir /wiki/java/anno-1203-game /anno-1203-textbasiertes-aufbau-simulations-spiel/ permanent
redir /wiki/perl/zerorandom /perl-zerorandom/ permanent
redir /wiki/perl/namengenerator /perl-namengenerator/ permanent
redir /wiki/perl/satzgenerator https://github.com/davidak/satzgenerator permanent
redir /wiki/perl/personendatengenerator /perl-personendatengenerator/ permanent
redir /wiki/java/rtfm /java-rtfm-random-text-file-maker/ permanent
redir /wiki/perl/counter /perl-counter/ permanent
redir /wiki/bitcoin /bitcoin/ permanent
redir /wiki/python/unterschiedliche-zufallswerte /python-unterschiedliche-zufallswerte/ permanent
redir /wiki/perl/rss-feed /perl-rss-feed/ permanent
redir /wiki/python/vcard-generator https://github.com/davidak/random-vcard-generator permanent
redir /wiki/anleitung/debian7-debootstrap /debian7-debootstrap/ permanent
redir /wiki/anleitung/windows-xp-automatisch-anmelden /windows-xp-automatisch-anmelden/ permanent
redir /wiki/anleitung/sophos-antivirus-client-enterprise-console /sophos-antivirus-client-enterprise-console/ permanent
redir /wiki/dokument/cpu-referat-praesentation-ausarbeitung-download /cpu-referat-praesentation-ausarbeitung-download/ permanent
redir /wiki/dokument/real-kassenzettel-reverse-engeneering /real-kassenzettel-reverse-engeneering/ permanent
redir /wiki/dokument/real-pfandgutschein-reverse-engeneering /real-pfandgutschein-reverse-engeneering/ permanent
redir /wiki/anleitung/wartezimmer /blog/wartezimmer/ permanent
}
stats.davidak.de {
file_server
root * /var/www/piwik/web/
encode gzip
respond /config/* "Access denied" 403 {
close
}
php_fastcgi unix//run/phpfpm/piwik.sock
header /piwik.js Cache-Control max-age=2592000
}
www.gutesoftware.de {
redir https://gutesoftware.de{uri}
}
gutesoftware.de {
file_server
root * /var/www/gutesoftware/web/
encode gzip
}
www.kaltefiste.net {
redir https://kaltefiste.net{uri}
}
kaltefiste.net {
file_server
root * /var/www/kf/web/
encode gzip
# Redirect to specific language
@lang_de {
header Accept-Language *de-DE*
}
@lang_not_de {
not header Accept-Language *de-DE*
}
route / {
redir @lang_de /de
redir @lang_not_de /en
}
}
www.meinsack.org {
redir https://meinsack.org{uri}
}
meinsack.org {
file_server
root * /var/www/meinsack/web/
encode gzip
}
'';
};
services.satzgenerator = {
enable = true;
bind = "127.0.0.1:8000";
workers = 5;
database = {
host = "127.0.0.1";
user = secrets.satzgenerator_mysql_user;
password = secrets.satzgenerator_mysql_password;
name = "satzgenerator";
};
};
# Cron
services.cron = {
enable = true;
mailto = "root";
systemCronJobs = [
"5 * * * * piwik ${pkgs.php}/bin/php /var/www/piwik/web/console core:archive --url=https://davidak.de/stats/ > /var/www/piwik/piwik-archive.log"
];
};
services.murmur = {
enable = true;
clientCertRequired = true;
hostName = "172.31.1.100 2a01:04f8:0c17:5c0e::1";
registerName = "Knochtensprech";
registerHostname = "davidak.de";
welcometext = "Willkommen auf unserem Mumble-Server!";
bandwidth = 128000;
};
virtualisation.oci-containers.containers = {
drone-server = {
image = "drone/drone:1";
ports = [ "127.0.0.1:8080:80" ];
volumes = [ "/var/lib/drone:/data" ];
environment = {
DRONE_SERVER_HOST = "ci.gutesoftware.de";
DRONE_SERVER_PROTO = "https";
DRONE_JSONNET_ENABLED = "true";
DRONE_GITEA_SERVER = "https://codeberg.org";
DRONE_GITEA_CLIENT_ID = secrets.DRONE_GITEA_CLIENT_ID;
DRONE_GITEA_CLIENT_SECRET = secrets.DRONE_GITEA_CLIENT_SECRET;
DRONE_RPC_SECRET = secrets.DRONE_RPC_SECRET;
DRONE_USER_CREATE = "username:davidak,admin:true";
DRONE_S3_ENDPOINT = "https://s3.gutesoftware.de";
DRONE_S3_PATH_STYLE = "true";
DRONE_S3_BUCKET = "drone";
AWS_ACCESS_KEY_ID = secrets.S3_ACCESS_KEY_ID;
AWS_SECRET_ACCESS_KEY = secrets.S3_SECRET_ACCESS_KEY;
AWS_DEFAULT_REGION = config.services.minio.region;
AWS_REGION = config.services.minio.region;
};
};
drone-runner = {
# ... (imported above)
dependsOn = [ "drone-server" ];
};
};
# S3 compatible Object Storage
services.minio = {
enable = true;
listenAddress = "127.0.0.1:9000";
accessKey = secrets.S3_ACCESS_KEY_ID;
secretKey = secrets.S3_SECRET_ACCESS_KEY;
region = "eu-central-1";
};
# Packages
environment.systemPackages = with pkgs; [ vnstat php ];
# The NixOS release to be compatible with for stateful data such as databases.
system.stateVersion = "18.03";
}