From d280b29394a581492ccf6d87218fca4abc72164c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Yule=20B=C3=A4dorf?= Date: Thu, 22 Feb 2024 19:20:24 +0100 Subject: [PATCH 1/5] obs-portal: init obs-portal on nachtigall This follows the official installation instructions at https://github.com/openbikesensor/portal/blob/main/docs/production-deployment.md Unfortunately, the postgres database needs to have postgis enabled, so we'll have to start a second instance. To stay close to the official deployment instructions, this is running in docker. The secrets were taken from the old installation instance. During initial installation, we'll need to import data from the old instance into this one, which might take a while. --- hosts/nachtigall/apps/obs-portal.nix | 140 +++++++++++++++++++++++++++ hosts/nachtigall/default.nix | 1 + secrets/obs-portal-database-env.age | 27 ++++++ secrets/obs-portal-env.age | Bin 0 -> 1593 bytes secrets/secrets.nix | 4 + 5 files changed, 172 insertions(+) create mode 100644 hosts/nachtigall/apps/obs-portal.nix create mode 100644 secrets/obs-portal-database-env.age create mode 100644 secrets/obs-portal-env.age diff --git a/hosts/nachtigall/apps/obs-portal.nix b/hosts/nachtigall/apps/obs-portal.nix new file mode 100644 index 0000000..0fd680d --- /dev/null +++ b/hosts/nachtigall/apps/obs-portal.nix @@ -0,0 +1,140 @@ +{ config +, lib +, pkgs +, self +, flake +, ... +}: let + configPy = pkgs.writeText "obs-portal-config.py" '' +DEBUG = False +VERBOSE = DEBUG +AUTO_RESTART = DEBUG +LEAN_MODE = False +FRONTEND_URL = None +FRONTEND_HTTPS = True +FRONTEND_DIR = "../frontend/build/" +FRONTEND_CONFIG = { + "imprintUrl": "https://pub.solar/about", + "privacyPolicyUrl": "https://pub.solar/privacy", + "mapHome": {"zoom": 12, "latitude": 50.93, "longitude": 6.97}, + "banner": { + "text": "This is an installation serving the Cologne/Bonn region run for Team OBSKöln by pub.solar n.e.V.", + "style": "info" + }, +} +TILES_FILE = None +ADDITIONAL_CORS_ORIGINS = None + ''; + + env = { + OBS_KEYCLOAK_URI = "auth.pub.solar"; + OBS_PORTAL_URI = "obs-portal.pub.solar"; + + OBS_POSTGRES_MAX_OVERFLOW = "20"; + OBS_POSTGRES_POOL_SIZE = "40"; + + OBS_HOST = "0.0.0.0"; + OBS_PORT = "3000"; + OBS_KEYCLOAK_URL = "https://auth.pub.solar/realms/pub.solar/"; + OBS_KEYCLOAK_CLIENT_ID = "openbikesensor-portal"; + OBS_DEDICATED_WORKER = "True"; + OBS_DATA_DIR = "/data"; + OBS_PROXIES_COUNT = "1"; + }; +in { + age.secrets.obs-portal-env = { + file = "${flake.self}/secrets/obs-portal-env.age"; + mode = "600"; + }; + + age.secrets.obs-portal-database-env = { + file = "${flake.self}/secrets/obs-portal-database-env.age"; + mode = "600"; + }; + + systemd.services."docker-network-obs-portal" = + let + docker = config.virtualisation.oci-containers.backend; + dockerBin = "${pkgs.${docker}}/bin/${docker}"; + in + { + serviceConfig.Type = "oneshot"; + before = [ "docker-obs-portal.service" ]; + script = '' + ${dockerBin} network inspect obs-portal-net >/dev/null 2>&1 || ${dockerBin} network create obs-portal-net --subnet 172.20.0.0/24 + ''; + }; + + services.nginx.virtualHosts."obs-portal.pub.solar" = { + enableACME = true; + forceSSL = true; + + locations."/" = { + proxyWebsockets = true; + extraConfig = '' + proxy_pass http://127.0.0.1:3001; + proxy_set_header Host $host; + ''; + }; + }; + + virtualisation = { + oci-containers = { + backend = "docker"; + + containers."obs-portal" = { + image = "git.pub.solar/pub-solar/obs-portal:latest"; + autoStart = true; + ports = [ "localhost:3001:${env.OBS_PORT}" ]; + + environment = env; + environmentFiles = [ config.age.secrets.obs-portal-env.path ]; + + volumes = [ + "${configPy}:/opt/obs/api/config.py" + "/var/lib/obs-portal${env.OBS_DATA_DIR}:${env.OBS_DATA_DIR}" + "/var/lib/obs-portal/tiles/:/tiles" + "/var/lib/obs-portal/pbf/:/pbf" + ]; + + extraOptions = [ + "--network=obs-portal-net" + ]; + }; + + containers."obs-portal-worker" = { + image = "git.pub.solar/pub-solar/obs-portal:latest"; + autoStart = true; + + cmd = [ "python" "tools/process_track.py" ]; + + environment = env; + environmentFiles = [ config.age.secrets.obs-portal-env.path ]; + + volumes = [ + "${configPy}:/opt/obs/api/config.py" + "/var/lib/obs-portal${env.OBS_DATA_DIR}:${env.OBS_DATA_DIR}" + ]; + + extraOptions = [ + "--network=obs-portal-net" + ]; + }; + + containers."obs-portal-db" = { + image = "openmaptiles/postgis:7.0"; + autoStart = true; + + environmentFiles = [ config.age.secrets.obs-portal-database-env.path ]; + + volumes = [ + "/var/lib/postgres-obs-portal/data:/var/lib/postgresql/data" + ]; + + extraOptions = [ + "--network=obs-portal-net" + ]; + }; + }; + }; +} diff --git a/hosts/nachtigall/default.nix b/hosts/nachtigall/default.nix index 69428bf..8e1455e 100644 --- a/hosts/nachtigall/default.nix +++ b/hosts/nachtigall/default.nix @@ -32,6 +32,7 @@ ./apps/promtail.nix ./apps/searx.nix ./apps/tmate.nix + ./apps/obs-portal.nix ./apps/matrix/irc.nix ./apps/matrix/mautrix-telegram.nix diff --git a/secrets/obs-portal-database-env.age b/secrets/obs-portal-database-env.age new file mode 100644 index 0000000..0286690 --- /dev/null +++ b/secrets/obs-portal-database-env.age @@ -0,0 +1,27 @@ +age-encryption.org/v1 +-> ssh-ed25519 iDKjwg hAoEiOaK1U0HImALePEYHiE6xebOOqtVujaBWgNBZF8 +ecf/ykqYPihRJxI/Y7Oh6QhWSyncwevlzEZoRqm3aGM +-> ssh-ed25519 uYcDNw NcIttsTn6wPCmoOYGtZ66IYhthjLDI3sYFe4pbW6cB4 +9hv4dEYoXXWSZ2pG1hy68vmTf++v+g3q7wVhT6cAog0 +-> ssh-rsa kFDS0A +KoW3J2Tw90chM6Oy17umOQN0WFI4je7CBk3IgdImsd4Mz5q17/nXlhVlFFhx4ZEk +Or9LaqytVk1NA6J4+suMRlx4Pd6oberXu1KBkFQMr1B3LKhNOaOZ+W1mrbQLGG9U +YUTyOpkHxVkw0IOsvxB/0reMCHtjKHo661zFjim1YFmEk0WRt4hU1XqsMNiE4wbc +GF0t9EWMN2pU2p7DpX/DzVTqu8yk8SQhCZc9kfzWcuawwf0rcjwUJ/Rk1MH5tMpK +odRXXl1slPPwQinE+KJqeyrfuRDHqwqmxnOfOWG6KQwWkVSE1btiHEvfuuLOjSjl +3wO+veRC9hW5sSCPANoFbuSQ1dprmoyaZnOyeRTbgw91ks/ogLBezF/KSkaMQeHx +XRnfcceBmeeqHl9L3Z+3EmBjwIqu2Og0pvhDU8G/ZeA0cHS/22QYGzeD/gOqaEW7 +d1VyA6LZd8PxIjoBamdipIpY0TqZ8+cA/yaUKNnYXXRSlKQ5ggPxh7ZXfvRbGg+m +WbNiHxBPcTK7/Bpzes4LJVcx0Ar4XeDxVQe1MITLpFWh+FDEQZEA3630JngZ153J +vBvw+VFedPSr6Ov+/33/J3LKC0XRatGnc++AWfo4rWPLCE6qovEDyY+wmct8gv0j +rMEK7OaNfyy+Z21mjrkwcEUbyoGt9ksEplaRblE0Lsk +-> ssh-ed25519 YFSOsg LmLRtBYMSzjid3VkUgAQvDOS9r0imWSKE7fm0t/x41Y +0mae0vsNmaS5aVOKezXit7KV44JKLpU+GWpuA++dCVo +-> ssh-ed25519 iHV63A Tc2z2JciftAikoj4Hv9IBgkcYWAcyGuPJTNA3Yw2K1w +cO5o/pbaZAtTvXUskOah9vWP/Tuvyi3QDM7g4AQ+b8s +-> ssh-ed25519 BVsyTA mk6n6ytaI4V9JVoUZFtwfFOgaLYc6gvVOcSZXQj/FVI +etqbUCqe0eY81qaVco7pMJjhfM+sA/bXLMW0bEsCLxI +--- CmNq6ZPxFoFTsySVfr7BTHV0tm9cbRYGG6IR7DNgbEY +!烈} +SꝟSlDs;!jrZR"#~!6AwEn ?kAcx~GV&M, +aU \ No newline at end of file diff --git a/secrets/obs-portal-env.age b/secrets/obs-portal-env.age new file mode 100644 index 0000000000000000000000000000000000000000..c23caae3a44fbe3881f2be79fd1d187f2743fbd9 GIT binary patch literal 1593 zcmZXU+3Vy60f5yOx&-=AM6`-_kX5kZXOfvoG7(zLB$H#3nH-Z$Cec!JOpeKYPXQ+o#vjZqXKMiDI>`e00-iG(%7b zi3SDbbXdDKu@WH*q*zy!d6QPv_9$lP4NL;b3O_-q=Te>vPd7|`*r5h_z$Ju|b$hSY z5ySc@R}prk;}wnb6?Qad1vyP%c#u{~1}Mg2Ty3$%nqq|#+>L`?(pCk&UKgiHq;wb` zd3|6qkQ4}W-sRTbDqMKzQAAe@&u4H4h~=5&U?*4(29H3h^5{!U8RGmQ*EVo-+|5(+ zK+2&D5(F9&^nw8kI>>9TDj72mnG~Suw95)p$e^)n&GZ(^TM(tWAZ>7M;VZqEHOi#7 z(s44b_ho8Ta5=b%qNGO`Q8xnw;D_Bj9^;v=orWr1!sBAKYoK^ZSv@Mkkv--_9fTv= z3yq`ULpe=2g#;rKYC07NWeKp()Yz<9UuBQu*52=pdE_w8f`Sx=l8hJ)hiqS;q)CYH z`Axbp^j#Q{X3EXP*p`X81P~f;sDqx!o*gq9!)fqwU=2|sU~dk3tmMy4d$*JeD0f*z z(Ye_emiVTlv!v)r4Cw&T534mL7)rlf!crSaSxU(V2t4%5!QXg`Dzv4-| zmilTbhhXc4GS35WH`Cc>9N?YZ!@(5XkgUNbq&n>8F6;|5yN$`#n6X%rD-7v%Ilgw& zwq+Q4(Y9+6269J|;<^--Ii;(;sHNsMz}!rCXs2}Ph?|BU+0dv_B=Aj-Z#HT&8>tRP zvM=+ymA20u_*krX#7gB;I%ZRIsvGSFGn;O;%H?>a4wKXpmJbldO-c$wEQRL#R(81ooWH4*TfHYN$@2y0@j~W|t_k5&qv1=G%JE$PrG+9=pLH zN&%CYVdqA=)lCQVGOBDA?mWO)yyi(zn*=71oxG?MoWqz7+apm&_(`xLMVW<}<5^m; zOVmXdvD0RfEr7GLv(dB`IRt{O!<^+hZcKH4l)4Itlr3AHT-9{3gtOLL(9>$*u5;)! zx9>(5-t*Yguc2>0_Nw{7>^uMb?eA;hzU?z#IR5g(pZrwt=%w@Yja#44z{lfjfBxOu z1o&L=LzM^A=DQcZ6lo zxmSPs#4W#i?Jae5ukhAq?t1pu@caL8>9~9O^XLEZy+^-xzH$A=Ef?;5absM4F*>Wy{op^}T%P~zZ=SpGkofE;F8=G*2QTr? g>GEIReE9W`=KA^NQToVj=$Br2 Date: Sat, 27 Apr 2024 22:28:56 +0200 Subject: [PATCH 2/5] remove git conflict heading --- secrets/secrets.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 32090c2..9c40bfb 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -1,5 +1,4 @@ let -<<<<<<< HEAD admins = import ../logins/admins.nix; nachtigall-host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP7G0ufi+MNvaAZLDgpieHrABPGN7e/kD5kMFwSk4ABj root@nachtigall"; From fef1874938c50bd33fe0e7db9a11aedc90f703d9 Mon Sep 17 00:00:00 2001 From: Hendrik Sokolowski Date: Sat, 27 Apr 2024 22:41:36 +0200 Subject: [PATCH 3/5] update obs-portal dns target --- terraform/dns.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/dns.tf b/terraform/dns.tf index 60226c0..5fb7c0a 100644 --- a/terraform/dns.tf +++ b/terraform/dns.tf @@ -36,8 +36,8 @@ resource "namecheap_domain_records" "pub-solar" { } record { hostname = "obs-portal" - type = "A" - address = "80.71.153.210" + type = "CNAME" + address = "nachtigall.pub.solar." } record { hostname = "vpn" From 1d6c5003e8b68c3025016f78572484ca3892b1ec Mon Sep 17 00:00:00 2001 From: Hendrik Sokolowski Date: Sun, 28 Apr 2024 01:05:43 +0200 Subject: [PATCH 4/5] nachtigall: obs-portal: fix dependencies of docker network unit and portal --- hosts/nachtigall/apps/obs-portal.nix | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hosts/nachtigall/apps/obs-portal.nix b/hosts/nachtigall/apps/obs-portal.nix index 0fd680d..da6c505 100644 --- a/hosts/nachtigall/apps/obs-portal.nix +++ b/hosts/nachtigall/apps/obs-portal.nix @@ -59,7 +59,8 @@ in { in { serviceConfig.Type = "oneshot"; - before = [ "docker-obs-portal.service" ]; + before = [ "docker-obs-portal.service" "docker-obs-portal-db.service" "docker-obs-portal-worker.service" ]; + requiredBy = [ "docker-obs-portal.service" "docker-obs-portal-db.service" "docker-obs-portal-worker.service" ]; script = '' ${dockerBin} network inspect obs-portal-net >/dev/null 2>&1 || ${dockerBin} network create obs-portal-net --subnet 172.20.0.0/24 ''; @@ -85,7 +86,11 @@ in { containers."obs-portal" = { image = "git.pub.solar/pub-solar/obs-portal:latest"; autoStart = true; - ports = [ "localhost:3001:${env.OBS_PORT}" ]; + ports = [ "127.0.0.1:3001:${env.OBS_PORT}" ]; + dependsOn = [ + "obs-portal-db" + "obs-portal-worker" + ]; environment = env; environmentFiles = [ config.age.secrets.obs-portal-env.path ]; From 10c86c6b2070540d17549177dcf4260d88b80c53 Mon Sep 17 00:00:00 2001 From: Hendrik Sokolowski Date: Sun, 28 Apr 2024 01:07:49 +0200 Subject: [PATCH 5/5] nachtigall: obs-portal: remove tiles mount --- hosts/nachtigall/apps/obs-portal.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/hosts/nachtigall/apps/obs-portal.nix b/hosts/nachtigall/apps/obs-portal.nix index da6c505..c182b8e 100644 --- a/hosts/nachtigall/apps/obs-portal.nix +++ b/hosts/nachtigall/apps/obs-portal.nix @@ -98,7 +98,6 @@ in { volumes = [ "${configPy}:/opt/obs/api/config.py" "/var/lib/obs-portal${env.OBS_DATA_DIR}:${env.OBS_DATA_DIR}" - "/var/lib/obs-portal/tiles/:/tiles" "/var/lib/obs-portal/pbf/:/pbf" ];