This commit is contained in:
nora 2025-08-03 00:33:53 +02:00
parent a1187fbef5
commit 68174b4a77
49 changed files with 88 additions and 585 deletions

View file

@ -1,27 +0,0 @@
name: Run playbooks
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
name: Run playbooks
steps:
- uses: actions/checkout@8b5e8b768746b50394015010d25e690bfab9dfbc # v3.6.0
- name: Unlock secrets
uses: sliteteam/github-action-git-crypt-unlock@8b1fa3ccc81e322c5c45fbab261eee46513fd3f8 # v1.2.0
env:
GIT_CRYPT_KEY: ${{ secrets.GIT_CRYPT_KEY_BASE64 }}
- name: Run Ansible playbook
uses: dawidd6/action-ansible-playbook@260ab3adce54d53c5db8f1b2eed1380ae5c73fea # v2.6.1
with:
playbook: all.yml
directory: playbooks
key: ${{ secrets.VPS_DEPLOY_KEY }}
known_hosts: |
vps1.nilstrieb.dev ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOjiNfzZQpN2KWd1LSM/LL+dLx8snlCV6jYys+W4NOBH
vps2.nilstrieb.dev ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzt3OZAOG2sih8T9Bhoqg8ANBP5ZX60z0xmUW4cBWvX
options: |
--inventory inventory.yml
-u root

View file

@ -7,9 +7,9 @@ APP="$1"
if [ "$APP" = "hugo-chat" ]; then if [ "$APP" = "hugo-chat" ]; then
REPO="https://github.com/C0RR1T/HugoChat.git" REPO="https://github.com/C0RR1T/HugoChat.git"
elif [ "$APP" = "cors" ]; then elif [ "$APP" = "cors" ]; then
REPO="https://github.com/nilstrieb-lehre/davinci-cors.git" REPO="https://github.com/noratrieb-lehre/davinci-cors.git"
else else
REPO="https://github.com/Nilstrieb/$APP.git" REPO="https://github.com/Noratrieb/$APP.git"
fi fi
echo "Checking out $REPO" echo "Checking out $REPO"

View file

@ -1 +0,0 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0Yl4+vAFgN+d82emRY8tHDgM7Pp0rLIsKBZku+YUsd vps-deploy-key

View file

@ -5,17 +5,6 @@ New infra based on more servers and more shit.
All servers have their hostname as their name here and are reachable via `$hostname.infra.noratrieb.dev`. All servers have their hostname as their name here and are reachable via `$hostname.infra.noratrieb.dev`.
They will have different firewall configurations depending on their roles. They will have different firewall configurations depending on their roles.
```
-------- --------
| dns1 | | dns2 |
-------- --------
--------
| vps1 |
--------
```
## DNS ## DNS

View file

@ -53,7 +53,16 @@
wg = { wg = {
privateIP = "10.0.0.1"; privateIP = "10.0.0.1";
publicKey = "5tg3w/TiCuCeKIBJCd6lHUeNjGEA76abT1OXnhNVyFQ="; publicKey = "5tg3w/TiCuCeKIBJCd6lHUeNjGEA76abT1OXnhNVyFQ=";
peers = [ "vps3" "vps4" "vps5" ]; peers = [ "vps2" "vps3" "vps4" "vps5" ];
};
};
vps2 = {
publicIPv4 = "184.174.32.252";
publicIPv6 = null;
wg = {
privateIP = "10.0.0.2";
publicKey = "SficHHJ0ynpZoGah5heBpNKnEVIVrgs72Z5HEKd3jHA=";
peers = [ "vps1" "vps3" "vps4" "vps5" ];
}; };
}; };
vps3 = { vps3 = {
@ -62,7 +71,7 @@
wg = { wg = {
privateIP = "10.0.0.3"; privateIP = "10.0.0.3";
publicKey = "pdUxG1vhmYraKzIIEFxTRAMhGwGztBL/Ly5icJUV3g0="; publicKey = "pdUxG1vhmYraKzIIEFxTRAMhGwGztBL/Ly5icJUV3g0=";
peers = [ "vps1" "vps4" "vps5" "dns1" "dns2" ]; peers = [ "vps1" "vps2" "vps4" "vps5" "dns1" "dns2" ];
}; };
}; };
vps4 = { vps4 = {
@ -73,7 +82,7 @@
wg = { wg = {
privateIP = "10.0.0.4"; privateIP = "10.0.0.4";
publicKey = "+n2XKKaSFdCanEGRd41cvnuwJ0URY0HsnpBl6ZrSBRs="; publicKey = "+n2XKKaSFdCanEGRd41cvnuwJ0URY0HsnpBl6ZrSBRs=";
peers = [ "vps1" "vps3" "vps5" ]; peers = [ "vps1" "vps2" "vps3" "vps5" ];
}; };
}; };
vps5 = { vps5 = {
@ -82,7 +91,7 @@
wg = { wg = {
privateIP = "10.0.0.5"; privateIP = "10.0.0.5";
publicKey = "r1cwt63fcOR+FTqMTUpZdK4/MxpalkDYRHXyy7osWUk="; publicKey = "r1cwt63fcOR+FTqMTUpZdK4/MxpalkDYRHXyy7osWUk=";
peers = [ "vps1" "vps3" "vps4" ]; peers = [ "vps1" "vps2" "vps3" "vps4" ];
}; };
}; };
}; };
@ -190,6 +199,19 @@
deployment.tags = [ "caddy" "eu" "apps" "website" ]; deployment.tags = [ "caddy" "eu" "apps" "website" ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
}; };
# VPS2 exists
vps2 = { name, nodes, modulesPath, config, lib, ... }: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
./modules/contabo
./modules/wg-mesh
./modules/caddy
./modules/garage
];
deployment.tags = [ "caddy" "eu" "apps" ];
system.stateVersion = "23.11";
};
# VPS3 is the primary monitoring/metrics server. # VPS3 is the primary monitoring/metrics server.
vps3 = { name, nodes, modulesPath, config, ... }: { vps3 = { name, nodes, modulesPath, config, ... }: {
imports = [ imports = [

View file

@ -37,11 +37,6 @@ let
ns1 = dns1; ns1 = dns1;
ns2 = dns2; ns2 = dns2;
# apps
cors-school = vps2 // {
subdomains.api = vps2;
};
localhost.A = [ (a "127.0.0.1") ]; localhost.A = [ (a "127.0.0.1") ];
# --- retired: # --- retired:

View file

@ -9,9 +9,6 @@ let
lib.optionalAttrs (publicIPv4 != null) { A = [ (a publicIPv4) ]; } // lib.optionalAttrs (publicIPv4 != null) { A = [ (a publicIPv4) ]; } //
lib.optionalAttrs (publicIPv6 != null) { AAAA = [ (aaaa publicIPv6) ]; }) lib.optionalAttrs (publicIPv6 != null) { AAAA = [ (aaaa publicIPv6) ]; })
networkingConfig; networkingConfig;
vps2 = {
A = [ "184.174.32.252" ];
};
combine = hosts: { combine = hosts: {
A = lib.lists.flatten (map (host: if builtins.hasAttr "A" host then host.A else [ ]) hosts); A = lib.lists.flatten (map (host: if builtins.hasAttr "A" host then host.A else [ ]) hosts);
@ -63,9 +60,6 @@ let
}; };
}; };
# --- legacy crap
old-docker = vps2;
# --- apps # --- apps
bisect-rustc = vps1; bisect-rustc = vps1;
docker = vps1; docker = vps1;

View file

@ -6,13 +6,6 @@
- co-du -> Contabo Düsseldorf - co-du -> Contabo Düsseldorf
- he-nu -> Hetzner Nürnberg - he-nu -> Hetzner Nürnberg
| name | disk space | identifier | zone |
| ---- | ---------- | ---------- | ----- |
| vps3 | 70GB | cabe | co-du |
| vps3 | 100GB | 020bd | co-ka |
| vps4 | 30GB | 41e40 | he-nu |
| vps5 | 100GB | 848d8 | co-du |
## buckets ## buckets
- `caddy-store`: Store for Caddy webservers - `caddy-store`: Store for Caddy webservers
@ -35,6 +28,7 @@
- `loki`: `GK84ffae2a0728abff0f96667b` - `loki`: `GK84ffae2a0728abff0f96667b`
- `backups`: `GK8cb8454a6f650326562bff2f` - `backups`: `GK8cb8454a6f650326562bff2f`
- `forgejo`: `GKc8bfd905eb7f85980ffe84c9` - `forgejo`: `GKc8bfd905eb7f85980ffe84c9`
- `upload-files`: `GK607464882f6e29fb31e0f553`
- `admin`: `GKaead6cf5340e54a4a19d9490` - `admin`: `GKaead6cf5340e54a4a19d9490`
- RW permissions on ~every bucket - RW permissions on ~every bucket

View file

@ -1,5 +1,5 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 qM6TYg QziuzHQxmWyRdv8dUPBWTgnMxFtqR6ttP16Z3XdvD3Y -> ssh-ed25519 qM6TYg UtoSFhZQ2PW1y3ifXgSdQQswoi5kdRg2gvczlEateC4
Krxmha5J+gTU0DjzPDTDIwz1mW0Q84XR2FgQyPm4bf4 ir2FpFkYo17MGBy+C4thM4lit7vn2CiBi09DcTb6ubs
--- t4Mea1Y35o5t2dhREnp8Zq1AyR4DAWMFW7Vv3CkgGKw --- YvRhsfFzedjeKssmOTzHvKkvIG0zXVVCIJsRNc/LTVg
ìlTS+Ƴ6y­¿rîëOØné<6E>&c`Ï°Ê ü<>:û³7V»-tf±puw€I¥w“Âøå  €KîÞ$é†Prm;Û·ûÎªæ ¹Œö+é ÚqE@<40>Àv]¢Ôòm =Í™'Sm

View file

@ -1,6 +1,7 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 qM6TYg ecu0Ic6o+WyT7XhZPo0Yf46bOye2LAgnJ5MxFPTY/E0 -> ssh-ed25519 qM6TYg GNYf0FjEDEqCe09mS9Hl7OIIjvhKTu8urwUPtY+yyB0
JqJCtQmtxgktMl/4HsHh0uRp/rzEoqT9Z81H9v1RXio xmAtm4n3s0rfq3S5OKFEG2k/noXFTKMt8hiW5QrD9SU
--- /CmBzuDf0AcCk6rAvEh5SmIMxpwCTjfj9IQtRLv5qYA --- HGBYxXQGM254m2YP5twgjgDme80f0uOL2m4uKy19ZBs
}Œ=5i ÖÂ(
©¨£#ª4bÎpzCaÀjÙnêB†±€ÍN<C38D>%ÚnO Ž³GKÔ´ÖâõƒÏ”ßÁ¼‹Æçé'ÄZ>T“œì<C593>ÙMøô<}//}|uá5œªsö* Õ×åÇÄT
‚®à±Öì{ÙõF“ü-\ƒ6{mítÏæÊMÑ-óX{‡%bQd]E³Éàü]i¸úãË}F»2¸$7¤ö#k4“;8ZžGþ_oÛ –¼

View file

@ -1,12 +1,13 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 qM6TYg B17o68OCsoljQLd4yLx1gZbt9zsFhQE8/QJeZ3Gx+AI -> ssh-ed25519 qM6TYg F9aj1EmsmRSXt1m3a41zpuwFmDBOuuaIrHkqP7PTVno
ADxN8iqNN5ApzHMtIXMnMTN4qe/7ba+ZoqkpHDpq9dE tVs8Oxa9gV/HdUf0hN/JLuWhbrXI9BXIrsh5HnsKBQI
-> ssh-ed25519 XzACZQ Jp5WvbUVmfecvN95vM6+DQmJicVf4u94Vm0mYtBVODw -> ssh-ed25519 pP9cdg dQdPm3OfbWl5Y8kJxmsUZ4rwpUo8w3+P3CHCiXw9VCw
XAdVpk6bAwAU7OQxvedepr3g8HQo5sY5efy3lYhf1xA 9yWbGgzgBz9GICAgYiOyPtMjDk/tBb4vsOveTuYP9bw
-> ssh-ed25519 51bcvA DUkgjLS805iAsnaCl3B8BOP6cdKOJCx0aK23UEDmTyw -> ssh-ed25519 XzACZQ 4lldtotM16DN/75dRX3QEmOzfIEySHcNOlFWqymI+Rs
dUZhXJiYkCZvassxSg0Cgf9c+ta2Oc2PNhLdvHBP24M oOaD7dZu0xC0R7CrVpfwoBU7eSgaWyJmAZ4WptCQdes
-> ssh-ed25519 vT7ExA 0Z2/GFY2aqO2HJJet3CRSh3yxchGt7AYTzkl0D2aoEQ -> ssh-ed25519 51bcvA k9eq2Tc3A9MztsdTvt3sDYUj/usYBJMp9IJQZAR67Ac
GuMqW7tbsEl/SskgN1hPa0B/aWtet/+pHxmbwsTzPCM ezccfIhPZaHKsVcUrxJL7u3jSA/kCTqLmWuQfxrFQBo
--- vgf72fLRkTVRtJoxh+qfim9YYELE0W74L6ZVjpo+8vI -> ssh-ed25519 vT7ExA BOCylq1RqaburnXxfsl3xqAmGSJnIxVhXK8H2xeFynk
åø=ê&óŸC»íÄŸŸ#À¥ÑÒ/nܤè´2Â9†ØÞøo[<5B>S+ uWʶ¢£4êÕf/hAÈþ#ïþOs_†RV£òEÆÆóÎûúÎVAlžTÏ/¤VΨtµøJNöËUë;ññnGúQïìÝ£ÖO{Áx[ ¿†íÏP¨Hß9P®:z OWhqsbJgHWlo3hsRZVQgEaArK32OI25N4Poi2qJ9wQs
ê‰û²åyX„Ñ`]%>¨+ÙÞ~)Ø`VïâxÛ°€i-ƒã¬Fýªš$xHå)ÒTMcZ --- bBQkNfDI0onJOyxOJIN3Yl2jkK5iRgYbK67RWsipXOE
3‡ýåA9â¯ÒAÕînÛ¯t•y®ßÚCj-îž{ÏŇâ)ô6¬DfØOÆQ¹Ü}'_n†øÈã‡>UPêNæDRŸÀÁª¨ûÊÆþ-<2D>¾„…éÂ"‡´úÛâšÙ?À>)E0<7F>‡v(~7 C¾O\UJJüŽ$SÂ8èá`€F«˜ÄíšQ§0uÙ3õmH•Ž~P÷Ž£ŒÅLqfõ~ºi¸Æn]=rSre#²wGŒ ³¥@ß|X#éØ÷’Â

Binary file not shown.

Binary file not shown.

View file

@ -2,6 +2,7 @@ let
dns1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBKoyDczFntyQyWj47Z8JeewKcCobksd415WM1W56eS"; dns1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBKoyDczFntyQyWj47Z8JeewKcCobksd415WM1W56eS";
dns2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINZ1yLdDhI2Vou/9qrPIUP8RU8Sg0WxLI2njtP5hkdL7"; dns2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINZ1yLdDhI2Vou/9qrPIUP8RU8Sg0WxLI2njtP5hkdL7";
vps1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII4Xj3TsDPStoHquTfOlyxShbA/kgMfQskKN8jpfiY4R"; vps1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII4Xj3TsDPStoHquTfOlyxShbA/kgMfQskKN8jpfiY4R";
vps2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzt3OZAOG2sih8T9Bhoqg8ANBP5ZX60z0xmUW4cBWvX";
vps3 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHvupo7d9YMZw56qhjB+tZPijxiG1dKChLpkOWZN0Y7C"; vps3 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHvupo7d9YMZw56qhjB+tZPijxiG1dKChLpkOWZN0Y7C";
vps4 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMpoLgBTWj1BcNxXVdM26jDBZl+BCtUTj20Wv4sZdCHz"; vps4 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMpoLgBTWj1BcNxXVdM26jDBZl+BCtUTj20Wv4sZdCHz";
vps5 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBWbIznvWQSqRF1E9Gv9y7JXMy3LZxMAWj6K0Nq91kyZ"; vps5 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBWbIznvWQSqRF1E9Gv9y7JXMy3LZxMAWj6K0Nq91kyZ";
@ -13,20 +14,21 @@ in
"hugochat_db_password.age".publicKeys = [ vps1 ]; "hugochat_db_password.age".publicKeys = [ vps1 ];
"openolat_db_password.age".publicKeys = [ vps1 ]; "openolat_db_password.age".publicKeys = [ vps1 ];
"minio_env_file.age".publicKeys = [ vps1 vps3 ]; "minio_env_file.age".publicKeys = [ vps1 vps3 ];
"garage_secrets.age".publicKeys = [ vps1 vps3 vps4 vps5 ]; "garage_secrets.age".publicKeys = [ vps1 vps2 vps3 vps4 vps5 ];
"caddy_s3_key_secret.age".publicKeys = [ vps1 vps3 vps4 vps5 ]; "caddy_s3_key_secret.age".publicKeys = [ vps1 vps2 vps3 vps4 vps5 ];
"registry_htpasswd.age".publicKeys = [ vps1 ]; "registry_htpasswd.age".publicKeys = [ vps1 ];
"registry_s3_key_secret.age".publicKeys = [ vps1 ]; "registry_s3_key_secret.age".publicKeys = [ vps1 ];
"grafana_admin_password.age".publicKeys = [ vps3 ]; "grafana_admin_password.age".publicKeys = [ vps3 ];
"loki_env.age".publicKeys = [ vps3 ]; "loki_env.age".publicKeys = [ vps3 ];
"backup_s3_secret.age".publicKeys = [ vps1 vps3 vps4 vps5 ]; "backup_s3_secret.age".publicKeys = [ vps1 vps2 vps3 vps4 vps5 ];
"s3_mc_admin_client.age".publicKeys = [ vps1 vps3 vps4 vps5 ]; "s3_mc_admin_client.age".publicKeys = [ vps1 vps2 vps3 vps4 vps5 ];
"killua_env.age".publicKeys = [ vps1 ]; "killua_env.age".publicKeys = [ vps1 ];
"forgejo_s3_key_secret.age".publicKeys = [ vps1 ]; "forgejo_s3_key_secret.age".publicKeys = [ vps1 ];
"upload_files_s3_secret.age".publicKeys = [ vps1 ]; "upload_files_s3_secret.age".publicKeys = [ vps1 ];
"wg_private_dns1.age".publicKeys = [ dns1 ]; "wg_private_dns1.age".publicKeys = [ dns1 ];
"wg_private_dns2.age".publicKeys = [ dns2 ]; "wg_private_dns2.age".publicKeys = [ dns2 ];
"wg_private_vps1.age".publicKeys = [ vps1 ]; "wg_private_vps1.age".publicKeys = [ vps1 ];
"wg_private_vps2.age".publicKeys = [ vps2 ];
"wg_private_vps3.age".publicKeys = [ vps3 ]; "wg_private_vps3.age".publicKeys = [ vps3 ];
"wg_private_vps4.age".publicKeys = [ vps4 ]; "wg_private_vps4.age".publicKeys = [ vps4 ];
"wg_private_vps5.age".publicKeys = [ vps5 ]; "wg_private_vps5.age".publicKeys = [ vps5 ];

View file

@ -1,6 +1,5 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 LZU5Eg dlH/b9FXAowA5m9KYdF+MirRu9fKXhf76jHXuKA6OAI -> ssh-ed25519 LZU5Eg C3IfbvL4t0pOHEb3Bc54+r6DZESgN6K6zPDhBlDumXk
ADHjmdwYkyd24vbi2jbeI9GmFZuf86/Twm48J3g958s UwOtrqp8I90Vux6L7CsV5K+2SDFB8LBiyLO8ud7IsQU
--- WVLjItfhBqlv55yTzq0/OzfTSfD1ypQfu9EGFf1vUUE --- 2tIecoG70broXFTtgjCUMcvk2RdKqpe5tihO6meI8DY
ś‚Ě<ń{©\VLv 泓、kユレウ& ミ`!ヘ藪_致`<60>マ-。ヤEp^<5E>ザ#:ゥ壌]ム優mサヒy<EFBE8B>厥^O†+t8ァ€<EFBDA7>.コ鉷奘; ョ
Î+Ôv_Ź#PI§¬ăF%(ă„ ¶˛ö>µëôăČźC'nË ő1|jNťüŹŇÔT^6ÇoĹâ

View file

@ -1,5 +1,6 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 5bWSnQ Li1ITKUHcUQFJX0NQCaz9Abjf6NjyVGTwE9WAzjJAU0 -> ssh-ed25519 5bWSnQ wqkRMdob+7G2mTNKySF2kiGhOKt4GLN/ne+4lM3pIwA
UekGYi4xmM88U0BX52iKGWnBTWCGrxMyMeN6zed12D4 Iz2Brik6I6YHjVxQcoDL0UTJOWcjuiErf5kCeWpnaV0
--- MUD9AikW/zNM+W3GiR23pw95ZsDhsxZVn5EMqr0X+DU --- 1ZkP0GiP78eGKl8te1w+o5I5kEbyPaiJFq7WGH4k1LE
Ê‚ý×]?@¥êTHôÀ]~œ?7qéãýŒÍ"W…+`·Ñ<1A>¥+Lµ]ö­‚»Êaœ­ÎSx*¥¹]6Љf¹îÀ á61zIìTÂU/ò5ã'|Œ½ûÊÌþìhÕ>z±ñ¶Ýr^Éwanog´lùX„º,kܶG
cÊõ¸æPÇ!Rh×»fW¥éhä §

View file

@ -0,0 +1,5 @@
age-encryption.org/v1
-> ssh-ed25519 pP9cdg GI2CXAYTJWUqmab/Fnl/cFZVCCBxYZX/snQ+w0aPjSk
8D6TxN4VYH14GQJ/XhUqyfKNLjM8f3LDmykLAvtl+IM
--- 6ru8v60LKlJjpy2PnmcwBdV09KMEh+neITYyuFscSIQ
F Й¿y#<ﯗÖmàߘžº¦¼Q2Õ^T2Lâ9µ]LÄžµhž[b¼rߤ!ï³jEnS?¾ìjCRà%„ÓsŸ;mœƒ\R

View file

@ -1,5 +1,5 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 XzACZQ J67LUjHa64q/z1K8zZpx1rsnoQ94NzhkeXEpfNr4ZVQ -> ssh-ed25519 XzACZQ pOD3jNWIufLkEVtkFJu6W0QjdzPJTK+t1MwgACv1zXU
dy5Tre9IicxhLBHoqvQAZepG7bNg2dEXFT5iPRcWOcA EJQ+9xPw6MnB6nJW6nDBUlzfHyY9XlfBIQlgje+FVE4
--- 9dJKhJeue6VNi0Sw05BX/t8jsxXyRIKz0K3/sy0kT7w --- BmTwJED+mJ/Qr0WFDELozwR2BgGDkHDcR2I9eSxuVn8
Ýh9ÎÛËi£·ÀÍs¡ØâM =TnÕw€W)<29>õ€Ûòêã²îÃ\ÇÕ<2*%æ_ëå×ܳ¿«ôgÇLñõN5c—D5ô@áÍ»ÂØ KêÃ~alNh.€½ù «kiAÛF*Ã/MY±ñ¡Zd†¬p”AÉ+-²Ù¬A<C2AC>¹Ü¢*S¥Z¶ï„ Nê­F­fˆbô3tª×rûÇy

View file

@ -1,5 +1,6 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 51bcvA P7ouUh98Mfi9Jsu6MDWaWH0NB2alXRIK8hxBIs0Nylg -> ssh-ed25519 51bcvA mzB9FcwUgPczK4/Rd2DZvCYoQfjT4qE+Z7HE9yHjgGU
tUZ1sWLlvPizsSWhK3fnVVhr4C9Ign5rwowxePGXFII sPDlr+YNhvbjYagyJb/kua9dWeG9tSt6KNjKh+/p+ps
--- PHPizXT8GPP9mIFg1paqqc8w3qsX63XpLkeT0APybik --- uZVoWpqKjapTtWRGpc7cUoifwOVFfd5DU+9pQpwruuo
´B§?*8-nËLsÍj< k*.@¯ªœé6K‡Ug ×'8¼ Ñ#Žòíhç.l~Sà3£%¶šÀ!ŸVYK•l¿R¾ ´Ôؘo Fv6¾œÚËï,ø»K¶¶Ó†(ÍÝèkÙ~Y4Á.`z(]w2²MV "¼%À³JUÚ$ô•È«ÁǸCïG
_:F¸Ý§ S

View file

@ -1,5 +1,5 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 vT7ExA 9+j3VYkFAW1obbLc31nv+45SyPMqH1zZPkI+PU4lVH8 -> ssh-ed25519 vT7ExA WsT1cFerSGwOnhrLBTN62zydQVC1oPQxXtwQxGUSY1w
G9QkkyTNH499EWhjiXCyXt7HgHlzJTZsaLiR+yOF18E Je1zd3NJ16yaOHQD8iPX7eaPJV3WH6Z3eiDkFip/2FY
--- vq7bT3yTioJ1UsD7hSu5jyYKhOE6UMIMsosu4f5pK1w --- J6ZhIFcXF12n+pV4JEaAut/QB2c5ycYSIGo6j3nLICQ
Q±<>žž¹ýÁ˜ÅVÐé#<23>(7èýÎEYÉÛÅÌ\ú££Z¨?GÙ«ç_C ÛI¦î ЉgNi´V¯åe]•¢tx@¸w+ SńOĆŤ<EFBFBD>žsIµ˝öüÜLJăŢ i—=Ům|,gőnYÖDv·ćA âd{Á·á q)~Ă3Ó!ó8¶ ·«ŢěńxPçÚńL7™"

View file

@ -1,5 +1,5 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 qM6TYg sAwuep3NgetXEKK5N8ZFP6Y0IDAGtTLIXH1hh5L0Hyc -> ssh-ed25519 qM6TYg n/6/3HfVk0IWfGRbgBB7qLkEXylLgYDxNzbLTaJWyhs
8pB7uytmRSkJMKi5S9YSLHKLgpYKkv5w2WaKaJL9sT4 jNP6viJqbOgpNke072hDeaGmApVc51wAN/O+8Gc58U4
--- JucAnOMMuFLpIyg9t+Azths9ttk6by6SKcMWA6Cwa+0 --- WoF4XMNOMMwKJ16Q7QrH97cGdyJ4nB4Dw04dyznfmL8
v§õÐ(TR͘ä´<C3A4>JpÂDòÀ%J—*^îl—ß±½ÂY…/‰§ê'®zBÙž˜Áë÷4§±GÛ6Æ·(å‹ /\,Wérææ7 ééeón€%á²@<40> þÿ#ÙÖõ"ØLËÆi"W€µ<E282AC><>AEŒèû-?Ø•´ìæ´~Z¿\±éÞðgO¨&Ùõ¥´õÊx¤»³vÈç —¼þ¹¢&w]ý"¢¿S2VɯÁ/”É

Binary file not shown.

View file

@ -1,5 +0,0 @@
---
- name: Generic setup
ansible.builtin.import_playbook: ./basic-setup.yml
- name: VPS 2
ansible.builtin.import_playbook: ./vps2.yml

View file

@ -1,112 +0,0 @@
---
- name: Basic Server setup
hosts: all
gather_facts: false
tasks:
- name: Change hostname
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
- name: apt update
ansible.builtin.apt:
update_cache: true
upgrade: yes
- name: Install fish
ansible.builtin.apt:
name: "fish"
state: present
- name: "Change root's shell to fish"
ansible.builtin.user:
name: root
shell: /usr/bin/fish
- name: Install useful tools
ansible.builtin.apt:
name: "{{ item }}"
state: present
with_items:
- htop
- awscli
- name: Install keyring packages
ansible.builtin.apt:
name: "{{ item }}"
with_items:
- debian-keyring
- debian-archive-keyring
- apt-transport-https
- name: Add caddy keyrings
ansible.builtin.shell: |
set -euo pipefail
rm -f /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# todo: show ok/changed
args:
executable: /bin/bash
- name: Add caddy repository
ansible.builtin.get_url:
url: "https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt"
dest: "/etc/apt/sources.list.d/caddy-stable.list"
mode: "u=rw,g=r,o=r"
- name: Add the docker GPG key
ansible.builtin.get_url:
url: "https://download.docker.com/linux/ubuntu/gpg"
dest: "/etc/apt/keyrings/docker.asc"
mode: "u=r,g=r,o=r"
- name: Add docker repository
ansible.builtin.copy:
dest: "/etc/apt/sources.list.d/docker.list"
content: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu jammy stable"
- name: Install docker
ansible.builtin.apt:
name: "{{ item }}"
state: present
with_items:
- docker-ce
- docker-ce-cli
- docker-compose-plugin
- name: Ensure docker is started
ansible.builtin.service:
name: docker
state: started
- name: Install caddy
ansible.builtin.apt:
name: caddy
state: present
args:
update_cache: true
- name: Ensure caddy is started
ansible.builtin.service:
name: caddy
state: started
- name: Create debug html root
ansible.builtin.file:
path: /var/www/html/debug
state: directory
mode: "u=rwx,g=rx,o=rx"
- name: Create debug webserver file
ansible.builtin.copy:
dest: /var/www/html/debug/index.html
src: "../debug.html"
mode: "u=rw,g=r,o=r"
- name: Copy Caddyfile
ansible.builtin.copy:
dest: /etc/caddy/Caddyfile
src: "../{{ inventory_hostname }}/Caddyfile" # TODO: Choose the right caddyfile depending on the server.
mode: "u=rw,g=r,o=r"
notify:
- "Caddyfile changed"
- name: Create /apps
ansible.builtin.file:
path: /apps
state: directory
mode: u=rwx,g=rx,o=rx
- name: Copy docker-compose
ansible.builtin.copy:
dest: /apps/docker-compose.yml
src: "../{{ inventory_hostname }}/docker-compose.yml" # TODO: choose the right directory
mode: "u=r,g=r,o=r"
handlers:
- name: "Caddyfile changed"
ansible.builtin.service:
name: caddy
state: reloaded

View file

@ -1,4 +0,0 @@
vps:
hosts:
vps2:
ansible_host: vps2.noratrieb.dev

View file

@ -1,97 +0,0 @@
---
- name: VPS 2 setup
hosts: vps2
gather_facts: false
tasks:
- name: Copy backup file
ansible.builtin.copy:
src: "../vps2/backup.sh"
dest: "/apps/backup.sh"
mode: "u=rx,g=rx,o=rx"
- name: Configure backup cron
ansible.builtin.cron:
name: Daily backup
minute: "5"
hour: "7"
job: "/apps/backup.sh"
#####
# APP: karin bot, /apps/karin-bot
#####
- name: Create /apps/karin-bot
ansible.builtin.file:
path: /apps/karin-bot
state: directory
mode: "u=rwx,g=rx,o=rx"
- name: "Copy karin .env secret"
ansible.builtin.copy:
dest: "/apps/karin-bot/.env"
src: "../secrets/karin-bot/.env"
mode: "u=r,g=r,o=r"
# TODO: Mount a volume in the karin-db to this directory
#####
# APP: cors-school, /apps/cors-school
#####
- name: Create /apps/cors-school
ansible.builtin.file:
path: /apps/cors-school
state: directory
mode: "u=rwx,g=rx,o=rx"
- name: Copy secret envs
ansible.builtin.copy:
dest: "/apps/cors-school/{{ item }}"
src: "../secrets/cors-school/{{ item }}"
mode: "u=r,g=r,o=r"
with_items:
- bot.env
- db.env
- server.env
#####
# APP: minecraft server, /apps/minecraft
#####
- name: Create /apps/minecraft
ansible.builtin.file:
path: /apps/minecraft
state: directory
mode: "u=rwx,g=rx,o=rx"
- name: Copy minecraft secrets
ansible.builtin.copy:
dest: "/apps/minecraft/.env"
src: "../secrets/minecraft/.env"
mode: "u=r,g=r,o=r"
#####
# APP: openolat, /apps/openolat
#####
- name: Create /apps/openolat
ansible.builtin.file:
path: /apps/openolat
state: directory
mode: "u=rwx,g=rx,o=rx"
- name: Copy extra properties
ansible.builtin.copy:
dest: /apps/openolat/extra-properties.properties
src: ../apps/openolat/extra-properties.properties
mode: "u=r,g=r,o=r"
- name: Olat data file permissions # TODO: a bit hacky.
ansible.builtin.file:
path: /apps/openolat/olatdata
state: directory
mode: "u=rwx,g=rwx,o=rwx"
#####
# END: docker compose up!
#####
# We want this to be last so that all app-specific config has been done.
- name: Copy .env
ansible.builtin.copy:
dest: "/apps/.env"
src: "../secrets/vps2.env"
mode: "u=r,g=r,o=r"
- name: Docker compose up! 🚀
community.docker.docker_compose_v2:
project_src: /apps
state: "present"
#####
# POST: things after starting up
#####
- name: Run CORS db migrations
ansible.builtin.shell: |
docker exec -w /app/server cors-school-server diesel migration run

View file

@ -1,23 +0,0 @@
#!/usr/bin/env bash
# Copies a base64 encoded deploy key to the servers.
set -eu
printf "Enter private key (base64 encoded): "
read -r key64
private=$(echo "$key64" | base64 -d)
public=$(ssh-keygen -f <(echo "$private") -y)
tmp=$(mktemp -d)
echo "$private" > "$tmp/id"
echo "$public" > "$tmp/id.pub"
delete() {
rm -r "$tmp"
}
trap delete EXIT
ssh-copy-id -i "$tmp/id" root@vps1.nilstrieb.dev
ssh-copy-id -i "$tmp/id" root@vps2.nilstrieb.dev

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,47 +0,0 @@
{
email nilstrieb@gmail.com
}
# https://gist.github.com/ryanburnette/d13575c9ced201e73f8169d3a793c1a3
(cors) {
@cors_preflight{args.0} method OPTIONS
@cors{args.0} header Origin {args.0}
handle @cors_preflight{args.0} {
header {
Access-Control-Allow-Origin "{args.0}"
Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
Access-Control-Allow-Credentials "false"
Access-Control-Allow-Headers "${args.1}"
Access-Control-Max-Age "86400"
defer
}
respond "" 204
}
handle @cors{args.0} {
header {
Access-Control-Allow-Origin "{args.0}"
Access-Control-Expose-Headers *
defer
}
}
}
vps2.nilstrieb.dev {
root * /var/www/html/debug
file_server
}
old-docker.noratrieb.dev {
reverse_proxy * localhost:5000
}
api.cors-school.nilstrieb.dev {
import cors https://cors-school.nilstrieb.dev "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token,refresh-token,Authorization"
reverse_proxy * localhost:5003
}
cors-school.nilstrieb.dev {
reverse_proxy * localhost:5004
}

View file

@ -1,76 +0,0 @@
#!/usr/bin/env bash
set -euxo pipefail
BUCKET=nilstrieb-backups
PREFIX="1/$(date --rfc-3339 seconds --utc)"
cd /apps
function upload_file {
local file="$1"
local tmppath
tmppath="$(mktemp)"
cp "$file" "$tmppath"
xz "$tmppath"
aws s3api put-object --bucket "$BUCKET" --key "${PREFIX}/${file}.xz" --body "${tmppath}.xz"
rm "$tmppath.xz"
}
function upload_pg_dump {
local appname="$1"
local containername="$2"
local dbname="$3"
local username="$4"
local tmppath
tmppath="$(mktemp)"
docker exec "$containername" pg_dump --format=custom --file /tmp/db.bak --host "127.0.0.1" --dbname "$dbname" --username "$username"
docker cp "$containername:/tmp/db.bak" "$tmppath"
xz "$tmppath"
aws s3api put-object --bucket "$BUCKET" --key "${PREFIX}/$appname/postgres.bak.xz" --body "$tmppath.xz"
docker exec "$containername" rm "/tmp/db.bak"
rm "$tmppath.xz"
}
function upload_dump_mongo {
local appname="$1"
local containername="$2"
local usernamepassword="$3"
local tmppath
tmppath="$(mktemp)"
docker exec "$containername" mongodump --archive=/tmp/db.bak --uri="mongodb://${usernamepassword}@127.0.0.1:27017"
docker cp "$containername:/tmp/db.bak" "$tmppath"
xz "$tmppath"
aws s3api put-object --bucket "$BUCKET" --key "${PREFIX}/$appname/db.bak.xz" --body "$tmppath.xz"
docker exec "$containername" rm "/tmp/db.bak"
rm "$tmppath.xz"
}
function upload_directory {
local appname="$1"
local directory="$2"
local filename="$3"
local tmppath
tmppath="$(mktemp)"
tar -cJf "$tmppath" "$directory"
aws s3api put-object --bucket "$BUCKET" --key "${PREFIX}/$appname/$filename" --body "$tmppath"
rm "$tmppath"
}
upload_pg_dump "cors-school" "cors-school-db" "davinci" "postgres"
# shellcheck disable=SC1091
source "karin-bot/.env"
upload_dump_mongo "karin-bot" "karin-bot-db" "$MONGO_INITDB_ROOT_USERNAME:$MONGO_INITDB_ROOT_PASSWORD"
upload_directory "openolat" "openolat/olatdata" "olatdata.tar.xz"
echo "Finished backup!"

View file

@ -1,109 +0,0 @@
version: "3.8"
services:
#### Karin
karin_bot_db:
container_name: karin-bot-db
image: "mongo:latest"
restart: always
volumes:
- "/apps/karin-bot/data:/data/db"
environment:
RUST_LOG: info
PRETTY: "true"
env_file:
- "/apps/karin-bot/.env"
networks:
- karin-bot
deploy:
resources:
limits:
cpus: "0.5"
memory: 500M
karin_bot:
container_name: karin-bot
image: "docker.noratrieb.dev/discord-court-bot:921be642"
restart: always
env_file:
- "/apps/karin-bot/.env"
environment:
DB_NAME: court_bot
MONGO_URI: "mongodb://karin-bot-db:27017"
RUST_LOG: INFO
PRETTY: "false"
networks:
- karin-bot
#### Cors School
cors_school_db:
container_name: cors-school-db
image: "postgres:latest"
restart: always
volumes:
- "/apps/cors-school/data:/var/lib/postgresql/data"
env_file:
# POSTGRES_PASSWORD=PASSWORD
- "/apps/cors-school/db.env"
environment:
POSTGRES_DB: davinci
PGDATA: "/var/lib/postgresql/data/pgdata"
networks:
- cors-school
cors_school_server:
container_name: cors-school-server
image: "docker.noratrieb.dev/cors-school-server:bef75a80"
restart: always
env_file:
# DATABASE_URL=postgres://postgres:PASSWORD@cors-school-db/davinci
# JWT_SECRET=secret
- "/apps/cors-school/server.env"
environment:
RUST_LOG: info
networks:
- cors-school
ports:
- "5003:8080"
cors_school_client:
container_name: cors-school-client
image: "docker.noratrieb.dev/cors-school-client:bef75a80"
restart: always
ports:
- "5004:80"
cors_school_bot:
container_name: cors-school-bot
image: "docker.noratrieb.dev/cors-school-bot:bef75a80"
restart: always
volumes:
# DISCORD_TOKEN=
# CORS_API_TOKEN=
- "/apps/cors-school/bot.env:/.env"
environment:
APPLICATION_ID: "867725027080142870"
RUST_LOG: info
BACKEND_URL: "http://cors-school-server:8080/api"
networks:
- cors-school
# minecraft_server:
# container_name: minecraft-server
# image: itzg/minecraft-server:latest
# restart: always
# environment:
# - TYPE=VANILLA
# - VERSION=1.20.1
# - DIFFICULTY=HARD
# - EULA=TRUE
# - MOTD=baden
# - MEMORY=6G
# - MODE=creative
# - PVP=true
# - SERVER_NAME=hallenbad
# - USE_AIKAR_FLAGS=true
# env_file:
# # For example, storing the WHITELIST and OPS
# - /apps/minecraft/.env
# ports:
# - "25565:25565"
# volumes:
# - /apps/minecraft/server:/data
networks:
cors-school:
karin-bot: