From 6522536dc80d823f42ccca6bcc834e9b82da4b8f Mon Sep 17 00:00:00 2001 From: Anish Lakhwara Date: Sun, 14 Jul 2024 16:43:57 -0700 Subject: [PATCH] dns: add write.sealight.xyz? --- .gitignore | 1 + dns/dnsconfig.js | 1 + hosts/profiles/blogg/default.nix | 18 ++++ modules/nixos/blogging.nix | 148 +++++++++++++++++++++++++++++++ pkgs/gpodder2go.nix | 14 +++ 5 files changed, 182 insertions(+) create mode 100644 .gitignore create mode 100644 hosts/profiles/blogg/default.nix create mode 100644 modules/nixos/blogging.nix create mode 100644 pkgs/gpodder2go.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..9b421064 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.direnv/ diff --git a/dns/dnsconfig.js b/dns/dnsconfig.js index a0819431..6ce41591 100644 --- a/dns/dnsconfig.js +++ b/dns/dnsconfig.js @@ -39,6 +39,7 @@ D('sealight.xyz', REG_NONE, DnsProvider(DNS_HEDNS), A('git', '69.61.2.203', TTL(300)), A('bin', '69.61.2.203', TTL(300)), A('ci', '69.61.2.203', TTL(300)), + A('write', '69.61.2.203', TTL(300)), // vultr -> nulled: lituus A('@', '45.77.48.108', TTL(300)), A('jitsi', '45.77.48.108', TTL(300)), diff --git a/hosts/profiles/blogg/default.nix b/hosts/profiles/blogg/default.nix new file mode 100644 index 00000000..6ea900cc --- /dev/null +++ b/hosts/profiles/blogg/default.nix @@ -0,0 +1,18 @@ +{pkgs, ... }: +{ + services.nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + }; + + # Enables MySQL + services.mysql = { + enable = true; + package = pkgs.mariadb; + }; + + services."write.sealight.xyz".enable = true; +} diff --git a/modules/nixos/blogging.nix b/modules/nixos/blogging.nix new file mode 100644 index 00000000..f4fed915 --- /dev/null +++ b/modules/nixos/blogging.nix @@ -0,0 +1,148 @@ +{ options, lib, config, pkgs, ... }: +let + # domain for the Ghost blog + serverName = "write.sealight.xyz"; + # port on which the Ghost service runs + port = 1357; + # user used to run the Ghost service + userName = builtins.replaceStrings [ "." ] [ "_" ] serverName; + # MySQL database used by Ghost + dbName = userName; + # MySQL user used by Ghost + dbUser = userName; + # directory used to save the blog content + dataDir = "/var/lib/${userName}"; + # Ghost package we created in the section above + ghost = import ./ghost { inherit pkgs; }; + # script that sets up the Ghost content directory + setupScript = pkgs.writeScript "${serverName}-setup.sh" '' + #! ${pkgs.stdenv.shell} -e + chmod g+s "${dataDir}" + [[ ! -d "${dataDir}/content" ]] && cp -r "${ghost}/content" "${dataDir}/content" + chown -R "${userName}":"${userName}" "${dataDir}/content" + chmod -R +w "${dataDir}/content" + ln -f -s "/etc/${serverName}.json" "${dataDir}/config.production.json" + [[ -d "${dataDir}/current" ]] && rm "${dataDir}/current" + ln -f -s "${ghost}/current" "${dataDir}/current" + [[ -d "${dataDir}/content/themes/casper" ]] && rm "${dataDir}/content/themes/casper" + ln -f -s "${ghost}/current/content/themes/casper" "${dataDir}/content/themes/casper" + ''; + + databaseService = "mysql.service"; + + serviceConfig = config.services."${serverName}"; + options = { enable = lib.mkEnableOption "${serverName} service"; }; +in { + options.services.${serverName} = options; + config = lib.mkIf serviceConfig.enable { + # Creates the user and group + users.users.${userName} = { + isSystemUser = true; + group = userName; + createHome = true; + home = dataDir; + }; + users.groups.${userName} = { }; + + # Creates the Ghost config + environment.etc."${serverName}.json".text = '' + { + "url": "https://${serverName}", + "server": { + "port": ${port}, + "host": "0.0.0.0" + }, + "database": { + "client": "mysql", + "connection": { + "host": "localhost", + "user": "${dbUser}", + "database": "${dbName}", + "password": "", + "socketPath": "/run/mysqld/mysqld.sock" + } + }, + "mail": { + "transport": "sendmail" + }, + "logging": { + "transports": ["stdout"] + }, + "paths": { + "contentPath": "${dataDir}/content" + } + } + ''; + + # Sets up the Systemd service + systemd.services."${serverName}" = { + enable = true; + description = "${serverName} ghost blog"; + restartIfChanged = true; + restartTriggers = + [ ghost config.environment.etc."${serverName}.json".source ]; + requires = [ databaseService ]; + after = [ databaseService ]; + path = [ pkgs.nodejs pkgs.vips ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = userName; + Group = userName; + WorkingDirectory = dataDir; + # Executes the setup script before start + ExecStartPre = setupScript; + # Runs Ghost with node + ExecStart = "${pkgs.nodejs}/bin/node current/index.js"; + # Sandboxes the Systemd service + AmbientCapabilities = [ ]; + CapabilityBoundingSet = [ ]; + KeyringMode = "private"; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "full"; + RemoveIPC = true; + RestrictAddressFamilies = [ ]; + RestrictNamespaces = true; + RestrictRealtime = true; + }; + environment = { NODE_ENV = "production"; }; + }; + + # Sets up the blog virtual host on NGINX + services.nginx.virtualHosts.${serverName} = { + # Sets up Lets Encrypt SSL certificates for the blog + forceSSL = true; + enableACME = true; + locations."/" = { proxyPass = "http://127.0.0.1:${toString port}"; }; + extraConfig = '' + charset UTF-8; + + add_header Strict-Transport-Security "max-age=2592000; includeSubDomains" always; + add_header Referrer-Policy "strict-origin-when-cross-origin"; + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Content-Type-Options nosniff; + ''; + }; + + # Sets up MySQL database and user for Ghost + services.mysql = { + ensureDatabases = [ dbName ]; + ensureUsers = [{ + name = dbUser; + ensurePermissions = { "${dbName}.*" = "ALL PRIVILEGES"; }; + }]; + }; + }; +} + diff --git a/pkgs/gpodder2go.nix b/pkgs/gpodder2go.nix new file mode 100644 index 00000000..f46e87fe --- /dev/null +++ b/pkgs/gpodder2go.nix @@ -0,0 +1,14 @@ +{ pkgs, ... }: + +pkgs.buildGoModule rec { + name = "gpodder2go"; + src = pkgs.fetchFromGitHub { + owner = "oxtyped"; + repo = "gpodder2go"; + rev = "v0.1.2"; + hash = "sha256-RAt0rd4DZwI7b7IEFd1o4s4ivADzgzBzBaeGVL8OmYo"; + }; + + vendorHash = "sha256-mbSgY5WjIAesT27uRgaiRF3N06yuUntjTp6kjUMh6Bw"; + doCheck = false; +}