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:
parent
07537d4889
commit
5125a31e7f
36 changed files with 97 additions and 165 deletions
BIN
hosts/best/cache/key.age
vendored
BIN
hosts/best/cache/key.age
vendored
Binary file not shown.
107
hosts/best/forgejo.nix
Normal file
107
hosts/best/forgejo.nix
Normal 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}";
|
||||
};
|
||||
}
|
|
@ -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à<>iÏ
|
||||
-> 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ºð挽Ù
|
86
hosts/best/grafana/default.nix
Normal file
86
hosts/best/grafana/default.nix
Normal 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;
|
||||
};
|
||||
};
|
||||
}
|
7
hosts/best/grafana/password.age
Normal file
7
hosts/best/grafana/password.age
Normal 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À
|
44
hosts/best/grafana/prometheus.nix
Normal file
44
hosts/best/grafana/prometheus.nix
Normal 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.
|
@ -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—{,–5â›\gàv¬K»e¼ä
|
Binary file not shown.
Binary file not shown.
97
hosts/best/matrix/default.nix
Normal file
97
hosts/best/matrix/default.nix
Normal 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}";
|
||||
};
|
||||
}
|
BIN
hosts/best/matrix/password.secret.age
Normal file
BIN
hosts/best/matrix/password.secret.age
Normal file
Binary file not shown.
115
hosts/best/nextcloud/default.nix
Normal file
115
hosts/best/nextcloud/default.nix
Normal 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;
|
||||
};
|
||||
}
|
BIN
hosts/best/nextcloud/icon.gif
Normal file
BIN
hosts/best/nextcloud/icon.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 767 KiB |
7
hosts/best/nextcloud/password.age
Normal file
7
hosts/best/nextcloud/password.age
Normal 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
3
hosts/best/site.nix
Normal file
|
@ -0,0 +1,3 @@
|
|||
{ self, ... }: {
|
||||
imports = [(self + /modules/site.nix)];
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue