{ config, pkgs, ... }: let envsubstConfiguration = { TLD = "$TLD"; nextcloudTLD = "$NEXTCLOUD_TLD"; gitTLD = "$GIT_TLD"; prosodyTLD = "$PROSODY_TLD"; bonecoTLD = "$BONECO_TLD"; pdfsTLD = "$PDFS_TLD"; songbooksDocumentationTLD = "$SONGBOOKS_DOCUMENTATION_TLD"; letsencryptEmail = "$LETSENCRYPT_EMAIL"; authorizedKey = "$AUTHORIZED_KEY"; userPassword = "$USER_PASSWORD"; userName = "$USER_NAME"; dataRoot = "$DATA_ROOT"; staticRoot = "$STATIC_ROOT"; faviconsRoot = "$FAVICONS_ROOT"; nextcloudDatabaseUser = "$NEXTCLOUD_DATABASE_USER"; nextcloudDatabasePassword = "$NEXTCLOUD_DATABASE_PASSWORD"; nextcloudAdminUser = "$NEXTCLOUD_ADMIN_USER"; nextcloudAdminPassword = "$NEXTCLOUD_ADMIN_PASSWORD"; nextcloudTablePrefix = "$NEXTCLOUD_TABLE_PREFIX"; gitPort = "$GIT_PORT"; gitRoot = "$GIT_ROOT"; systemStateVersion = "$SYSTEM_STATE_VERSION"; prosodyAdminUser = "$PROSODY_ADMIN_USER"; prosodyMUCTLD = "$PROSODY_MUC_TLD"; prosodyPort = "$PROSODY_PORT"; prosodyHTTPPort = "$PROSODY_HTTP_PORT"; matterbridgeWhatsappNumber = "$MATTERBRIDGE_WHATSAPP_NUMBER"; matterbridgeBotJID = "$MATTERBRIDGE_BOT_JID"; matterbridgeBotPassword = "$MATTERBRIDGE_BOT_PASSWORD"; matterbridgeBotNick = "$MATTERBRIDGE_BOT_NICK"; matterbridgeMUCServer = "$MATTERBRIDGE_MUC_SERVER"; matterbridgeXMPPServer = "$MATTERBRIDGE_XMPP_SERVER"; matterbridgeXMPPChannel = "$MATTERBRIDGE_XMPP_CHANNEL"; }; staticSiteFromRepo = repoName: pkgs.stdenv.mkDerivation { name = repoName; src = fetchTarball "https://git.sr.ht/~euandreh/${DOLLAR}{repoName}/archive/master.tar.gz"; phases = "unpackPhase buildPhase"; buildPhase = '' mkdir ${DOLLAR}out cp index.html ${DOLLAR}out cp favicon.ico ${DOLLAR}out ''; }; in { imports = [ ./hardware-configuration.nix ]; boot.loader.grub = { enable = true; version = 2; device = "/dev/vda"; }; networking = { useDHCP = false; interfaces.ens3.useDHCP = true; }; environment.systemPackages = with pkgs; [ vim git gitAndTools.git-annex gotop ]; networking.firewall.allowedTCPPorts = [ # SSH: OpenSSH 22 # HTTP and HTPPS: NGINX 80 443 # XMPP: Prosody # https://prosody.im/doc/ports 5000 5222 5269 5280 5281 5347 5582 ]; security.acme = { acceptTerms = true; email = envsubstConfiguration.letsencryptEmail; }; services = { openssh = { enable = true; permitRootLogin = "no"; passwordAuthentication = false; }; nginx = { enable = true; recommendedGzipSettings = true; recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; virtualHosts = { "${envsubstConfiguration.nextcloudTLD}" = { forceSSL = true; enableACME = true; }; "${envsubstConfiguration.gitTLD}" = { forceSSL = true; enableACME = true; extraConfig = '' location = /favicon.ico { alias ${envsubstConfiguration.dataRoot}/favicons/git.ico; } location / { proxy_pass http://localhost:${envsubstConfiguration.gitPort}; } ''; }; "${envsubstConfiguration.bonecoTLD}" = { forceSSL = true; enableACME = true; root = staticSiteFromRepo "boneco"; }; "${envsubstConfiguration.pdfsTLD}" = { forceSSL = true; enableACME = true; root = staticSiteFromRepo "pdfs-da-d-maria"; }; "${envsubstConfiguration.songbooksDocumentationTLD}" = { forceSSL = true; enableACME = true; extraConfig = '' location = / { return 301 master/; } root ${envsubstConfiguration.staticRoot}/songbooks/; ''; }; "${envsubstConfiguration.prosodyTLD}" = { forceSSL = true; enableACME = true; serverAliases = [ envsubstConfiguration.prosodyMUCTLD ]; extraConfig = '' location = /favicon.ico { alias ${envsubstConfiguration.dataRoot}/favicons/conversejs.ico; } location / { proxy_pass http://localhost:${envsubstConfiguration.prosodyHTTPPort}/conversejs; } ''; }; }; }; postgresql = { enable = true; ensureDatabases = [ "nextcloud" ]; package = pkgs.postgresql_11; ensureUsers = [{ name = "nextcloud"; ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; }]; }; nextcloud = { enable = true; package = pkgs.nextcloud19; nginx.enable = true; hostName = envsubstConfiguration.nextcloudTLD; https = true; maxUploadSize = "4G"; autoUpdateApps.enable = true; config = { overwriteProtocol = "https"; dbtype = "pgsql"; dbhost = "/run/postgresql"; dbuser = envsubstConfiguration.nextcloudDatabaseUser; dbpass = envsubstConfiguration.nextcloudDatabasePassword; dbtableprefix = envsubstConfiguration.nextcloudTablePrefix; adminuser = envsubstConfiguration.nextcloudAdminUser; adminpass = envsubstConfiguration.nextcloudAdminPassword; }; }; prosody = let fullchainPEM = "/var/lib/acme/${envsubstConfiguration.prosodyTLD}/fullchain.pem"; keyPEM = "/var/lib/acme/${envsubstConfiguration.prosodyTLD}/key.pem"; in { enable = true; admins = [ envsubstConfiguration.prosodyAdminUser ]; allowRegistration = false; modules = { websocket = true; }; package = pkgs.prosody.override { withCommunityModules = [ "http_upload" "conversejs" "bookmarks" ]; }; extraModules = [ "http_upload" "conversejs" "bookmarks" ]; ssl = { cert = fullchainPEM; key = keyPEM; }; virtualHosts = { "${envsubstConfiguration.prosodyTLD}" = { enabled = true; domain = "${envsubstConfiguration.prosodyTLD}"; ssl = { cert = fullchainPEM; key = keyPEM; }; }; }; }; matterbridge = { enable = false; configFile = '' [whatsapp.mywhatsapp] Number="${envsubstConfiguration.matterbridgeWhatsappNumber}" RemoteNickFormat="[{PROTOCOL}] @<{NICK}>:" [xmpp.myxmpp] Server="${envsubstConfiguration.matterbridgeXMPPServer}" Jid="${envsubstConfiguration.matterbridgeBotJID}" Password="${envsubstConfiguration.matterbridgeBotPassword}" Muc="${envsubstConfiguration.matterbridgeMUCServer}" Nick="${envsubstConfiguration.matterbridgeBotNick}" RemoteNickFormat="[{PROTOCOL}] <{NICK}>" [[gateway]] name="gateway1" enable=true [[gateway.inout]] account="whatsapp.mywhatsapp" channel="dunno" [[gateway.inout]] account="xmpp.myxmpp" channel="${envsubstConfiguration.matterbridgeXMPPChannel}" ''; }; lighttpd = { enable = true; port = pkgs.lib.toInt envsubstConfiguration.gitPort; cgit = { enable = true; subdir = ""; configText = '' enable-blame=1 enable-commit-graph=1 enable-follow-links=1 enable-index-owner=0 enable-log-filecount=1 enable-log-linecount=1 max-repodesc-length=120 repo.readme=:README.md remove-suffix=1 root-title=EuAndreh's git repositories snapshots=tar.gz zip source-filter=${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py about-filter=${pkgs.cgit}/lib/cgit/filters/about-formatting.sh scan-path=${envsubstConfiguration.gitRoot} ''; }; }; }; systemd.services = { "nextcloud-setup" = { requires = [ "postgresql.service" ]; after = [ "postgresql.service" ]; }; "data-folder-init" = { enable = true; description = "Setup data folders and permissions"; wantedBy = [ "multi-user.target" ]; script = pkgs.lib.fold (p: acc: acc + '' mkdir -p ${DOLLAR}{p} chown -R andreh:users ${DOLLAR}{p} chmod -R 755 ${DOLLAR}{p} '') "" (with envsubstConfiguration; [ staticRoot gitRoot faviconsRoot dataRoot ]); serviceConfig = { Type = "oneshot"; }; }; }; users.extraUsers."${envsubstConfiguration.userName}" = { uid = 1000; isNormalUser = true; extraGroups = [ "wheel" ]; password = envsubstConfiguration.userPassword; openssh.authorizedKeys.keys = [ envsubstConfiguration.authorizedKey ]; }; system.stateVersion = envsubstConfiguration.systemStateVersion; }