The Wobserver is currently in my living room running on my Homelab Build, so how do you view these pages? Surely my home IP address is not blasted on to the web via DynDNS, right? Right.
The Edge Server is a small VM co-located with AS64241 in beautiful Seattle, Washington. Yours could be on AWS, or DigitalOcean, or Hetzner, or whatever, man; it could also be your home IP address blasted on to the web via DynDNS, but it doesn't need to be. The Edge Server can establish an encrypted connection to the Wobserver using Tailscale. SSL can be terminated by an NGINX and proxied to the Nginx on the far side, or transparently proxied for termination within the Wobserver.
Base NixOS Server Manifest
This thing is "just" an Arroyo System, it pulls its configuration from my Knowledge Base.
{ config, pkgs, lib, ... }:
{
services.nginx.on-retreat.enable = false;
services.nginx.on-retreat.returnDate = "28 July";
services.tailscale.useRoutingFeatures = "server";
networking.firewall.logRefusedConnections = false;
imports = [
# <<arroyo_nixos_imports()>>
../nixos/akkoma-media-proxy.nix
];
home-manager.users.rrix.imports = [
# <<arroyo_home-manager_imports()>>
];
system.stateVersion = lib.mkDefault "24.11";
home-manager.users.rrix = {
home.stateVersion = config.system.stateVersion;
# don't ship pinentry-qt
services.gpg-agent.pinentryPackage = lib.mkForce pkgs.pinentry-curses;
};
services.prometheus.exporters.node = {
enable = true;
enabledCollectors = [ "systemd" ];
};
services.openssh.enable = true;
environment.systemPackages = with pkgs; [
pkgs.htop
];
}Helpers
local modules = arroyo.nixos_modules("edge")
local lines = {}
for i, m in ipairs(modules) do
table.insert(lines, "../../" .. m)
end
return table.concat(lines, "\n")local modules = arroyo.home_modules("edge")
local lines = {}
for i, m in ipairs(modules) do
table.insert(lines, "../../" .. m)
end
return table.concat(lines, "\n")The Edge Server's Base Nginx Forwarding configuration
The Edge Server mostly exists to serve My HTTP services and My Websites from The Wobserver to the web from a stable public IP address.
It's set up as a VM King Mountain right now but can quickly come up anywhere you can get a NixOS. Build a global content distribution network on the back of Tailscale's peering agreements, today!
{ config, pkgs, lib, ... }:
let
enabled = config.services.nginx.on-retreat.enable;
returnDate = config.services.nginx.on-retreat.returnDate;
retreatPage = pkgs.replaceVars ../files/on-retreat.html {
inherit returnDate;
};
in
{
options.services.nginx.on-retreat = with lib; {
enable = mkEnableOption { name = "turn off sites while offline"; };
returnDate = mkOption { type = types.str; default = ""; };
};
config = {
networking.firewall.allowedTCPPorts = [ 80 22 443 ];
services.logrotate = {
enable = true;
settings.nginx = {
frequency = "daily";
rotate = 365;
compress = true;
delaycompress = true;
};
};
services.nginx.virtualHosts."fontkeming.fail" = {
serverAliases = [
<<mkVirtualHosts()>>
];
forceSSL = true;
locations = lib.mkMerge [
# Retreat mode: serve the 503 page
(lib.mkIf enabled {
"/" = {
return = "503";
extraConfig = ''
error_page 503 /503.html;
'';
};
})
# Normal mode: proxy everything
(lib.mkIf (!enabled) {
"/" = {
proxyPass = "http://last-bank";
extraConfig = ''
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header Host $host;
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
})
{
"=/503.html" = {
alias = retreatPage;
extraConfig = ''
internal;
add_header Content-Type text/html;
'';
};
}
];
};
};
}On Retreat page
<!DOCTYPE html>
<html>
<head>
<title>The Arcology Site Network is temporarily offline</title>
</head>
<body>
<h1>Ryan Rix is offline and AFK right now</h1>
<p>They will be returning from a meditation retreat on <b>@returnDate@</b> and his sites will be offline until then. Thank you for understanding.</p>
<p>Please contact <a href="https://bluecliffzen.org">Blue Cliff Zen Center</a> if you need to get ahold of them despite this. Be good and be good at it.</p>
</body>
</html>Helpers for Hosts
local lines = {}
for i, row in ipairs(tbl) do
table.insert(lines, '"' .. row[1] .. '"')
end
return table.concat(lines, "\n")"fontkeming.fail"
"dns.fontkeming.fail"
"docker.fontkeming.fail"
"scanner.fontkeming.fail"
"vault.whatthefuck.computer"
"kickass.systems"
"thelionsrear.com"
"arcology.garden"
"engine.arcology.garden"
"thechanceencounter.com"
"cce.whatthefuck.computer"
"whatthefuck.computer"
"files.fontkeming.fail"
"notes.whatthefuck.computer"
"i.notes.whatthefuck.computer"
"bag.fontkeming.fail"
"ring.whatthefuck.computer"
"media.whatthefuck.computer"
"feeds.whatthefuck.computer"
"dongiverse.com"
"links.fontkeming.fail"