1
Fork 0
mirror of https://github.com/RGBCube/ncc synced 2025-07-30 11:37:44 +00:00

feat: move away from cube host

This commit is contained in:
RGBCube 2025-02-28 00:29:52 +03:00
parent 07537d4889
commit 5125a31e7f
Signed by: RGBCube
SSH key fingerprint: SHA256:CzqbPcfwt+GxFYNnFVCqoN5Itn4YFrshg1TrnACpA5M
36 changed files with 97 additions and 165 deletions

Binary file not shown.

107
hosts/best/forgejo.nix Normal file
View file

@ -0,0 +1,107 @@
{ self, config, lib, ... }: let
inherit (config.networking) domain;
inherit (lib) const enabled genAttrs head merge mkForce;
fqdn = "git.${domain}";
port = 8001;
in {
imports = [
(self + /modules/nginx.nix)
(self + /modules/postgresql.nix)
];
secrets.forgejoPasswordMail = {
file = self + /modules/mail/password.plain.age;
owner = "forgejo";
};
services.postgresql.ensure = [ "forgejo" ];
services.restic.backups = genAttrs config.services.restic.hosts <| const {
paths = [ "/var/lib/forgejo" ];
};
services.openssh.settings.AcceptEnv = mkForce "SHELLS COLOTERM GIT_PROTOCOL";
services.forgejo = enabled {
lfs = enabled;
secrets.mailer.PASSWD = config.secrets.forgejoPasswordMail.path;
database = {
socket = "/run/postgresql";
type = "postgres";
};
settings = let
description = "RGBCube's Forge of Shitty Software";
in {
default.APP_NAME = description;
attachment.ALLOWED_TYPES = "*/*";
cache.ENABLED = true;
mailer = {
ENABLED = true;
PROTOCOL = "smtps";
SMTP_ADDR = self.disk.mailserver.fqdn;
USER = "git@${domain}";
};
other = {
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
SHOW_FOOTER_VERSION = false;
};
packages.ENABLED = false;
repository = {
DEFAULT_BRANCH = "master";
DEFAULT_MERGE_STYLE = "rebase-merge";
DEFAULT_REPO_UNITS = "repo.code, repo.issues, repo.pulls";
DEFAULT_PUSH_CREATE_PRIVATE = false;
ENABLE_PUSH_CREATE_ORG = true;
ENABLE_PUSH_CREATE_USER = true;
DISABLE_STARS = true;
};
"repository.upload" = {
FILE_MAX_SIZE = 100;
MAX_FILES = 10;
};
server = {
DOMAIN = domain;
ROOT_URL = "https://${fqdn}/";
LANDING_PAGE = "/explore";
HTTP_ADDR = "::1";
HTTP_PORT = port;
SSH_PORT = head config.services.openssh.ports;
DISABLE_ROUTER_LOG = true;
};
service.DISABLE_REGISTRATION = true;
session = {
COOKIE_SECURE = true;
SAME_SITE = "strict";
};
"ui.meta" = {
AUTHOR = description;
DESCRIPTION = description;
};
};
};
services.nginx.virtualHosts.${fqdn} = merge config.services.nginx.sslTemplate {
locations."/".proxyPass = "http://[::1]:${toString port}";
};
}

View file

@ -1,8 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 8y3T6w izWjzENLwfqk9n6gvSvSQVPl/BZJZCa8hhLOVu5IvjY
wvfsfYEoYRWf93ArRNP/6rmXikqr0pZa2WyoYmoOYuw
-> ssh-ed25519 CzqbPQ h4ciazCxdHa0kEhImX9PPxLRs9Qw4eP9GFm4GgzQzzo
0wgm2Bf1/OfsxESnaoYQlXjN1IFHtBihU7yTDm3nGK0
--- kzbMa60jx3l2aqxA3Ll86mwCOzBLxcy2X2HjQS/iFtE
!@xAmzôU Ð"{GŠÎbYihJ}öÖºõ›@&g†çæ ·Ô
Ù5•Cñ¾¾{b/\=Ùxð (´Ï}z[ ŸA \ÔÏÔè7 EBœ3¢­„™2Ùk~A%§äLðù«k0l1M¸­Õ³Tà<>
-> ssh-ed25519 8y3T6w Hb6jT+7DbmcTh1fI4zF6ANWE5CgBEcD5N9gXCM0Dfm0
WpJeWN3xbOWRcYYuJkN7Y67DGnZqqZXurndBguWqUgo
-> ssh-ed25519 CzqbPQ KG+fgkB7r/HlgoNPY6cEeBn4vHlmJhlpShBmwEEGqiM
vEO8zBi6MCE6O0NF4/K6W7r3c594VGevIGuREIPYgWw
--- Ja8D1pjVd+J4Cv2VdavhLa/V7rMisT9WCrpDYDtaXCI
³_Ö„,hq2ÄêÚ>0ÔPÄó² ¹ÊŒJž?³Åâ˜û/ÌHÂ(¹ ÖÜi«´I¡£ý˜ÚLbÂÆ¼äØ`©fFY 9“Å.@²¤C[Ù—Áj“™pýÍgâÔðµÓbßq\8Üü÷3ºð挽Ù

View file

@ -0,0 +1,86 @@
{ self, config, lib, ... }: let
inherit (config.networking) domain;
inherit (lib) const enabled genAttrs merge;
fqdn = "metrics.${domain}";
port = 8000;
in {
imports = [
(self + /modules/nginx.nix)
(self + /modules/postgresql.nix)
];
secrets.grafanaPassword = {
file = ./password.age;
owner = "grafana";
};
secrets.grafanaPasswordMail = {
file = self + /modules/mail/password.plain.age;
owner = "grafana";
};
services.postgresql.ensure = [ "grafana" ];
services.restic.backups = genAttrs config.services.restic.hosts <| const {
paths = [ "/var/lib/grafana" ];
};
systemd.services.grafana = {
after = [ "postgresql.service" ];
requires = [ "postgresql.service" ];
};
services.grafana = enabled {
provision = enabled;
settings = {
analytics.reporting_enabled = false;
database.host = "/run/postgresql";
database.type = "postgres";
database.user = "grafana";
server.domain = fqdn;
server.http_addr = "::1";
server.http_port = port;
users.default_theme = "system";
};
settings.security = {
admin_email = "metrics@${domain}";
admin_password = "$__file{${config.secrets.grafanaPassword.path}}";
admin_user = "admin";
cookie_secure = true;
disable_gravatar = true;
disable_initial_admin_creation = true; # Just in case.
};
settings.smtp = {
enabled = true;
password = "$__file{${config.secrets.grafanaPasswordMail.path}}";
startTLS_policy = "MandatoryStartTLS";
ehlo_identity = "metrics@${domain}";
from_address = "metrics@${domain}";
from_name = "Metrics";
host = "${self.disk.mailserver.fqdn}:${toString self.disk.services.postfix.relayPort}";
};
};
services.nginx.virtualHosts.${fqdn} = merge config.services.nginx.sslTemplate {
locations."/" = {
extraConfig = /* nginx */ ''
# Grafana sets `nosniff` while not setting the content type properly,
# so everything breaks with it. Unset the header.
proxy_hide_header X-Content-Type-Options;
'';
proxyPass = "http://[::1]:${toString port}";
proxyWebsockets = true;
};
};
}

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 8y3T6w 1kO3fql8g9bmfuoLK2FUCmVBjgPHJ/51Yi+959QUSH0
gVMPYBnDW+iO0IStDXYPBkUcPqArBMiqOvChfbQb9nE
-> ssh-ed25519 CzqbPQ TUC1qiq9PXGmAkNkUBScYxK36X99xN7aBOsVUw6YFB0
9zk6II1eqtZztn6mf2BUwf9rYtrbnWkA9DBY/4H188I
--- +upO/vB2Q1tjXM7d+Zj9BnPwbRUs9lHTb+KU4vXrnQY
ÁngÆxߣS^8]ôìï(¨Ó“Ì@:¯~<7E>:2,žÈøÃŽ@<40>TxGÀ

View file

@ -0,0 +1,44 @@
{ self, config, lib, ... }: let
inherit (lib) enabled filterAttrs flatten mapAttrsToList;
in {
services.grafana.provision.datasources.settings = {
datasources = [{
name = "Prometheus";
type = "prometheus";
url = "http://[::1]:${toString config.services.prometheus.port}";
orgId = 1;
}];
deleteDatasources = [{
name = "Prometheus";
orgId = 1;
}];
};
services.prometheus = enabled {
listenAddress = "[::]";
retentionTime = "1w";
scrapeConfigs = let
configToScrapeConfig = hostName: { config, ... }: let
hostConfig = config;
in hostConfig.services.prometheus.exporters
|> filterAttrs (exporterName: exporterConfig:
exporterName != "minio" &&
exporterName != "unifi-poller" &&
exporterName != "tor" &&
exporterConfig.enable or false)
|> mapAttrsToList (exporterName: exporterConfig: {
job_name = "${exporterName}-${hostName}";
static_configs = [{
targets = [ "${hostName}:${toString exporterConfig.port}" ];
}];
});
in self.nixosConfigurations
|> mapAttrsToList configToScrapeConfig
|> flatten;
};
}

Binary file not shown.

Binary file not shown.

View file

@ -1,7 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 8y3T6w QFNMQ0/Nz/Hgr+AnATo5+06Xp7wwTrGSlwbE4EJ8M0o
yr6mqPKPUsuPvtGH+N/4oZHVzYt5p2GiXCiOZKHK2IA
-> ssh-ed25519 CzqbPQ gHGzzoNOS72IIZChwmPZ2empbMX80/set+Y3YN9nohQ
7rScYa4ntZTJe/IpWyY5Col4+123Temz9I+6A0ILCSE
--- IBo4lMDiPHrfQmv+PByQtft/FFNTzNyIjf0Hx9zoDuc
7<£æë4‡.î…/É)Q³È+Q"ëñ<C3AB> 8¶¨¿-\$
-> ssh-ed25519 8y3T6w o3hgSj4Cc6nRqDArwUJ3+tjxI7jXhztineZpCVqOdnA
GkL/pNTNimrbStwuD0N3Alpp9pcyZwEiJLlsWW2dIsg
-> ssh-ed25519 CzqbPQ OME6weqUWgtzgocBi/R+ExdOd6riRiHVL5i07mnsmiY
5UyvAXD7k5kgNcxkR54WEL17if/4hppzMiFggnj0zkQ
--- HWXzq9sNHOeVuWyminUwkuHsoHJAzhmquL931lW3lU0
`#(|K<7F>2éÈG{,\gàv¬K»e¼ä

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,97 @@
{ self, config, lib, ... }: let
inherit (config.networking) domain;
inherit (lib) const enabled genAttrs merge strings;
fqdn = "chat.${domain}";
port = 8002;
wellKnownResponse = data: /* nginx */ ''
${config.services.nginx.headers}
add_header Access-Control-Allow-Origin * always;
default_type application/json;
return 200 '${strings.toJSON data}';
'';
configWellKnownResponse.locations = {
"= /.well-known/matrix/client".extraConfig = wellKnownResponse {
"m.homeserver".base_url = "https://${fqdn}";
};
"= /.well-known/matrix/server".extraConfig = wellKnownResponse {
"m.server" = "${fqdn}:443";
};
};
in {
imports = [
(self + /modules/nginx.nix)
(self + /modules/postgresql.nix)
];
secrets.matrixSecret = {
file = ./password.secret.age;
owner = "matrix-synapse";
};
services.postgresql.ensure = [ "matrix-synapse" ];
services.restic.backups = genAttrs config.services.restic.hosts <| const {
paths = [ "/var/lib/matrix-synapse" ];
};
services.matrix-synapse = enabled {
withJemalloc = true;
configureRedisLocally = true;
settings.redis.enabled = true;
extras = [ "postgres" "url-preview" "user-search" ];
log.root.level = "WARNING"; # Shut the fuck up.
settings = {
server_name = domain;
# We are not setting web_client_location since the root is not accessible
# from the outside web at all. Only /_matrix is reverse proxied to.
database.name = "psycopg2";
report_stats = false;
enable_metrics = true;
metrics_flags.known_servers = true;
expire_access_token = true;
url_preview_enabled = true;
# Trusting Matrix.org.
suppress_key_server_warning = true;
};
# Sets registration_shared_secret.
extraConfigFiles = [ config.secrets.matrixSecret.path ];
settings.listeners = [{
inherit port;
bind_addresses = [ "::1" ];
tls = false;
type = "http";
x_forwarded = true;
resources = [{
compress = false;
names = [ "client" "federation" ];
}];
}];
};
services.nginx.virtualHosts.${domain} = configWellKnownResponse;
services.nginx.virtualHosts.${fqdn} = merge config.services.nginx.sslTemplate configWellKnownResponse {
locations."/".return = "301 https://${domain}/404";
locations."/_matrix".proxyPass = "http://[::1]:${toString port}";
locations."/_synapse/client".proxyPass = "http://[::1]:${toString port}";
};
}

Binary file not shown.

View file

@ -0,0 +1,115 @@
{ self, config, lib, pkgs, ... }: let
inherit (config.networking) domain;
inherit (lib) const enabled genAttrs merge mkAfter;
fqdn = "cloud.${domain}";
packageNextcloud = pkgs.nextcloud30;
in {
imports = [
(self + /modules/nginx.nix)
(self + /modules/postgresql.nix)
];
secrets.nextcloudPassword = {
file = ./password.age;
owner = "nextcloud";
};
secrets.nextcloudPasswordExporter = {
file = ./password.age;
owner = "nextcloud-exporter";
};
services.prometheus.exporters.nextcloud = enabled {
listenAddress = "[::]";
username = "admin";
url = "https://${fqdn}";
passwordFile = config.secrets.nextcloudPasswordExporter.path;
};
services.postgresql.ensure = [ "nextcloud" ];
services.restic.backups = genAttrs config.services.restic.hosts <| const {
paths = [ "/var/lib/nextcloud" ];
};
systemd.services.nextcloud-setup = {
after = [ "postgresql.service" ];
requires = [ "postgresql.service" ];
script = mkAfter /* sh */ ''
# TODO: Nextcloud 30 removed these. Find another way.
# nextcloud-occ theming:config name "RGBCube's Depot"
# nextcloud-occ theming:config slogan "RGBCube's storage of insignificant data."
# nextcloud-occ theming:config color "#000000"
# nextcloud-occ theming:config background backgroundColor
# nextcloud-occ theming:config logo ${./icon.gif}
'';
};
services.nextcloud = enabled {
package = packageNextcloud;
hostName = fqdn;
https = true;
configureRedis = true;
config.adminuser = "admin";
config.adminpassFile = config.secrets.nextcloudPassword.path;
config.dbhost = "/run/postgresql";
config.dbtype = "pgsql";
settings = {
default_phone_region = "TR";
# Even with a manual SMTP config, Nextcloud fails to communicate properly
# and fails to send mail. PHP moment?
# mail_smtphost = "::1"; # FIXME: Will need to use SMTP.
# mail_smtpmode = "sendmail";
# mail_from_address = "cloud";
maintenance_window_start = 1;
# No clue why it was syslog.
# What are the NixOS module authors on?
log_type = "file";
};
settings.enabledPreviewProviders = [
"OC\\Preview\\BMP"
"OC\\Preview\\GIF"
"OC\\Preview\\JPEG"
"OC\\Preview\\Krita"
"OC\\Preview\\MarkDown"
"OC\\Preview\\MP3"
"OC\\Preview\\OpenDocument"
"OC\\Preview\\PNG"
"OC\\Preview\\TXT"
"OC\\Preview\\XBitmap"
"OC\\Preview\\HEIC"
];
phpOptions = {
"opcache.interned_strings_buffer" = "16";
output_buffering = "off";
};
extraAppsEnable = true;
extraApps = {
inherit (packageNextcloud.packages.apps)
bookmarks calendar contacts deck forms
impersonate mail maps notes previewgenerator;
};
nginx.recommendedHttpHeaders = true;
};
services.nginx.virtualHosts.${fqdn} = merge config.services.nginx.sslTemplate {
extraConfig = config.services.nginx.headers;
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 KiB

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 8y3T6w 9liYuROGFIi5Zm5vZpUmXoJxbQWXNCP8qUV1Zh8QxCw
mPJWPqaPlTzolj5fTCSifaZvNzm4iRe8jcCwyDc6luk
-> ssh-ed25519 CzqbPQ KqS720TwZBncZCDnZ8mW8U8JJeyVXRbT0NOWmONO5QY
NmiNDln8D3PB+xU5tyXMcocM6B5Pa8EP2/mTUEOxJ1Y
--- dKRBVkxs485Spwp7YXH53K7PxCMDhA9hIhCpfUAgK9E
°.ttÖv<C396>ÿœ­ÎšK&u¹#”<>H«-f<>ˆ™Ùž5ž3÷Óãѧ

Binary file not shown.

3
hosts/best/site.nix Normal file
View file

@ -0,0 +1,3 @@
{ self, ... }: {
imports = [(self + /modules/site.nix)];
}