From d43fb3016d1d9f6d22326c5948058470a16bfea3 Mon Sep 17 00:00:00 2001 From: Nickolaj Jepsen Date: Thu, 22 Jan 2026 00:00:45 +0100 Subject: [PATCH] feat: add forgejo --- .github/copilot-instructions.md | 3 +- modules/homelab/default.nix | 1 + modules/homelab/forgejo.nix | 75 ++++++++++++++++++ modules/homelab/glance.nix | 6 ++ modules/system/ssh.nix | 10 +++ secrets/forgejo-ssh-key.age | Bin 0 -> 792 bytes ...2c8735530cc4358f5c0913-forgejo-ssh-key.age | Bin 0 -> 775 bytes ...7d4308015913d2d7b32915-forgejo-ssh-key.age | 8 ++ ...1b7de6d9abcae5a166f745-forgejo-ssh-key.age | Bin 0 -> 776 bytes ...2ab73cb530a2edc55-forgejo-runner-token.age | Bin 0 -> 377 bytes ...9576a0aea8c75c70c4fb53-forgejo-ssh-key.age | Bin 0 -> 681 bytes .../hosts/homelab/forgejo-runner-token.age | 9 +++ ...1b7de6d9abcae5a166f745-forgejo-ssh-key.age | Bin 0 -> 736 bytes ...88df9084e07b44b361d309-forgejo-ssh-key.age | Bin 0 -> 702 bytes 14 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 modules/homelab/forgejo.nix create mode 100644 secrets/forgejo-ssh-key.age create mode 100644 secrets/hosts/bootstrap/.rekey/bdc52981b52c8735530cc4358f5c0913-forgejo-ssh-key.age create mode 100644 secrets/hosts/desktop-wsl/.rekey/9a411f84fe7d4308015913d2d7b32915-forgejo-ssh-key.age create mode 100644 secrets/hosts/desktop/.rekey/a3fe8763891b7de6d9abcae5a166f745-forgejo-ssh-key.age create mode 100644 secrets/hosts/homelab/.rekey/387158a9d90fcba2ab73cb530a2edc55-forgejo-runner-token.age create mode 100644 secrets/hosts/homelab/.rekey/a9c15eed169576a0aea8c75c70c4fb53-forgejo-ssh-key.age create mode 100644 secrets/hosts/homelab/forgejo-runner-token.age create mode 100644 secrets/hosts/laptop/.rekey/a3fe8763891b7de6d9abcae5a166f745-forgejo-ssh-key.age create mode 100644 secrets/hosts/work/.rekey/a3e27d220088df9084e07b44b361d309-forgejo-ssh-key.age diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 49c0aa0..da9edcc 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -68,6 +68,7 @@ just secret-edit # Edit an encrypted secret ### Safety Boundaries **CRITICAL**: As an AI agent, you are **FORBIDDEN** from executing commands that permanently modify the system state or perform remote deployments. + - **DO NOT** run `just switch` or `just boot`. - **DO NOT** run `just switch `. - Use `just test` or `just build-system` if you need to verify that a configuration builds successfully. @@ -85,7 +86,7 @@ Secrets use agenix + agenix-rekey with YubiKey master identity: ## Adding New Features 1. **New program**: Create `modules/programs/.nix`, guard with `lib.mkIf config.fireproof.desktop.enable` or similar -2. **New homelab service**: Create `modules/homelab/.nix`, add to `modules/homelab/default.nix` imports +2. **New homelab service**: Create `modules/homelab/.nix`, add to `modules/homelab/default.nix` imports, and **add a link to the dashboard in `modules/homelab/glance.nix`** 3. **New host**: Run `just new-host `, then add to `hosts/default.nix` ## Common Patterns diff --git a/modules/homelab/default.nix b/modules/homelab/default.nix index f2cbdf3..b3dd8b6 100644 --- a/modules/homelab/default.nix +++ b/modules/homelab/default.nix @@ -7,6 +7,7 @@ ./arr.nix ./audiobookshelf.nix ./freshrss.nix + ./forgejo.nix ./glance.nix ./home-assistant ./jellyfin.nix diff --git a/modules/homelab/forgejo.nix b/modules/homelab/forgejo.nix new file mode 100644 index 0000000..a20e1cc --- /dev/null +++ b/modules/homelab/forgejo.nix @@ -0,0 +1,75 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.mkIf config.fireproof.homelab.enable (let + domain = "forgejo.nickolaj.com"; +in { + age.secrets.forgejo-runner-token = { + rekeyFile = ../../secrets/hosts/homelab/forgejo-runner-token.age; + mode = "0600"; + }; + + services.forgejo = { + enable = true; + database.type = "postgres"; + dump = { + enable = true; + interval = "daily"; + }; + settings = { + server = { + DOMAIN = domain; + ROOT_URL = "https://${domain}/"; + HTTP_PORT = 3000; + HTTP_ADDR = "127.0.0.1"; + }; + service = { + DISABLE_REGISTRATION = true; + ENABLE_INTERNAL_SIGNIN = false; + }; + actions = { + ENABLED = true; + }; + }; + }; + + services.gitea-actions-runner = { + package = pkgs.forgejo-runner; + instances.homelab = { + enable = true; + name = "homelab"; + url = "https://${domain}"; + tokenFile = config.age.secrets.forgejo-runner-token.path; + labels = [ + "ubuntu-latest:docker://node:20-bookworm" + ]; + }; + }; + systemd.services.gitea-runner-default.serviceConfig.DynamicUser = lib.mkForce false; + + services.postgresql = { + ensureDatabases = ["forgejo"]; + ensureUsers = [ + { + name = "forgejo"; + ensureDBOwnership = true; + } + ]; + }; + + services.restic.backups.homelab.paths = [ + config.services.forgejo.stateDir + config.services.forgejo.dump.backupDir + ]; + + services.nginx.virtualHosts."${domain}" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:3000"; + }; + }; +}) diff --git a/modules/homelab/glance.nix b/modules/homelab/glance.nix index 426df8f..c3534cd 100644 --- a/modules/homelab/glance.nix +++ b/modules/homelab/glance.nix @@ -216,6 +216,12 @@ in { icon = "sh:freshrss"; same-tab = true; } + { + title = "Forgejo"; + url = "https://forgejo.nickolaj.com"; + icon = "sh:forgejo"; + same-tab = true; + } { title = "Sonarr"; url = "https://sonarr.nickolaj.com"; diff --git a/modules/system/ssh.nix b/modules/system/ssh.nix index ab83071..3ebbba9 100644 --- a/modules/system/ssh.nix +++ b/modules/system/ssh.nix @@ -17,6 +17,11 @@ in { mode = "0600"; owner = username; }; + age.secrets.forgejo-ssh-key = { + rekeyFile = ../../secrets/forgejo-ssh-key.age; + mode = "0600"; + owner = username; + }; age.secrets.ssh-key-ao = lib.mkIf workEnabled { rekeyFile = ../../secrets/ssh-key-ao.age; mode = "0600"; @@ -40,6 +45,11 @@ in { hostname = "x.nickolaj.com"; user = "nickolaj"; }; + "forgejo.nickolaj.com" = { + hostname = "forgejo.nickolaj.com"; + user = "git"; + identityFile = "${config.age.secrets.forgejo-ssh-key.path}"; + }; } // lib.optionalAttrs workEnabled { # Work hostnames definded in ./networking.nix diff --git a/secrets/forgejo-ssh-key.age b/secrets/forgejo-ssh-key.age new file mode 100644 index 0000000000000000000000000000000000000000..6adb410a665f0fa8ba65f91f661c1e24bb32df78 GIT binary patch literal 792 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR2FFfuhYv{VQ&b@eqcO0sZtck>VMEJ)Qa zjz|s8bPTjKN>2AS@eQjgi_$N3PmVHm%I7l3axcwxaV&H$b#aL_E-6nk$j$bPN;HlN zEf3H1$x1Q}(yk12OfR&^iUiqEkXfc%U}S2hP-yJq7gny|SQuIrWn%2@T;Le)7ZPmX z=I3kXYZ+1zo}HTRl4xNTUQv>s?vaw~6XagV6=f8ZQdMT)Vjhu~7ie5uf*WEI( zC^^TXvN+2q$IC0<(%-MtuuMBk+u64;(=e^Fs<_z2KRrJs$1|NvS65dd-KQ!ryg0-s z%qTdyIMBti)Z0DVB;BLZS=%en+r&35+11FxEF_{bxY(D=!sS70&HY?K=H<^1CHE~% z>${nFSgc-0Wlx!kc%1yww-5H~N~i|0AHCJ${-Dl*&nqu#Yq-mvNmmg+*kQZN)$yR&if66q=FO}Qa4x2>SuUgT!SMo_=<}D9Zg?F$u`T9b)0vs& z`&~1-5%#S8dPweE7;{$F(NiY>q;*H>Y*7F0XAAJZfURzin05 zUe71e;kW*$mS=2A3Hs)7B~Vp${<&RwmDA>aczr`}+p5JiOU^mWPcr>=E-bF}vq0P2 zY4KivTX+=2B!lb^OL3kz6baARcj3^@AM2k*#LVuoY3;9mnl;f;b*;wtg)Zz(yBC$L zI^`-AaF1E_gG^P9t4emNbSB(vu5`*Z(a`-o25utd2+^4F@9E4Rz6 zmSvcbGil1>GPCmvVUs63o4+%|rjvc$Kj{q@CcKZHzslNc*Jr*yH|zUNPp+Kw_Oev@ mkU!Z(C9Kqpvvpkuo3j1S>D?#UchnWsZ@L_0E7mJ1e-HpzV@T2f literal 0 HcmV?d00001 diff --git a/secrets/hosts/bootstrap/.rekey/bdc52981b52c8735530cc4358f5c0913-forgejo-ssh-key.age b/secrets/hosts/bootstrap/.rekey/bdc52981b52c8735530cc4358f5c0913-forgejo-ssh-key.age new file mode 100644 index 0000000000000000000000000000000000000000..b7608a649ef8e68676fd3c9d0c070e0f4459ab09 GIT binary patch literal 775 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCUlH1x9w2~@B&2#hi? z*3R@T_X{)EPf2w$DDgJ*$`17M@yj;yEy+uAchpYyOiwP4$mc3fH7yTvGEU8Rw#>*g z3-$Ezuk;9wbob3DD#>$<46jHwiF8jdON$B$%Ldt&S)QY&n_iTfSe&Y0rCx2IZl_?* zcd!XBJ^$;2D&fnQi83YUJUoM=`Q<>!&@ADmW| z?Cl#A5E|y`9hhAf&gJ8$9hH*qR$fryk)IP_>Yr?AWad$pn3?Zn;+f;0pPQ4E>E=?E z8x)%BXBm`b5S)^4>2BegUy$LKV`x&&rK_u}5L}evlu=w_T3T3@Y-*bAX;Bc7muupa zVj1a{nCxF{U=m{P>s9F%oSk3JC4N!ukKHxPwND+nT(ib z>3ojIPrc1t9_aq67rfNI;?T>TMdCU-F}HK-oBayLp z?X!v*qMq4Hr~Y4iR&2I#K=zNPf^ikr3sdLTJNT(JYW@*o)3`Qs;+5NHLUP@i5+<;^ zZJF`wQO`53O~HZn`?x>!t#g=JSNGyzNb!ne$M>w4Oy1)AA$#w|J?p)D7tT#`dBros amxEKecvhep#|)nSB^pO&Hm`49S`7e7!%g7; literal 0 HcmV?d00001 diff --git a/secrets/hosts/desktop-wsl/.rekey/9a411f84fe7d4308015913d2d7b32915-forgejo-ssh-key.age b/secrets/hosts/desktop-wsl/.rekey/9a411f84fe7d4308015913d2d7b32915-forgejo-ssh-key.age new file mode 100644 index 0000000..6f2be36 --- /dev/null +++ b/secrets/hosts/desktop-wsl/.rekey/9a411f84fe7d4308015913d2d7b32915-forgejo-ssh-key.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 KDYMLA 3XX1km6w6wqWFXVoPVo9+pHr9POhVlQ2ITm0b9Rc2Xo +syQAnCjVkK8FuVj/rv05mC3uo3FyNJW8TG6LhqnokEI +-> 8Ae$E-grease M1 +PcS1jY8MbdwwWwPCRvBBYVkRmvD9UUQyjCgJtmKdBUw+Ziv7 +--- Gjix1IgomW7LXSfoOXRm4/zMXHfS5WFeD4C5nYwxH30 +wqQ {4_VN?C3?Vۛ,b_,\rY4ޫ9zKb=(&3x5F\t`-J~)Mb`#-LKjp Rx+ H&ݕKU +e%c/=XڬGCݺ2>-(YxѶ73gى k,-X$u6|VͱlNĘ 4 o„*ώNL3k YB-j)vR37R~O!'{T +&s-zr wȁhfػʎkT9`eG8Qj*6ٳ&V+j$6,KLw0ΰ+7?.iHL("jҴ #yqXmNOQ{1-gOG, y s \ No newline at end of file diff --git a/secrets/hosts/desktop/.rekey/a3fe8763891b7de6d9abcae5a166f745-forgejo-ssh-key.age b/secrets/hosts/desktop/.rekey/a3fe8763891b7de6d9abcae5a166f745-forgejo-ssh-key.age new file mode 100644 index 0000000000000000000000000000000000000000..c86ea75fdc32acf9665fb01b50231bb2224d6123 GIT binary patch literal 776 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCR+Ep!ddFIR{PH!?}~ zt@3m+F;0urj&w6Obl3MWjm#+YOD_m3F840Yb4*P$aCP^pDCa6N(l2odOb#`4igJt$ zF-=Z1HrIFc%8l^L_bYKvF4y)7GS4pw2`bPo3kBI09UWzqRim3;l$uzast}W_RcREU zP-|ONrc{(~%N5{Q78w-m7U)}E=u%YT9_*H$Zj^3T<{X;jn^TY*7U)u$Yh2`;=2h&L zZ0MYm=xLN+Sm9?9mFnqPm|mD$?#Ja(rEQd+P3x&ZVoXtB_ulU6@hs=n`5U=vkWLXzm_V>gO4$ zpPiYSQfO}KlU@`aneAaz9OP$ez;$+8p2WObVb4Xonaefblx+DD#JW1#o%_^- z32P?S{pPwoujg#!QsYF|l&=@h&pLdr;_%s%MqIoMY)*&d*9qMeYitdER+uj$bBk$H z{rf$u-k&|xzxR#ej@ir4NneV+xnKTQysB87Mmh8DJeg2oxvMKY&$+y)JRYW^bZ_g- zd5<6D$x1xrn8Bo5oil4++|CBsFNHPHs*BfQl~Z@ z5(~TY^Hsl>P5S*kD|5Z_O+~UhvJTwT+tce7b8r%`qwkxJ--$b>%(7xWF~L?QdghC) z^~{&t8vjW?^vs|Aw9G*Iw9|_RX?&C2j)+S}UpaKALa;9Rvs!`J9Vbcg+jgxCfxpFK aCzQPYX~b8&cGhD-3W9%PtL$NaiZ{^~`t5_AyF#OApR> z4ROg0clPng%Bu_u4>nB832=*a^-Rf0^GFW!jRe`|SRI+~rkh@rnpm8wkQf~Ao?)us zkmhHn5Nxhsp2L-!?UIs_YUJ$h=c?^iX^}GutE&)^rXLa% zVH)ZjQW6-Z?OGXNW)|x2>t^a2VPQ}j>YEstpQ>#c;u@4znayQzet+fUl_w^qmnk1! z^4`YyX4wzUmvaK<7acx*?d?zg&LsZ3NmtI88$XOlUem95GJerld#S$yN(`D2Ex)+@ X|J{CZ)$e=Y^yO!EFwV?2sr&{2C`pOd literal 0 HcmV?d00001 diff --git a/secrets/hosts/homelab/.rekey/a9c15eed169576a0aea8c75c70c4fb53-forgejo-ssh-key.age b/secrets/hosts/homelab/.rekey/a9c15eed169576a0aea8c75c70c4fb53-forgejo-ssh-key.age new file mode 100644 index 0000000000000000000000000000000000000000..a0a9ce43e940d7756fe310b621a19ce2d1f2edfa GIT binary patch literal 681 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCSHttixvDpv?9_epX$ z&W^}&ipb6MH*!x(^0CNw&qy`04AsuaE_W=;HS-O2v#{_EbLDbNu5c_fN%yTvOEe7D z4)8B`H7KjdbT2aYttvK3&-Qll2rM##pI;!|l<=uzQgR*@W-=@}H^;^hEO&y;|D$ss?c+Y$ zCSvw{UHQptwe}%SlFG?ZnU^+|{W`8O=N|j{Q2QlmmnPO;kn-BQILSt&;M0l#H-Y(= zih9f3gQn^jeL1s1Rq4RhYlpAa2E1`)fBB{TpVH1*uLM_YpPlq$POI%%bGgHpBGjMy zMP4z}49`1M^E-7-(vA-Xlgm%;&yLGlcIk1>XLfD#I>~2~3V(8jg)ZZjmz$e~i>%;9`-9DzrYAc~t+( zv6rVOyQe6xlAq7)e8^*Ju-4zRQ|B>H++{ys$6I)B X25519 /7xd7wW72ibsmB1cpyfT14TM+y2Qo0G/vTEURUZprmg +KPKazzWC9mxDGAcZLrTkjhmXq/RsJAp4mdZysjvQI6E +-> piv-p256 q3LNVw Axl/D2SGpYP/eHdoTrOrTgzZZdcNSNPcOhfkwnCsBzSH +L6TMeLKBtUGtlSLUcHh+XHNvfLi6iwgkznNldu+mmXQ +-> gdcz[!v-grease x `{t0 +mWsv +--- RGBGe47nVpK4mlxh8cUFzg8R52AAtY3iNUb7bYO6e1E +i1aekG} rƌ'֢$ULg|À/J@7i+ aAXTwWC3y)a]l \ No newline at end of file diff --git a/secrets/hosts/laptop/.rekey/a3fe8763891b7de6d9abcae5a166f745-forgejo-ssh-key.age b/secrets/hosts/laptop/.rekey/a3fe8763891b7de6d9abcae5a166f745-forgejo-ssh-key.age new file mode 100644 index 0000000000000000000000000000000000000000..e7f5a446e6bb82b20ad542ca065c94118dd196fa GIT binary patch literal 736 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCR+Ep!ddFIVu3$O|g0 zObK;0_Ab(P_R==Wtw>EV4f8Z8bBe4e_AJ!St1=3zEJ}8+a^y;NbV*4LP6`V&Pcclg zC^gIr&2tS&FNkpVsVH^~@XyP3&Mhbi()J572nE?z0cHQl9v}0?wpdHWa#2tnVVjoT9O#<7EqO9 z9Pa5}8SHEsmFyl;kyR3umFidF=9rwsWnNNQnp$XT801>+%cZNUtKd=SRABC#<(=-A zUZ(A&A0DWk6jJ0FniZK5>6aH}p5mXInqL*>l@Vf|&-GLKX^P**Z<*KUXxQI=Quwom z*;D%5>b&gixJhfZtqgOY`Mqi8+lSr^Pkt;77hFyA#vyPZimS;l-qW@ z)-}{CK7P5A&s;}*Y2sP)g91NFG>=5zW)obn{jT}{$VaR9B+e-16}!)zkzf4h4D08` zof$i1??|3_^!Kgk%_Ao7Us|Q#zp=N@bwvof)T_s@_&eGy%n!U-vaV`}TvPRjRspef z496C{?mF7jY5#s%=)=?Y%ss4EEhc=lEtaq9=~=vVS$2cZkADZg`)WBIoD_Us{r)GO znbZGWUJ-Cj-#J}7H~-PAISfa>iy9eU-Js2*Wv_8oWy9=U5|c0X+?EiWeO&Wpu8o%H z1Y_3c0$pd@)|LKczIx=X%muSnwx;La%A23dxD?%=aBS0}Nd?Ky+txL2?vgXv@a%#s zS60#ANo@SW@2{|Y->dsoaXx$3S^1mieO62Ac(BGl=-g*M<>ab@z4ia9%C=v#I}mnD zqG!p?k`j-vX0H|d&Rjn6UGsyOyR>^d!AQvrhebo?k#*H4`-wzSITEA}otZ;5w_7nhnEJA1i literal 0 HcmV?d00001 diff --git a/secrets/hosts/work/.rekey/a3e27d220088df9084e07b44b361d309-forgejo-ssh-key.age b/secrets/hosts/work/.rekey/a3e27d220088df9084e07b44b361d309-forgejo-ssh-key.age new file mode 100644 index 0000000000000000000000000000000000000000..bf23f6888dffd0eb73815f05fd0b8e36e85f500d GIT binary patch literal 702 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCR+4Kyw=D_5{Ah$u2B zO7?TFG72;fGfuA1HghvIH`Xqxj4X?ajED?R$qx@Q_lZi5Nak|Na&gNo%F5I?DDgM2 z$PCRlD+;O1NY081&o41DH!aL_G%`%hD9CVgOa|GeS(UDvUX+?xoT?C?k-`;jl9}mI zQ0ZJASe9rR;F(ognx7R^sa=s%Zsb{MYL;4Vlw0mom6zk>TjHBo>|0jq7G&TTkXlq! zRA|AatE;PET$-+*pIZ{8?Gs{}WK>p=n-}Puniy2#SLhj<>QQ3q=bITE;b^RF;Tp>2 zt{}pEPi>ofg7TWl3MWlF=WU&M(Ly>f!Rpf1uG-?O@>BR;_!Kb~h0Cw-zs7Sk)oL=A zLFJz2>cArx#dPQAs}^m)JxS!l$1h&1HUI1Y E081P=DF6Tf literal 0 HcmV?d00001