nixify appview #3

open
opened by anirudh.fi targeting master from push-oqkkllmzurup
+4 -4
flake.lock
···
"sqlite-lib-src": "sqlite-lib-src"
},
"locked": {
-
"lastModified": 1758898964,
-
"narHash": "sha256-UFCO4KN7EzT058WcJtjiQiIaoKwSP2ddkhPK74S8zug=",
+
"lastModified": 1762506184,
+
"narHash": "sha256-4NqqrAHQXMUasM5Vw7BUUgjvXA1xrfYkhaKu6YNxFpo=",
"ref": "refs/heads/master",
-
"rev": "7ddfed41ed0e2241dbb2edb9b0f69fce7e40f820",
-
"revCount": 1450,
+
"rev": "30d281f77d830b1c45104a44c9e7e5eafb52b354",
+
"revCount": 1611,
"type": "git",
"url": "https://tangled.org/@tangled.org/core"
},
+30
flake.nix
···
};
nixosConfigurations.pds = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
+
specialArgs = {
+
commonArgs = import ./common/ssh.nix;
+
};
modules = [
disko.nixosModules.disko
./hosts/pds/configuration.nix
];
};
+
nixosConfigurations.appview = nixpkgs.lib.nixosSystem {
+
system = "x86_64-linux";
+
specialArgs = {
+
commonArgs = import ./common/ssh.nix;
+
};
+
modules = [
+
disko.nixosModules.disko
+
./hosts/appview/configuration.nix
+
];
+
};
colmenaHive = colmena.lib.makeHive {
meta = {
···
pkgs.curl
];
};
+
appview = { pkgs, ... }: {
+
deployment = {
+
targetHost = "alpha.tangled.sh";
+
targetPort = 22;
+
targetUser = "tangler";
+
buildOnTarget = true;
+
};
+
nixpkgs.system = "x86_64-linux";
+
imports = [
+
disko.nixosModules.disko
+
tangled.nixosModules.appview
+
./hosts/appview/configuration.nix
+
./hosts/appview/services/appview.nix
+
./hosts/appview/services/nginx-alpha.nix
+
];
+
time.timeZone = "Europe/Helsinki";
+
};
pds = { pkgs, ... }: {
deployment = {
targetHost = "tngl.sh";
+57
hosts/appview/configuration.nix
···
+
{ modulesPath
+
, lib
+
, pkgs
+
, ...
+
} @ args:
+
{
+
imports = [
+
(modulesPath + "/installer/scan/not-detected.nix")
+
(modulesPath + "/profiles/qemu-guest.nix")
+
./disk-config.nix
+
];
+
boot.loader.grub = {
+
# no need to set devices, disko will add all devices that have a EF02 partition to the list already
+
# devices = [ ];
+
efiSupport = true;
+
efiInstallAsRemovable = true;
+
};
+
+
networking.hostName = "appview-arn";
+
services = {
+
openssh.enable = true;
+
};
+
+
+
nix = {
+
extraOptions = ''
+
experimental-features = nix-command flakes ca-derivations
+
warn-dirty = false
+
keep-outputs = false
+
'';
+
};
+
+
environment.systemPackages = map lib.lowPrio [
+
pkgs.curl
+
pkgs.gitMinimal
+
];
+
+
users.users.tangler = {
+
extraGroups = [ "networkmanager" "wheel" ];
+
openssh.authorizedKeys.keys = args.commonArgs.sshKeys;
+
isNormalUser = true;
+
};
+
+
security.sudo.extraRules = [
+
{
+
users = [ "tangler" ];
+
commands = [
+
{
+
command = "ALL";
+
options = [ "NOPASSWD" ];
+
}
+
];
+
}
+
];
+
+
system.stateVersion = "25.05";
+
}
+56
hosts/appview/disk-config.nix
···
+
# Example to create a bios compatible gpt partition
+
{ lib, ... }:
+
{
+
disko.devices = {
+
disk.disk1 = {
+
device = lib.mkDefault "/dev/vda";
+
type = "disk";
+
content = {
+
type = "gpt";
+
partitions = {
+
boot = {
+
name = "boot";
+
size = "1M";
+
type = "EF02";
+
};
+
esp = {
+
name = "ESP";
+
size = "500M";
+
type = "EF00";
+
content = {
+
type = "filesystem";
+
format = "vfat";
+
mountpoint = "/boot";
+
};
+
};
+
root = {
+
name = "root";
+
size = "100%";
+
content = {
+
type = "lvm_pv";
+
vg = "pool";
+
};
+
};
+
};
+
};
+
};
+
lvm_vg = {
+
pool = {
+
type = "lvm_vg";
+
lvs = {
+
root = {
+
size = "100%FREE";
+
content = {
+
type = "filesystem";
+
format = "ext4";
+
mountpoint = "/";
+
mountOptions = [
+
"defaults"
+
];
+
};
+
};
+
};
+
};
+
};
+
};
+
}
+11
hosts/appview/services/appview.nix
···
+
{ modulesPath
+
, lib
+
, pkgs
+
, ...
+
} @ args:
+
{
+
services.tangled.appview = {
+
enable = true;
+
environmentFile = "/etc/secrets/appview.env";
+
};
+
}
+53
hosts/appview/services/nginx-alpha.nix
···
+
{ config, pkgs, ... }:
+
{
+
services.nginx = {
+
enable = true;
+
recommendedTlsSettings = true;
+
recommendedOptimisation = true;
+
recommendedGzipSettings = true;
+
+
# Fix proxy headers hash warnings
+
appendHttpConfig = ''
+
proxy_headers_hash_max_size 1024;
+
proxy_headers_hash_bucket_size 128;
+
'';
+
+
virtualHosts = {
+
# AppView service on alpha.tangled.sh
+
"alpha.tangled.sh" = {
+
forceSSL = true;
+
enableACME = true;
+
+
locations."/" = {
+
proxyPass = "http://127.0.0.1:3000";
+
extraConfig = ''
+
proxy_http_version 1.1;
+
proxy_set_header Host $host;
+
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;
+
client_max_body_size 100M;
+
'';
+
};
+
+
# WebSocket support for /logs endpoint
+
locations."~ /logs$" = {
+
proxyPass = "http://127.0.0.1:3000";
+
proxyWebsockets = true;
+
extraConfig = ''
+
proxy_read_timeout 86400;
+
'';
+
};
+
};
+
};
+
};
+
+
# Open firewall ports
+
networking.firewall.allowedTCPPorts = [ 80 443 ];
+
+
# ACME configuration for Let's Encrypt
+
security.acme = {
+
acceptTerms = true;
+
defaults.email = "team@tangled.org";
+
};
+
}
+93
hosts/appview/services/nginx.nix
···
+
{ config, pkgs, ... }:
+
{
+
services.nginx = {
+
enable = true;
+
recommendedProxySettings = true;
+
recommendedTlsSettings = true;
+
recommendedOptimisation = true;
+
recommendedGzipSettings = true;
+
+
virtualHosts = {
+
# Redirect tangled.sh → tangled.org
+
"tangled.sh" = {
+
serverAliases = [ "www.tangled.sh" ];
+
locations."/" = {
+
return = "301 https://tangled.org$request_uri";
+
};
+
forceSSL = true;
+
enableACME = true;
+
};
+
+
# Redirect strings.tangled.sh → tangled.org/strings/*
+
"strings.tangled.sh" = {
+
locations."/" = {
+
return = "301 https://tangled.org/strings$request_uri";
+
};
+
forceSSL = true;
+
enableACME = true;
+
};
+
+
# Redirect strings.tangled.org → tangled.org/strings/*
+
"strings.tangled.org" = {
+
locations."/" = {
+
return = "301 https://tangled.org/strings$request_uri";
+
};
+
forceSSL = true;
+
enableACME = true;
+
};
+
+
# Main app on tangled.org
+
"tangled.org" = {
+
serverAliases = [ "www.tangled.org" ];
+
+
forceSSL = true;
+
enableACME = true;
+
+
extraConfig = ''
+
# Redirect www → bare domain
+
if ($host = www.tangled.org) {
+
return 301 https://tangled.org$request_uri;
+
}
+
+
client_max_body_size 100M;
+
'';
+
+
locations."~ ^/@tangled\\.sh(/.*)?$" = {
+
return = "301 https://tangled.org/@tangled.org$1$is_args$args";
+
};
+
+
locations."~ ^/tangled\\.sh(/.*)?$" = {
+
return = "301 https://tangled.org/tangled.org$1$is_args$args";
+
};
+
+
locations."~ /logs$" = {
+
proxyPass = "http://127.0.0.1:3000";
+
proxyWebsockets = true;
+
extraConfig = ''
+
proxy_read_timeout 86400;
+
'';
+
};
+
+
locations."/" = {
+
proxyPass = "http://127.0.0.1:3000";
+
extraConfig = ''
+
proxy_set_header Host $host;
+
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;
+
include ${config.services.nginx.package}/conf/mime.types;
+
'';
+
};
+
};
+
};
+
};
+
+
# Open firewall ports
+
networking.firewall.allowedTCPPorts = [ 80 443 ];
+
+
# ACME configuration for Let's Encrypt
+
security.acme = {
+
acceptTerms = true;
+
defaults.email = "team@tangled.org";
+
};
+
}
+1 -1
hosts/nixery/configuration.nix
···
networking.hostName = "nixery";
services = {
openssh.enable = true;
-
tangled-spindle = {
+
tangled.spindle = {
enable = true;
server = {
owner = "did:plc:wshs7t2adsemcrrd4snkeqli"; # @tangled.sh