From fb4e658628a5d9a114526549ef9825c6943c0822 Mon Sep 17 00:00:00 2001 From: Diogo Carvalho Date: Fri, 18 Oct 2024 21:58:15 +0100 Subject: [PATCH 01/47] Fix entrypoint --- templates/compose/mosquitto.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/mosquitto.yaml b/templates/compose/mosquitto.yaml index 1ec6f0cdc..475d7cf39 100644 --- a/templates/compose/mosquitto.yaml +++ b/templates/compose/mosquitto.yaml @@ -32,7 +32,7 @@ services: echo ''listener 1883'' > /mosquitto/config/mosquitto.conf; fi && echo ''require_certificate ''$REQUIRE_CERTIFICATE >> /mosquitto/config/mosquitto.conf && - echo ''allow_anonymous ''$ALLOW_ANONYMOUS >> /mosquitto/config/mosquitto.conf && + echo ''allow_anonymous ''$ALLOW_ANONYMOUS >> /mosquitto/config/mosquitto.conf; if [ -n ''$SERVICE_USER_MOSQUITTO''] && [ -n ''$SERVICE_PASSWORD_MOSQUITTO'' ]; then echo ''password_file /mosquitto/config/passwords'' >> /mosquitto/config/mosquitto.conf && touch /mosquitto/config/passwords && From cf82f0a807f56c554451874c3d21a4f825480b01 Mon Sep 17 00:00:00 2001 From: Aleksandr Vasilenko Date: Tue, 22 Oct 2024 10:36:18 -0500 Subject: [PATCH 02/47] FoundryVTT Template --- public/svgs/foundryvtt.png | Bin 0 -> 35049 bytes templates/compose/foundryvtt.yaml | 37 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 public/svgs/foundryvtt.png create mode 100644 templates/compose/foundryvtt.yaml diff --git a/public/svgs/foundryvtt.png b/public/svgs/foundryvtt.png new file mode 100644 index 0000000000000000000000000000000000000000..c6a04508f3fbe4d3f0e4fe2d8bfc471ca8a0d35a GIT binary patch literal 35049 zcmbSy_g52LwDzQuLJ7T-&_SwzfV6~O1r$L9g-{fvqlk!7qo?7f`7dst}5b zs1yN3q=Y7*Nbe=NeBWC4AGq_&oLTG4nloqb{p|AWlVWRa%7PKV006*ZZf0~20HDW1 zD1d?;-#Y)3=mr27U~6^W`1tYvd_n&AO+99&;~~R9m|-EpI3vO^5@ryE879IEM-he( zo^e)$VI#t@6JcByVc3f>bcGqI1cn!$kwRcx#WO*0?*JEW_XG)5($iW0wb2d@DO3R;~8!ujMKu5ECM46&xj^4vIz_j z&xpY@G6{@a0ul;g0G5{t)^eHm3W3?_1ooB*n*}FIi3MTE!E}lh`Tiz9D8}k1#9XPsC4z<- z@}pctun%O|ZF$hj0!VE(@X0d*^QQzRH27Q2^Nt${ytCmgljV#*!FFAmMTQ44pvNbL zfgj}K8}zx$R5>@ygnp>=)v0i8k%ZEfaAmq&_w3m3o@GBPjDDiV8KT1a_A2i!BHOB+ zP>Un)!;>6^lI-qM%uAL+zpVs68SxfqaAcig|9*y_>dDt`z*~Qs+k${r6GDz%5IA^% z-?I`vAPFxR2v%Ei?>Gw|m{yBhQ2 zZQ;#(_|urb%4DYE$fAqS5&;zIE@m zRlj7u5S5tzFl?l#Xf)=@a%Ti*)xt6KODc#q{r(6Z1-Cxn&wx$3S8EIZ_d1*z(A**>I#dh{Y59=#mYxkDw#5mez4Zv!CX8cm}E{;`DvdZe{YDV!A#Ecv}gO} z>t{sQ>T}^X+Jcyr`me&PZwx9(MU^5Q&K%8{lo$Wt@S4_&49)%g81QX5KDl@Z5}#pj z*76c$I)Tn>59Kg8AW6Di@~i4R@4&?Yd*Q5XaztJK#6yMU#9Pv4^uj1vL1@3F|391h z2lK_`cc}qSUjX##Z$k^wdkN_WiAKd7ACh+(lyc%f6IdXRCN7OR1U)i)Wy~|-#1UJ; zyq-vBLoHc%DXwvF*lvX@#y8@q2l*4sg{Do>}zkQqbkxALsydmGfdav>G z>4Iwj3yb38cg*oBUm9z_0VmMB77M|XNkz?C@vp2as5)kbW@%%5pGA4erpJrZ-`#7K z78VKnaDBb~mbFM5)If5oWoD-J$xYL#zE3pOwHzHiUZB(lJ%8~JuESS_s6-=SQNM?m z+2e10I<#+3;lX_=eG|EA*RmIE4@(NHUSjFx&Jr9hf}%8ODC(w6$YWPjZ@LZNgqx<5V|sckKG^kD#67CYZb*1kP7+P{Wmhx zqN9;^r#PuhTipSG{t06n9RF*hyMoFz`sEp;tFYVMcV6?=F69hI=>ZVpycU-L^E1XoI} zAg)XoXyS&9Sn^f%!w-?z&XjBy&a+J)b>pRy$%1NMQ(JHLep1a-qpbQ#v20t?)^d4p zMg$f;k(bPu<6Q)3iUxC@5l1O+$sxNN2o|wx>JEneT4g`Q6vYI0Ds^Tw+7{Un)tk?) zXLwt`scHZ04;mNCiDzX`J9vEa%EH-0mQytc&#akli5s#En$9qVS6g6F8Qs4R)c=WV zt3OXPT)+H?XL&lk5)QeA{HKx=&oJIbwOrOK6edmv9sVWXdSU&qPu3?$@3T?IZ5E;8 z{hat?wcoajdW^g}om3(8_}joj#j@U$4Vw?`PY|J3?614PM^}@1a6#DX!?5#gOcdp;&@ zzTvQj!?#U7!KuPGPn_p4QC;?p-f^DMtg5(U*Yc|@X_Rxh%qRH2_#a-c|2vGHoS)is z9F(3o>?UsaJ}avfzdLhJ@q~TO=$U8jiH=cJ%oO7Su^Q&9r?S8wl{^+#oPVdbJ=clHM|NZ?= zQ~$^KQgEZUs6ZR=-3|EDtcvtVzk7MkETgh4o)P$`p0XF!?Z@o+`AKP2UN>jkNSw~6 z1O_U@&I&`}*T3Kz32S#=OOY*f(TPE~vAzVpV)+YtHpc<_=_BKP7s(jUI^~P~(s6s4 z`^Z>E*<6|Cf92J%H$5jI1)I6lH`LblGgCk!#B^8n6}#Wf@6E;&$?0Eix)NF|A*td8 z5_yxtyk!6uTg#nm3y@uEE|izWuk0tc#kOPwN)sKfh+M@Y|8-6a6EDZOk^VbNn?*V# zo{<~b3Sbx1GyKq0J+Srae6>olM9C}Gj-->bV)VPM_FrS^q&KM&S>|d^n$0nDVUanj zG)njY%AOEpV2W)>xyHiEO zSHOk9Yc@I0R-UhGP46_m52D1GzdEFxr75$I(Muk4wC=G-kHe0E=ta0J?rL7`zLi#$ zgzdQSxKoE4AJS9l^foA~CBrVL|2})HrE>g1)?tp&2a8GP-rQRN-_# zx1?8-SZGqD_SZeZ#C!jqT}b{Y9!0Blyz({-&zgqpMAC$UEnpZ?BBZp$`i zO{(U%b3m=aP%l^E*P&j54dZv*cCsJ-ZM{&qbTwL((LQzZ%)4iE!fY>rah2ybn{(M& z6|8fUk01YJHPdu%7lzBE#2V&P@{&S0WiEZmuK91MPkoJeNo1vOGsLuXydvSIuQ4x7 zj`YLNldUF3>6P{jF0CvNdLncX8lt89R|N6~aD(5!5>vH_7$cEi9{j#Ne!+FELcWiC zPE#q$N&zfUi^0DbWm;s%sy%b;%!S|PEC(YkcbhPlcI=UNu z?>=66`@)AZ_re!A-{uGX{Gb2$&P?<@Zu^j#`IHFa$1ov=HCR~PU4*TmvK4#`d3^vI zVyETN7U{Fymcc*3g6Gd@k-mgfMDr&U@s{l^F zwdjw3(aC$org1M~(%@MN#ETx&%If*KA*oa?<_>?;wozEG@T_&jM>f>%)*gXPAuJ~w zEpLQp4}r3z`RuHk>>Dh}YW#?7UYaEq-FR7OvZI^IkyYS1`ZvJ!H~M+PitFA@PVg%5 zf=x!eQe01F2D=HRD8mh7lE&wwU@@QBqZQPbqpu9iDu+GV(PU*39h$Ha)*~!1Aj2PU zd;W*EXp{x2U&#S?W5FeKufa*cRy?MsD{~rAH-85f^Orq3d@y}LsYJ{kKgd+(rab98 z%2e_6LAgl){N$`N?zGmJ5m;2tGblmKx$Lr|j0Md_72&=909La|t4(%_>37s5XHfWz z$b&Yvf`v;n$RMmD#6sLv(o7`&W4S{s8%E6rM{XsfAh|8fwU=<8`{b)Fc?kbb{gc(v z$recbeQ*A?nzzoh(whM>{IbeJNmFInN1GK-I)vmO5ot5g0-r9i1f5?j*e-flepLj{ zeF$B43w7hex$az_{Un>~Dsv6p{(*4uP4|4$?8MZKh8UXROyy;ylhe~RVzDXWuuV)F zK`&Suke5AJ{^)7*+45+PHKXz0I%p$`3X4%|ZCN|${j<>=-W04bA|zpxjIT)qu2sKR zQA?{x_$J9Z)~O;bPf@uwv7P;3s4t?cIR8+3Su~q!O%N}H@;JP(XGlsk%*=7QacZ&* z#0=({=nZq+;H~geR}Fpr{E{D2v{f5#Hbv36Pj)jQnP1_}m-(x6*T|0%jQ89p*F z8%9F&Djyp~_qyC~XfyUhPS5*w^%pYMC~0)V8mPpX!}H+)Cx_}?uBsWf$j!#m+cc)H zLJKIe86_Sv=yLCcne=0!{5Mu)rF0o*qo{T2rA1whaWTdE(99%;f%I1Kx8O@DhX3iE z09UT1|YdVO;N4+{%_7oXy*fj+*xR_~nsDNnrbR2WbH(PIX;-}s@&?qXWN==$CFNm_dS0juP$;(%Z1#sGV`)|EdTh31%ABBpATjy zW!95xo_zE5Z;=Yxam_UudCGky5N7kU*`IS2@~<(gFSA3nIKEKya8}&WH8dYLq)dD6 zcx>aI8J|!h%cs;8RbTymVfOK}pJ(qbGPcjE!ZqAjZ}QFLsE_mF?|^`x-zH}+T6|7v zb)1j8v3H}KXos>`DIM#7uB(@#G<-<)(x*dMO=xUUaYNzpKinDbt=w^^*@eG`R?c4R zK23O}Jfwmnc8-e$+;o-Q?fj`MNu0Dzi8B=L$d6kSR=G;sNUTTchMCJCkQ zTCa}wDZ9(BF9Z_vmPxVqgRebd(;AofK4~3M+*@rnrCqEvEv^(>h+^I2Dy)zL_U#-z zf-bG}n*+3qO1gVK_A3K@r^?hZX_?c3ANVTjM$NZUT z#u<;D-b)tVV}A=l_W*mN8arHkur9EBaA!j*3MSME>vzr2*E62dGsedH!%jiL>XCTj+DapY3Ik z0BAMV%L^7`Ill9zk{)?J`pd{?H)rg^f|8{|R5)>7fk4bO&U>`L>o!Ju%Y(xtREg*O zW#=a&d>r|hmyL$QaY0a_bfaCezq?{3!*o6#OOUGhcFW|PL0(hf!|Tq~ZX!^;!--dd zup>LWw{F*U>Z`VQTEU5S|4om%RYOWOGL#q@%DAXf#b{=rjMXA=vNA;`7NreCroXwt zR{a*Uh?b(ya%c4&8i1ahR~a0Ie_K6v6DRs1@^||+{wy3MS)5B!^5Pyb?~{AAYZR4Y zD-nVp?m03`-a}qwByV_98ZvYiB;c8VsT%gHh(fB#69mB7ee>~pcK=*5@ntKDA>-Vg z*1H*ZnQdY9s^w7-oZ({})ijy(ZAN-V@p;;$0Y_$ry5Pb9wOl0*jcv@fose@Q;6udgtUFDeGA2{_iTeT5kkVmjV|rp8|Xa zmg|T3mWn6dTp-dWiEhabn^UA*$=Px_4`J{#rWa*_a;J`Q}7(!!d`} zgTPD{mC;dTN!fK+OzpDvuDzgfW919St>L`SAAjgD(~fSJT|nnLH_(wk@O5)ZN|~9T zOrO~LcE_NAaLD`D0sH*_Iod7}vNYIkPEF?vpkBZ0EwqSR5tR%fPFGi64rP=ayudGp zY)go|Oi0)#Mg7MJ6*5}UCPfZ!JxFm*k~Wo(oD%Xp zzbExK=g-pX32&l+qtn-m>%YOP?nmQR|2h`ZPv5=Nxaai(vG?C+KU&M!uFwV9?Azpe zwZ}#B+ndbWT&jz+9lHagdW#X)HP1b5()9jGby&*wBPdUPyF)oalm||kfiqD{n{1Bz zb|Rh7$95xS==5ThKA$g8XVIZM-aM3FR4M3Y02a1tceG-(^;1djV!q=<*(YE`$D~f5 z29r4|n_~Tc;C*{skr{x429Xz|_2{2I`|{E`$(+0IE_{9a$8& zFyjLu%AS$D&M7-#qZun?F6m{_BSA5ZjnDaVXOcwr+xt}g`o+H7`d=jJeZ3|9u;_v~ z`O9H|_Lkv7`J0A_0-ZLKQyZJtx!-fj$h1?H;!r^vX60ItdNCuN;zvwU)C)<@UGk(| zpVgyEjwbw?=}`SW#-?ht(R{JpuGgtM9dAZIR>>0Y%_6LNniq(x8*_aMSc1|xYV!}^ ztpyQG%@;I0rQCoDw2;;TYryS0 z68WR~RIf7se)6Ks zL%;fa&@&rI`B}yRuthijcz11E6!x<4#{1acZgxHKd^~GJqRxxFF5*C7_XVLIysumX zBfK=w&2{gDe32sbASUv_ghP`9s&5A6g0*N8Z={FCM-+7P&sF|ahLhm7zNt-}{33*r z=bCR;ESC)FHtW%j^qY~lC&YJp`9ciMtwOjMwVz$y!WWWC@SUv*?lski!NjsKf49^e zdmZ%VsURbYIA#|58`T_nZZS=$A0GT{0r=o5yo9=lHe;^nZju;N_n+A5h+=1$maR=D z*#o_J7?K?K{+_D zDyO}jgpuh*+6u>)Q0u6BhMZ8T6jrxgeo@4T8bw*f-^p`uJ|=s#x?$@_)X__54dA&p zNg8YmkMwxthfYX{NN{2J(Uu)GF*m2dRHzW=!n45q?{aW#aMgX#)Z)PqX7ySUgoW?Nt*8@sPl%%eOZ6 zze8ZYJ?~9|TQQ7?fmHF8;;y#Dl8KiQUt6DMdV!0HJBMb#9`CD$w{OdG!PtSb60kjO zA>#nhI40on=m%q{qmv@=b$NocGMwjn^68T%o&?Ql|8X|jd&<{_qh;7Q@OCs?uuTlT zv!xm&Pw6?|1o56>a4Og(sWFS3b(Of@Rc^ENS|b#+@Uoj*K}ORai?xaNKHa;OknVfu z_x${edU_U=c4hj8mU+I~6PW&!Kqhwze~~2aK{j-kJvQdDICX;d=WSEW6)w2c-17pAeoL49Z^BkoEBW@owRCj8mB!nBg{`humkx{)1~0dv z+tPamWCxGrv#B8&Pa%3&=#*a&IgjZP#2~XC& zVj;b^&!tBNAi>?}i;W91%W13!R-1i)f*^zg_3gi5{<&4}-E$*d*AX>Yys^4Bg9sV$ z*}&3qz#id^I4rsGT?9jCkKLYyKz^QR3=gWUM7eq3PEqKy54dY){?pnN

f@WT5Ut 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 O0000 Date: Tue, 22 Oct 2024 11:07:26 -0500 Subject: [PATCH 03/47] Add comments to env --- templates/compose/foundryvtt.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/templates/compose/foundryvtt.yaml b/templates/compose/foundryvtt.yaml index d11c257c8..9373daf23 100644 --- a/templates/compose/foundryvtt.yaml +++ b/templates/compose/foundryvtt.yaml @@ -12,20 +12,35 @@ services: expose: - 30000 environment: + # Account username or email address for foundryvtt.com. Required for downloading an application distribution. - FOUNDRY_USERNAME=${FOUNDRY_USERNAME} + # Account password for foundryvtt.com. Required for downloading an application distribution. - FOUNDRY_PASSWORD=${FOUNDRY_PASSWORD} + # The presigned URL generate from the user's profile. Required for downloading an application distribution if username/password are not provided. - FOUNDRY_RELEASE_URL=${FOUNDRY_RELEASE_URL} + # Admin password to be applied at startup. If omitted the admin password will be cleared. - FOUNDRY_ADMIN_KEY=${FOUNDRY_ADMIN:-atropos} + # A custom hostname to use in place of the host machine's public IP address when displaying the address of the game session. This allows for reverse proxies or DNS servers to modify the public address. - FOUNDRY_HOSTNAME=${FOUNDRY_HOSTNAME} + # A string path which is appended to the base hostname to serve Foundry VTT content from a specific namespace. For example setting this to demo will result in data being served from http://x.x.x.x/demo/. - FOUNDRY_ROUTE_PREFIX=${FOUNDRY_ROUTE_PREFIX} + # Inform the Foundry server that the software is running behind a reverse proxy on some other port. This allows the invitation links created to the game to include the correct external port. - FOUNDRY_PROXY_PORT=${FOUNDRY_PROXY_PORT:-80} + # Indicates whether the software is running behind a reverse proxy that uses SSL. This allows invitation links and A/V functionality to work as if the Foundry server had SSL configured directly. - FOUNDRY_PROXY_SSL=${FOUNDRY_PROXY_SSL:-true} + # The default application language and module which provides the core translation files. - FOUNDRY_LANGUAGE=${FOUNDRY_LANGUAGE:-en.core} + # Choose the CSS theme for the setup page. Choose from foundry, fantasy, or scifi. - FOUNDRY_CSS_THEME=${FOUNDRY_CSS_THEME:-foundry} + # Set to true to reduce network traffic by serving minified static JavaScript and CSS files. Enabling this setting is recommended for most users, but module developers may wish to disable it. - FOUNDRY_MINIFY_STATIC_FILES=${FOUNDRY_MINIFY_STATIC_FILES:-true} + # The world to startup at system start. - FOUNDRY_WORLD=${FOUNDRY_WORLD} + # Set to true to enable FoundryVTT telemetry, false to disable. This options allows the collection of anonymous usage data to help improve FoundryVTT. - FOUNDRY_TELEMETRY=${FOUNDRY_TELEMETRY} + # Container TZ database name - TIMEZONE=${TIMEZONE:-UTC} + # Set a path to cache downloads of the Foundry distribution archive and speed up subsequent container startups. - CONTAINER_CACHE=/data/container_cache volumes: - foundryvtt_data:/data From d504df431a703dde0886f593923b50480fa5f144 Mon Sep 17 00:00:00 2001 From: Aleksandr Vasilenko Date: Wed, 23 Oct 2024 10:02:39 -0500 Subject: [PATCH 04/47] Added FQDN --- templates/compose/foundryvtt.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/templates/compose/foundryvtt.yaml b/templates/compose/foundryvtt.yaml index 9373daf23..d7e5c6fe0 100644 --- a/templates/compose/foundryvtt.yaml +++ b/templates/compose/foundryvtt.yaml @@ -4,14 +4,14 @@ # logo: svgs/foundryvtt.png # port: 30000 -version: '3.8' - services: foundryvtt: image: felddy/foundryvtt:release expose: - 30000 environment: + # FQDN will be proxied to port 30000 + - SERVICE_FQDN_FOUNDRY_30000 # Account username or email address for foundryvtt.com. Required for downloading an application distribution. - FOUNDRY_USERNAME=${FOUNDRY_USERNAME} # Account password for foundryvtt.com. Required for downloading an application distribution. @@ -20,7 +20,7 @@ services: - FOUNDRY_RELEASE_URL=${FOUNDRY_RELEASE_URL} # Admin password to be applied at startup. If omitted the admin password will be cleared. - FOUNDRY_ADMIN_KEY=${FOUNDRY_ADMIN:-atropos} - # A custom hostname to use in place of the host machine's public IP address when displaying the address of the game session. This allows for reverse proxies or DNS servers to modify the public address. + # A custom hostname to use in place of the host machine's public IP address when displaying the address of the game session. This allows for reverse proxies or DNS servers to modify the public address. Example: foundry.example.com - FOUNDRY_HOSTNAME=${FOUNDRY_HOSTNAME} # A string path which is appended to the base hostname to serve Foundry VTT content from a specific namespace. For example setting this to demo will result in data being served from http://x.x.x.x/demo/. - FOUNDRY_ROUTE_PREFIX=${FOUNDRY_ROUTE_PREFIX} @@ -49,4 +49,3 @@ services: timeout: 5s interval: 30s retries: 3 - From 8084d185c806ddaff92c21e0169d1d8c23cfed76 Mon Sep 17 00:00:00 2001 From: Carl Hurd Date: Wed, 23 Oct 2024 22:20:32 -0400 Subject: [PATCH 05/47] Update reactive-resume.yaml Add the required env vars for Minio for Coolify handling --- templates/compose/reactive-resume.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/compose/reactive-resume.yaml b/templates/compose/reactive-resume.yaml index e2d18e8e4..12cccebd9 100644 --- a/templates/compose/reactive-resume.yaml +++ b/templates/compose/reactive-resume.yaml @@ -48,7 +48,8 @@ services: image: minio/minio command: server /data --console-address ":9001" environment: - - SERVICE_FQDN_MINIO_9000 + - MINIO_SERVER_URL=$MINIO_SERVER_URL + - MINIO_BROWSER_REDIRECT_URL=$MINIO_BROWSER_REDIRECT_URL - MINIO_ROOT_USER=$SERVICE_USER_MINIO - MINIO_ROOT_PASSWORD=$SERVICE_PASSWORD_MINIO volumes: From d0c8ab2b458aa4f904e2a4c493957f2f83422c82 Mon Sep 17 00:00:00 2001 From: Carl Hurd Date: Wed, 23 Oct 2024 22:33:03 -0400 Subject: [PATCH 06/47] Update reactive-resume.yaml Move back to quay.io container registry --- templates/compose/reactive-resume.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/reactive-resume.yaml b/templates/compose/reactive-resume.yaml index 12cccebd9..accbf9c05 100644 --- a/templates/compose/reactive-resume.yaml +++ b/templates/compose/reactive-resume.yaml @@ -45,7 +45,7 @@ services: retries: 10 minio: - image: minio/minio + image: quay.io/minio/minio:latest command: server /data --console-address ":9001" environment: - MINIO_SERVER_URL=$MINIO_SERVER_URL From b28cf1a3660bb25dd6eb1e5d11fa559e819a2b7c Mon Sep 17 00:00:00 2001 From: Jakob Ortmann Date: Thu, 24 Oct 2024 11:37:28 +0200 Subject: [PATCH 07/47] add martin as a service --- public/svgs/martin.png | Bin 0 -> 187011 bytes templates/compose/martin.yaml | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 public/svgs/martin.png create mode 100644 templates/compose/martin.yaml diff --git a/public/svgs/martin.png b/public/svgs/martin.png new file mode 100644 index 0000000000000000000000000000000000000000..d1a99e1480f6cb5c90a1892e7f2713c3719276d9 GIT binary patch literal 187011 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ÅvWh4lfBccKr6_V7ZXbH+ceN_z@WT&o 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

a|tO2W6--9@C-2uVJ+Y}FMxUJ)Av47+5?A85S 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 LvQ(vnNznfSUkm;! literal 0 HcmV?d00001 diff --git a/templates/compose/martin.yaml b/templates/compose/martin.yaml new file mode 100644 index 000000000..98bef16ed --- /dev/null +++ b/templates/compose/martin.yaml @@ -0,0 +1,35 @@ +# documentation: https://maplibre.org/martin/introduction.html/ +# slogan: Martin is a tile server able to generate and serve vector tiles on the fly from large PostGIS databases, PMTiles (local or remote), and MBTiles files, allowing multiple tile sources to be dynamically combined into one. +# tags: postgis, vector, tiles +# logo: svgs/martin.png +# port: 3000 + + +services: + martin: + image: ghcr.io/maplibre/martin:v0.13.0 + environment: + - SERVICE_FQDN_MARTIN_3000 + - HOST=${SERVICE_FQDN_DOCUSEAL} + - DATABASE_URL=postgresql://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/${POSTGRES_DB} + depends_on: + postgresql: + condition: service_healthy + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000"] + interval: 5s + timeout: 20s + retries: 10 + postgresql: + image: postgis/postgis:16-3.4-alpine + volumes: + - postgresql-data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=$SERVICE_USER_POSTGRES + - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - POSTGRES_DB=${POSTGRES_DB:-docuseal} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 \ No newline at end of file From 2f1be6a2ab70647ab3f3b48a88f2cc660175f5f8 Mon Sep 17 00:00:00 2001 From: Jakob Ortmann Date: Thu, 24 Oct 2024 12:10:52 +0200 Subject: [PATCH 08/47] fixed some copy and paste errors --- templates/compose/martin.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/compose/martin.yaml b/templates/compose/martin.yaml index 98bef16ed..5d152dbdc 100644 --- a/templates/compose/martin.yaml +++ b/templates/compose/martin.yaml @@ -10,7 +10,7 @@ services: image: ghcr.io/maplibre/martin:v0.13.0 environment: - SERVICE_FQDN_MARTIN_3000 - - HOST=${SERVICE_FQDN_DOCUSEAL} + - HOST=${SERVICE_FQDN_MARTIN} - DATABASE_URL=postgresql://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/${POSTGRES_DB} depends_on: postgresql: @@ -27,9 +27,9 @@ services: environment: - POSTGRES_USER=$SERVICE_USER_POSTGRES - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - POSTGRES_DB=${POSTGRES_DB:-docuseal} + - POSTGRES_DB=${POSTGRES_DB:-martin} healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 20s - retries: 10 \ No newline at end of file + retries: 10 From ff60189285fdbf8b8ad85bb971dad0d91e1288fa Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:20:01 +0200 Subject: [PATCH 09/47] fix 2 step confirmation password is now checked if it is enabled --- app/Livewire/NavbarDeleteTeam.php | 2 +- app/Livewire/Project/Database/BackupEdit.php | 2 +- app/Livewire/Project/Database/BackupExecutions.php | 2 +- app/Livewire/Project/Service/FileStorage.php | 2 +- app/Livewire/Project/Service/ServiceApplicationView.php | 2 +- app/Livewire/Project/Shared/Danger.php | 2 +- app/Livewire/Project/Shared/Destination.php | 2 +- app/Livewire/Project/Shared/Storages/Show.php | 2 +- app/Livewire/Server/Delete.php | 2 +- app/Livewire/Team/AdminView.php | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/Livewire/NavbarDeleteTeam.php b/app/Livewire/NavbarDeleteTeam.php index 2c45de269..10ba0c86a 100644 --- a/app/Livewire/NavbarDeleteTeam.php +++ b/app/Livewire/NavbarDeleteTeam.php @@ -19,7 +19,7 @@ public function mount() public function delete($password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Project/Database/BackupEdit.php b/app/Livewire/Project/Database/BackupEdit.php index d356d739c..016218b78 100644 --- a/app/Livewire/Project/Database/BackupEdit.php +++ b/app/Livewire/Project/Database/BackupEdit.php @@ -59,7 +59,7 @@ public function mount() public function delete($password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Project/Database/BackupExecutions.php b/app/Livewire/Project/Database/BackupExecutions.php index 30c01fc3d..d7ac18097 100644 --- a/app/Livewire/Project/Database/BackupExecutions.php +++ b/app/Livewire/Project/Database/BackupExecutions.php @@ -42,7 +42,7 @@ public function cleanupFailed() public function deleteBackup($executionId, $password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Project/Service/FileStorage.php b/app/Livewire/Project/Service/FileStorage.php index 2b6f18ec2..4d070bc0c 100644 --- a/app/Livewire/Project/Service/FileStorage.php +++ b/app/Livewire/Project/Service/FileStorage.php @@ -88,7 +88,7 @@ public function convertToFile() public function delete($password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Project/Service/ServiceApplicationView.php b/app/Livewire/Project/Service/ServiceApplicationView.php index 22d4cf4cb..8324ee645 100644 --- a/app/Livewire/Project/Service/ServiceApplicationView.php +++ b/app/Livewire/Project/Service/ServiceApplicationView.php @@ -50,7 +50,7 @@ public function instantSaveAdvanced() public function delete($password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Project/Shared/Danger.php b/app/Livewire/Project/Shared/Danger.php index c7aad89ef..2a21532ce 100644 --- a/app/Livewire/Project/Shared/Danger.php +++ b/app/Livewire/Project/Shared/Danger.php @@ -92,7 +92,7 @@ public function mount() public function delete($password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Project/Shared/Destination.php b/app/Livewire/Project/Shared/Destination.php index 1e872c60a..c305e817c 100644 --- a/app/Livewire/Project/Shared/Destination.php +++ b/app/Livewire/Project/Shared/Destination.php @@ -119,7 +119,7 @@ public function addServer(int $network_id, int $server_id) public function removeServer(int $network_id, int $server_id, $password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Project/Shared/Storages/Show.php b/app/Livewire/Project/Shared/Storages/Show.php index 4c9303033..54b1be3af 100644 --- a/app/Livewire/Project/Shared/Storages/Show.php +++ b/app/Livewire/Project/Shared/Storages/Show.php @@ -41,7 +41,7 @@ public function submit() public function delete($password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Server/Delete.php b/app/Livewire/Server/Delete.php index 606977b20..cc2b335e1 100644 --- a/app/Livewire/Server/Delete.php +++ b/app/Livewire/Server/Delete.php @@ -17,7 +17,7 @@ class Delete extends Component public function delete($password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Team/AdminView.php b/app/Livewire/Team/AdminView.php index 25af875bb..700c30f0a 100644 --- a/app/Livewire/Team/AdminView.php +++ b/app/Livewire/Team/AdminView.php @@ -78,7 +78,7 @@ private function finalizeDeletion(User $user, Team $team) public function delete($id, $password) { - if (! InstanceSettings::get('disable_two_step_confirmation')) { + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); From d2066dd2dce31bd6a836999732ab50187f7a0dfa Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:21:22 +0200 Subject: [PATCH 10/47] fix password is now checked before a user can disable 2 step confirmation --- app/Livewire/Settings/Index.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/Livewire/Settings/Index.php b/app/Livewire/Settings/Index.php index 9747329f6..938d0e548 100644 --- a/app/Livewire/Settings/Index.php +++ b/app/Livewire/Settings/Index.php @@ -5,6 +5,8 @@ use App\Jobs\CheckForUpdatesJob; use App\Models\InstanceSettings; use App\Models\Server; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Hash; use Livewire\Component; class Index extends Component @@ -185,8 +187,14 @@ public function render() return view('livewire.settings.index'); } - public function toggleTwoStepConfirmation() + public function toggleTwoStepConfirmation($password) { + if (! Hash::check($password, Auth::user()->password)) { + $this->addError('password', 'The provided password is incorrect.'); + + return; + } + $this->settings->disable_two_step_confirmation = true; $this->settings->save(); $this->disable_two_step_confirmation = true; From 20d821585cb5c5a79348b4611ea6fb226bec730a Mon Sep 17 00:00:00 2001 From: Aleksandr Vasilenko Date: Thu, 24 Oct 2024 10:06:28 -0500 Subject: [PATCH 11/47] Added a few more env variables --- templates/compose/foundryvtt.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/templates/compose/foundryvtt.yaml b/templates/compose/foundryvtt.yaml index d7e5c6fe0..452e806e7 100644 --- a/templates/compose/foundryvtt.yaml +++ b/templates/compose/foundryvtt.yaml @@ -12,12 +12,16 @@ services: environment: # FQDN will be proxied to port 30000 - SERVICE_FQDN_FOUNDRY_30000 + # Version of Foundry Virtual Tabletop to install i.e. 12.331 + - FOUNDRY_VERSION=${FOUNDRY_VERSION:-12.331} # Account username or email address for foundryvtt.com. Required for downloading an application distribution. - FOUNDRY_USERNAME=${FOUNDRY_USERNAME} # Account password for foundryvtt.com. Required for downloading an application distribution. - FOUNDRY_PASSWORD=${FOUNDRY_PASSWORD} # The presigned URL generate from the user's profile. Required for downloading an application distribution if username/password are not provided. - FOUNDRY_RELEASE_URL=${FOUNDRY_RELEASE_URL} + # The license key to install. e.g.; AAAA-BBBB-CCCC-DDDD-EEEE-FFFF If left unset, a license key will be fetched when using account authentication. + - FOUNDRY_LICENSE_KEY=${FOUNDRY_LICENSE_KEY} # Admin password to be applied at startup. If omitted the admin password will be cleared. - FOUNDRY_ADMIN_KEY=${FOUNDRY_ADMIN:-atropos} # A custom hostname to use in place of the host machine's public IP address when displaying the address of the game session. This allows for reverse proxies or DNS servers to modify the public address. Example: foundry.example.com @@ -28,13 +32,15 @@ services: - FOUNDRY_PROXY_PORT=${FOUNDRY_PROXY_PORT:-80} # Indicates whether the software is running behind a reverse proxy that uses SSL. This allows invitation links and A/V functionality to work as if the Foundry server had SSL configured directly. - FOUNDRY_PROXY_SSL=${FOUNDRY_PROXY_SSL:-true} + # An absolute or relative path that points to the awsConfig.json⁠ or true for AWS environment variable credentials evaluation⁠ usage. + - FOUNDRY_AWS_CONFIG=${FOUNDRY_AWS_CONFIG} # The default application language and module which provides the core translation files. - FOUNDRY_LANGUAGE=${FOUNDRY_LANGUAGE:-en.core} # Choose the CSS theme for the setup page. Choose from foundry, fantasy, or scifi. - FOUNDRY_CSS_THEME=${FOUNDRY_CSS_THEME:-foundry} # Set to true to reduce network traffic by serving minified static JavaScript and CSS files. Enabling this setting is recommended for most users, but module developers may wish to disable it. - FOUNDRY_MINIFY_STATIC_FILES=${FOUNDRY_MINIFY_STATIC_FILES:-true} - # The world to startup at system start. + # The world ID to startup at system start. - FOUNDRY_WORLD=${FOUNDRY_WORLD} # Set to true to enable FoundryVTT telemetry, false to disable. This options allows the collection of anonymous usage data to help improve FoundryVTT. - FOUNDRY_TELEMETRY=${FOUNDRY_TELEMETRY} From 1cb59d1883937bdc1ca2080e4ea7a447f7cfc4f6 Mon Sep 17 00:00:00 2001 From: Aleksandr Vasilenko Date: Thu, 24 Oct 2024 10:22:29 -0500 Subject: [PATCH 12/47] Removed hardcoded version It cannot be null and it will be annoying to update the template with every release. Users still can set this variable in their project if they want to install non-latest version. --- templates/compose/foundryvtt.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/templates/compose/foundryvtt.yaml b/templates/compose/foundryvtt.yaml index 452e806e7..f1c80d619 100644 --- a/templates/compose/foundryvtt.yaml +++ b/templates/compose/foundryvtt.yaml @@ -12,8 +12,6 @@ services: environment: # FQDN will be proxied to port 30000 - SERVICE_FQDN_FOUNDRY_30000 - # Version of Foundry Virtual Tabletop to install i.e. 12.331 - - FOUNDRY_VERSION=${FOUNDRY_VERSION:-12.331} # Account username or email address for foundryvtt.com. Required for downloading an application distribution. - FOUNDRY_USERNAME=${FOUNDRY_USERNAME} # Account password for foundryvtt.com. Required for downloading an application distribution. From c17ca1ea7e31fde31da089e37b05ce56980a749a Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:05:43 +0200 Subject: [PATCH 13/47] fix dozzle with auth --- templates/compose/dozzle-with-auth.yaml | 17 ++++++++--------- templates/service-templates.json | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/templates/compose/dozzle-with-auth.yaml b/templates/compose/dozzle-with-auth.yaml index 0b0e5b9a3..8521f824b 100644 --- a/templates/compose/dozzle-with-auth.yaml +++ b/templates/compose/dozzle-with-auth.yaml @@ -1,4 +1,3 @@ -# ignore: true # documentation: https://dozzle.dev/ # slogan: Dozzle is a simple and lightweight web UI for Docker logs. # tags: dozzle,docker,logs,web-ui @@ -14,19 +13,19 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock - type: bind - source: /data/users.yml - target: /data/users.yml + source: ./data/users.yml + target: /data/users.yml:ro content: | users: - # "admin" here is username + # "admin" is the username admin: - name: "Admin" - # Just sha-256 which can be computed with "echo -n password | shasum -a 256" - password: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8" - email: me@email.net + email: test@email.com + name: Admin + # A sha-256 hash of the password you want to use. Can be computed with "echo -n password | shasum -a 256". Default password is "Test". + password: $2a$11$viucCvFLlHWvBNOOI6uypuVU.D09UWb.zswRxEg0MkDPi1q/bKbdG + healthcheck: test: ["CMD", "/dozzle", "healthcheck"] interval: 3s timeout: 30s retries: 5 - start_period: 30s diff --git a/templates/service-templates.json b/templates/service-templates.json index 67aff4d1b..2832614f4 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -516,6 +516,20 @@ "logo": "svgs/dokuwiki.png", "minversion": "0.0.0" }, + "dozzle-with-auth": { + "documentation": "https://dozzle.dev/?utm_source=coolify.io", + "slogan": "Dozzle is a simple and lightweight web UI for Docker logs.", + "compose": "c2VydmljZXM6CiAgZG96emxlOgogICAgaW1hZ2U6ICdhbWlyMjAvZG96emxlOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9ET1paTEVfODA4MAogICAgICAtIERPWlpMRV9BVVRIX1BST1ZJREVSPXNpbXBsZQogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2RhdGEvdXNlcnMueW1sCiAgICAgICAgdGFyZ2V0OiAnL2RhdGEvdXNlcnMueW1sOnJvJwogICAgICAgIGNvbnRlbnQ6ICJ1c2VyczpcbiAgIyBcImFkbWluXCIgaXMgdGhlIHVzZXJuYW1lXG4gIGFkbWluOlxuICAgIGVtYWlsOiB0ZXN0QGVtYWlsLmNvbVxuICAgIG5hbWU6IEFkbWluXG4gICAgIyBBIHNoYS0yNTYgaGFzaCBvZiB0aGUgcGFzc3dvcmQgeW91IHdhbnQgdG8gdXNlLiBDYW4gYmUgY29tcHV0ZWQgd2l0aCBcImVjaG8gLW4gcGFzc3dvcmQgfCBzaGFzdW0gLWEgMjU2XCIuIERlZmF1bHQgcGFzc3dvcmQgaXMgXCJUZXN0XCIuXG4gICAgcGFzc3dvcmQ6ICQyYSQxMSR2aXVjQ3ZGTGxIV3ZCTk9PSTZ1eXB1VlUuRDA5VVdiLnpzd1J4RWcwTWtEUGkxcS9iS2JkR1xuIgogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIC9kb3p6bGUKICAgICAgICAtIGhlYWx0aGNoZWNrCiAgICAgIGludGVydmFsOiAzcwogICAgICB0aW1lb3V0OiAzMHMKICAgICAgcmV0cmllczogNQo=", + "tags": [ + "dozzle", + "docker", + "logs", + "web-ui" + ], + "logo": "svgs/dozzle.svg", + "minversion": "0.0.0", + "port": "8080" + }, "dozzle": { "documentation": "https://dozzle.dev/guide/getting-started#running-with-docker?utm_source=coolify.io", "slogan": "Dozzle is a simple and lightweight web UI for Docker logs.", From 8b12fa65dd8d41b63c04eeaf65c87153ba95a47c Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:16:37 +0200 Subject: [PATCH 14/47] fix martin --- templates/compose/martin.yaml | 9 +++++---- templates/service-templates.json | 13 +++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/templates/compose/martin.yaml b/templates/compose/martin.yaml index 5d152dbdc..a56ebe12c 100644 --- a/templates/compose/martin.yaml +++ b/templates/compose/martin.yaml @@ -4,14 +4,13 @@ # logo: svgs/martin.png # port: 3000 - services: martin: image: ghcr.io/maplibre/martin:v0.13.0 environment: - SERVICE_FQDN_MARTIN_3000 - HOST=${SERVICE_FQDN_MARTIN} - - DATABASE_URL=postgresql://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/${POSTGRES_DB} + - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-martin-db} depends_on: postgresql: condition: service_healthy @@ -20,14 +19,16 @@ services: interval: 5s timeout: 20s retries: 10 + postgresql: image: postgis/postgis:16-3.4-alpine + platform: linux/amd64 volumes: - - postgresql-data:/var/lib/postgresql/data + - martin-postgresql-data:/var/lib/postgresql/data environment: - POSTGRES_USER=$SERVICE_USER_POSTGRES - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - POSTGRES_DB=${POSTGRES_DB:-martin} + - POSTGRES_DB=${POSTGRES_DB:-martin-db} healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s diff --git a/templates/service-templates.json b/templates/service-templates.json index 2832614f4..d4e8a0f4e 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -1456,6 +1456,19 @@ "minversion": "0.0.0", "port": "8025" }, + "martin": { + "documentation": "https://maplibre.org/martin/introduction.html/?utm_source=coolify.io", + "slogan": "Martin is a tile server able to generate and serve vector tiles on the fly from large PostGIS databases, PMTiles (local or remote), and MBTiles files, allowing multiple tile sources to be dynamically combined into one.", + "compose": "c2VydmljZXM6CiAgbWFydGluOgogICAgaW1hZ2U6ICdnaGNyLmlvL21hcGxpYnJlL21hcnRpbjp2MC4xMy4wJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX01BUlRJTl8zMDAwCiAgICAgIC0gJ0hPU1Q9JHtTRVJWSUNFX0ZRRE5fTUFSVElOfScKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBwb3N0Z3Jlc3FsOjU0MzIvJHtQT1NUR1JFU19EQjotbWFydGluLWRifScKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLXEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTozMDAwJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcG9zdGdyZXNxbDoKICAgIGltYWdlOiAncG9zdGdpcy9wb3N0Z2lzOjE2LTMuNC1hbHBpbmUnCiAgICBwbGF0Zm9ybTogbGludXgvYW1kNjQKICAgIHZvbHVtZXM6CiAgICAgIC0gJ21hcnRpbi1wb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotbWFydGluLWRifScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "postgis", + "vector", + "tiles" + ], + "logo": "svgs/martin.png", + "minversion": "0.0.0", + "port": "3000" + }, "mattermost": { "documentation": "https://docs.mattermost.com?utm_source=coolify.io", "slogan": "Mattermost is an open source, self-hosted Slack-alternative.", From dc92fe8760ab4929abe089a57e46c2d213c44104 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:50:57 +0200 Subject: [PATCH 15/47] fix reactive resume --- templates/compose/reactive-resume.yaml | 3 ++- templates/service-templates.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/compose/reactive-resume.yaml b/templates/compose/reactive-resume.yaml index accbf9c05..0cf8ed6b9 100644 --- a/templates/compose/reactive-resume.yaml +++ b/templates/compose/reactive-resume.yaml @@ -62,6 +62,7 @@ services: chrome: image: ghcr.io/browserless/chrome:latest + platform: linux/amd64 environment: - HEALTH=true - TIMEOUT=10000 @@ -69,7 +70,7 @@ services: - TOKEN=$SERVICE_PASSWORD_CHROMETOKEN redis: - image: redis:alpine + image: redis:7-alpine command: redis-server volumes: - redis_data:/data diff --git a/templates/service-templates.json b/templates/service-templates.json index d4e8a0f4e..3ef4cacbb 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -2114,7 +2114,7 @@ "reactive-resume": { "documentation": "https://rxresu.me/?utm_source=coolify.io", "slogan": "A one-of-a-kind resume builder that keeps your privacy in mind.", - "compose": "c2VydmljZXM6CiAgcmVhY3RpdmUtcmVzdW1lOgogICAgaW1hZ2U6ICdhbXJ1dGhwaWxsYWkvcmVhY3RpdmUtcmVzdW1lOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9SRUFDVElWRVJFU1VNRV8zMDAwCiAgICAgIC0gUFVCTElDX1VSTD0kU0VSVklDRV9GUUROX1JFQUNUSVZFUkVTVU1FCiAgICAgIC0gJ1NUT1JBR0VfVVJMPSR7U0VSVklDRV9GUUROX01JTklPfS9kZWZhdWx0JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gQUNDRVNTX1RPS0VOX1NFQ1JFVD0kU0VSVklDRV9QQVNTV09SRF9BQ0NFU1NUT0tFTgogICAgICAtIFJFRlJFU0hfVE9LRU5fU0VDUkVUPSRTRVJWSUNFX1BBU1NXT1JEX1JFRlJFU0hUT0tFTgogICAgICAtIENIUk9NRV9UT0tFTj0kU0VSVklDRV9QQVNTV09SRF9DSFJPTUVUT0tFTgogICAgICAtICdDSFJPTUVfVVJMPXdzOi8vY2hyb21lOjMwMDAvY2hyb21lJwogICAgICAtICdSRURJU19VUkw9cmVkaXM6Ly9yZWRpczo2Mzc5JwogICAgICAtIFNUT1JBR0VfRU5EUE9JTlQ9bWluaW8KICAgICAgLSBTVE9SQUdFX1BPUlQ9OTAwMAogICAgICAtIFNUT1JBR0VfUkVHSU9OPXVzLWVhc3QtMQogICAgICAtIFNUT1JBR0VfQlVDS0VUPWRlZmF1bHQKICAgICAgLSBTVE9SQUdFX0FDQ0VTU19LRVk9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIFNUT1JBR0VfU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIFNUT1JBR0VfVVNFX1NTTD1mYWxzZQogICAgICAtICdESVNBQkxFX1NJR05VUFM9JHtTRVJWSUNFX0RJU0FCTEVfU0lHTlVQUzotZmFsc2V9JwogICAgICAtICdESVNBQkxFX0VNQUlMX0FVVEg9JHtTRVJWSUNFX0RJU0FCTEVfRU1BSUxfQVVUSDotZmFsc2V9JwogICAgZGVwZW5kc19vbjoKICAgICAgLSBwb3N0Z3JlcwogICAgICAtIG1pbmlvCiAgICAgIC0gY2hyb21lCiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIG1pbmlvOgogICAgaW1hZ2U6IG1pbmlvL21pbmlvCiAgICBjb21tYW5kOiAnc2VydmVyIC9kYXRhIC0tY29uc29sZS1hZGRyZXNzICI6OTAwMSInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTUlOSU9fOTAwMAogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgdm9sdW1lczoKICAgICAgLSAnbWluaW8tZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBtYwogICAgICAgIC0gcmVhZHkKICAgICAgICAtIGxvY2FsCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBjaHJvbWU6CiAgICBpbWFnZTogJ2doY3IuaW8vYnJvd3Nlcmxlc3MvY2hyb21lOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIEhFQUxUSD10cnVlCiAgICAgIC0gVElNRU9VVD0xMDAwMAogICAgICAtIENPTkNVUlJFTlQ9MTAKICAgICAgLSBUT0tFTj0kU0VSVklDRV9QQVNTV09SRF9DSFJPTUVUT0tFTgogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczphbHBpbmUnCiAgICBjb21tYW5kOiByZWRpcy1zZXJ2ZXIKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzX2RhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBwaW5nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "compose": "c2VydmljZXM6CiAgcmVhY3RpdmUtcmVzdW1lOgogICAgaW1hZ2U6ICdhbXJ1dGhwaWxsYWkvcmVhY3RpdmUtcmVzdW1lOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9SRUFDVElWRVJFU1VNRV8zMDAwCiAgICAgIC0gUFVCTElDX1VSTD0kU0VSVklDRV9GUUROX1JFQUNUSVZFUkVTVU1FCiAgICAgIC0gJ1NUT1JBR0VfVVJMPSR7U0VSVklDRV9GUUROX01JTklPfS9kZWZhdWx0JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gQUNDRVNTX1RPS0VOX1NFQ1JFVD0kU0VSVklDRV9QQVNTV09SRF9BQ0NFU1NUT0tFTgogICAgICAtIFJFRlJFU0hfVE9LRU5fU0VDUkVUPSRTRVJWSUNFX1BBU1NXT1JEX1JFRlJFU0hUT0tFTgogICAgICAtIENIUk9NRV9UT0tFTj0kU0VSVklDRV9QQVNTV09SRF9DSFJPTUVUT0tFTgogICAgICAtICdDSFJPTUVfVVJMPXdzOi8vY2hyb21lOjMwMDAvY2hyb21lJwogICAgICAtICdSRURJU19VUkw9cmVkaXM6Ly9yZWRpczo2Mzc5JwogICAgICAtIFNUT1JBR0VfRU5EUE9JTlQ9bWluaW8KICAgICAgLSBTVE9SQUdFX1BPUlQ9OTAwMAogICAgICAtIFNUT1JBR0VfUkVHSU9OPXVzLWVhc3QtMQogICAgICAtIFNUT1JBR0VfQlVDS0VUPWRlZmF1bHQKICAgICAgLSBTVE9SQUdFX0FDQ0VTU19LRVk9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIFNUT1JBR0VfU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIFNUT1JBR0VfVVNFX1NTTD1mYWxzZQogICAgICAtICdESVNBQkxFX1NJR05VUFM9JHtTRVJWSUNFX0RJU0FCTEVfU0lHTlVQUzotZmFsc2V9JwogICAgICAtICdESVNBQkxFX0VNQUlMX0FVVEg9JHtTRVJWSUNFX0RJU0FCTEVfRU1BSUxfQVVUSDotZmFsc2V9JwogICAgZGVwZW5kc19vbjoKICAgICAgLSBwb3N0Z3JlcwogICAgICAtIG1pbmlvCiAgICAgIC0gY2hyb21lCiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIG1pbmlvOgogICAgaW1hZ2U6ICdxdWF5LmlvL21pbmlvL21pbmlvOmxhdGVzdCcKICAgIGNvbW1hbmQ6ICdzZXJ2ZXIgL2RhdGEgLS1jb25zb2xlLWFkZHJlc3MgIjo5MDAxIicKICAgIGVudmlyb25tZW50OgogICAgICAtIE1JTklPX1NFUlZFUl9VUkw9JE1JTklPX1NFUlZFUl9VUkwKICAgICAgLSBNSU5JT19CUk9XU0VSX1JFRElSRUNUX1VSTD0kTUlOSU9fQlJPV1NFUl9SRURJUkVDVF9VUkwKICAgICAgLSBNSU5JT19ST09UX1VTRVI9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIE1JTklPX1JPT1RfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgIHZvbHVtZXM6CiAgICAgIC0gJ21pbmlvLWRhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbWMKICAgICAgICAtIHJlYWR5CiAgICAgICAgLSBsb2NhbAogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgY2hyb21lOgogICAgaW1hZ2U6ICdnaGNyLmlvL2Jyb3dzZXJsZXNzL2Nocm9tZTpsYXRlc3QnCiAgICBwbGF0Zm9ybTogbGludXgvYW1kNjQKICAgIGVudmlyb25tZW50OgogICAgICAtIEhFQUxUSD10cnVlCiAgICAgIC0gVElNRU9VVD0xMDAwMAogICAgICAtIENPTkNVUlJFTlQ9MTAKICAgICAgLSBUT0tFTj0kU0VSVklDRV9QQVNTV09SRF9DSFJPTUVUT0tFTgogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LWFscGluZScKICAgIGNvbW1hbmQ6IHJlZGlzLXNlcnZlcgogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXNfZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", "tags": [ "reactive-resume", "resume-builder", From 25b0c8e35452b292981c46e22402b3ea70993884 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 24 Oct 2024 20:49:20 +0200 Subject: [PATCH 16/47] Refactor license and OAuth settings to redirect non-admin users to home page --- app/Livewire/Settings/License.php | 3 +++ app/Livewire/SettingsOauth.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/Livewire/Settings/License.php b/app/Livewire/Settings/License.php index ca0c9c1ae..8cb7aad8f 100644 --- a/app/Livewire/Settings/License.php +++ b/app/Livewire/Settings/License.php @@ -28,6 +28,9 @@ public function mount() if (! isCloud()) { abort(404); } + if (! isInstanceAdmin()) { + return redirect()->route('home'); + } $this->instance_id = config('app.id'); $this->settings = instanceSettings(); } diff --git a/app/Livewire/SettingsOauth.php b/app/Livewire/SettingsOauth.php index c3884589f..17b3b89a3 100644 --- a/app/Livewire/SettingsOauth.php +++ b/app/Livewire/SettingsOauth.php @@ -24,6 +24,9 @@ protected function rules() public function mount() { + if (! isInstanceAdmin()) { + return redirect()->route('home'); + } $this->oauth_settings_map = OauthSetting::all()->sortBy('provider')->reduce(function ($carry, $setting) { $carry[$setting->provider] = $setting; From 091cbdf04837ffa831bb8b7b9f7178383077b604 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 24 Oct 2024 21:47:05 +0200 Subject: [PATCH 17/47] fix foundryvtt --- templates/compose/foundryvtt.yaml | 7 ++----- templates/service-templates.json | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/templates/compose/foundryvtt.yaml b/templates/compose/foundryvtt.yaml index f1c80d619..5cf961a37 100644 --- a/templates/compose/foundryvtt.yaml +++ b/templates/compose/foundryvtt.yaml @@ -10,7 +10,6 @@ services: expose: - 30000 environment: - # FQDN will be proxied to port 30000 - SERVICE_FQDN_FOUNDRY_30000 # Account username or email address for foundryvtt.com. Required for downloading an application distribution. - FOUNDRY_USERNAME=${FOUNDRY_USERNAME} @@ -40,14 +39,12 @@ services: - FOUNDRY_MINIFY_STATIC_FILES=${FOUNDRY_MINIFY_STATIC_FILES:-true} # The world ID to startup at system start. - FOUNDRY_WORLD=${FOUNDRY_WORLD} - # Set to true to enable FoundryVTT telemetry, false to disable. This options allows the collection of anonymous usage data to help improve FoundryVTT. - - FOUNDRY_TELEMETRY=${FOUNDRY_TELEMETRY} - # Container TZ database name + - FOUNDRY_TELEMETRY=${FOUNDRY_TELEMETRY:-false} - TIMEZONE=${TIMEZONE:-UTC} # Set a path to cache downloads of the Foundry distribution archive and speed up subsequent container startups. - CONTAINER_CACHE=/data/container_cache volumes: - - foundryvtt_data:/data + - foundryvtt-data:/data healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:30000"] timeout: 5s diff --git a/templates/service-templates.json b/templates/service-templates.json index 3ef4cacbb..d9b5e154b 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -784,6 +784,21 @@ "minversion": "0.0.0", "port": "3000" }, + "foundryvtt": { + "documentation": "https://foundryvtt.com/kb/?utm_source=coolify.io", + "slogan": "Foundry Virtual Tabletop is a self-hosted & modern roleplaying platform", + "compose": "c2VydmljZXM6CiAgZm91bmRyeXZ0dDoKICAgIGltYWdlOiAnZmVsZGR5L2ZvdW5kcnl2dHQ6cmVsZWFzZScKICAgIGV4cG9zZToKICAgICAgLSAzMDAwMAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0ZPVU5EUllfMzAwMDAKICAgICAgLSAnRk9VTkRSWV9VU0VSTkFNRT0ke0ZPVU5EUllfVVNFUk5BTUV9JwogICAgICAtICdGT1VORFJZX1BBU1NXT1JEPSR7Rk9VTkRSWV9QQVNTV09SRH0nCiAgICAgIC0gJ0ZPVU5EUllfUkVMRUFTRV9VUkw9JHtGT1VORFJZX1JFTEVBU0VfVVJMfScKICAgICAgLSAnRk9VTkRSWV9MSUNFTlNFX0tFWT0ke0ZPVU5EUllfTElDRU5TRV9LRVl9JwogICAgICAtICdGT1VORFJZX0FETUlOX0tFWT0ke0ZPVU5EUllfQURNSU46LWF0cm9wb3N9JwogICAgICAtICdGT1VORFJZX0hPU1ROQU1FPSR7Rk9VTkRSWV9IT1NUTkFNRX0nCiAgICAgIC0gJ0ZPVU5EUllfUk9VVEVfUFJFRklYPSR7Rk9VTkRSWV9ST1VURV9QUkVGSVh9JwogICAgICAtICdGT1VORFJZX1BST1hZX1BPUlQ9JHtGT1VORFJZX1BST1hZX1BPUlQ6LTgwfScKICAgICAgLSAnRk9VTkRSWV9QUk9YWV9TU0w9JHtGT1VORFJZX1BST1hZX1NTTDotdHJ1ZX0nCiAgICAgIC0gJ0ZPVU5EUllfQVdTX0NPTkZJRz0ke0ZPVU5EUllfQVdTX0NPTkZJR30nCiAgICAgIC0gJ0ZPVU5EUllfTEFOR1VBR0U9JHtGT1VORFJZX0xBTkdVQUdFOi1lbi5jb3JlfScKICAgICAgLSAnRk9VTkRSWV9DU1NfVEhFTUU9JHtGT1VORFJZX0NTU19USEVNRTotZm91bmRyeX0nCiAgICAgIC0gJ0ZPVU5EUllfTUlOSUZZX1NUQVRJQ19GSUxFUz0ke0ZPVU5EUllfTUlOSUZZX1NUQVRJQ19GSUxFUzotdHJ1ZX0nCiAgICAgIC0gJ0ZPVU5EUllfV09STEQ9JHtGT1VORFJZX1dPUkxEfScKICAgICAgLSAnRk9VTkRSWV9URUxFTUVUUlk9JHtGT1VORFJZX1RFTEVNRVRSWTotZmFsc2V9JwogICAgICAtICdUSU1FWk9ORT0ke1RJTUVaT05FOi1VVEN9JwogICAgICAtIENPTlRBSU5FUl9DQUNIRT0vZGF0YS9jb250YWluZXJfY2FjaGUKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ZvdW5kcnl2dHQtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTozMDAwMCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICByZXRyaWVzOiAzCg==", + "tags": [ + "foundryvtt", + "foundry", + "vtt", + "ttrpg", + "roleplaying" + ], + "logo": "svgs/foundryvtt.png", + "minversion": "0.0.0", + "port": "30000" + }, "freshrss-with-mariadb": { "documentation": "https://freshrss.org/index.html?utm_source=coolify.io", "slogan": "A free, self-hostable feed aggregator.", From 8182305ac46d601c08a27fb024aa6e3604a57c3e Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 24 Oct 2024 20:57:30 +0200 Subject: [PATCH 18/47] fix: admins should now invite owner --- app/Livewire/Team/InviteLink.php | 3 +++ resources/views/livewire/team/invite-link.blade.php | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/Livewire/Team/InviteLink.php b/app/Livewire/Team/InviteLink.php index 6c9e405fc..25f8a1ff5 100644 --- a/app/Livewire/Team/InviteLink.php +++ b/app/Livewire/Team/InviteLink.php @@ -41,6 +41,9 @@ private function generate_invite_link(bool $sendEmail = false) { try { $this->validate(); + if (auth()->user()->role() === 'admin' && $this->role === 'owner') { + throw new \Exception('Admins cannot invite owners.'); + } $member_emails = currentTeam()->members()->get()->pluck('email'); if ($member_emails->contains($this->email)) { return handleError(livewire: $this, customErrorMessage: "$this->email is already a member of ".currentTeam()->name.'.'); diff --git a/resources/views/livewire/team/invite-link.blade.php b/resources/views/livewire/team/invite-link.blade.php index 739c06267..2e0f02078 100644 --- a/resources/views/livewire/team/invite-link.blade.php +++ b/resources/views/livewire/team/invite-link.blade.php @@ -1,8 +1,10 @@

- + - + @if (auth()->user()->role() === 'owner') + + @endif From 0c34e81b2bfffa4bd11589d8d750748a1b3bbbc4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 24 Oct 2024 21:48:51 +0200 Subject: [PATCH 19/47] fix: add experimental flag --- app/Actions/Server/StartSentinel.php | 4 ++-- bootstrap/helpers/shared.php | 4 ++++ config/coolify.php | 1 + resources/views/livewire/server/form.blade.php | 4 ++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index e2af0c3ba..ad5d4cdb2 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -9,10 +9,10 @@ class StartSentinel { use AsAction; - public function handle(Server $server, bool $restart = false, bool $is_dev = false) + public function handle(Server $server, bool $restart = false) { // TODO: Sentinel is not available in this version (soon). - if (! $is_dev) { + if (! isExperimentalEnabled()) { return; } $version = get_latest_sentinel_version(); diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index cd0eb709a..99b7b4c6f 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -362,6 +362,10 @@ function isCloud(): bool return ! config('coolify.self_hosted'); } +function isExperimentalEnabled(): bool +{ + return config('coolify.is_experimental_enabled'); +} function translate_cron_expression($expression_to_validate): string { if (isset(VALID_CRON_STRINGS[$expression_to_validate])) { diff --git a/config/coolify.php b/config/coolify.php index f9878fff7..0a93d86ea 100644 --- a/config/coolify.php +++ b/config/coolify.php @@ -13,4 +13,5 @@ 'helper_image' => env('HELPER_IMAGE', 'ghcr.io/coollabsio/coolify-helper'), 'is_horizon_enabled' => env('HORIZON_ENABLED', true), 'is_scheduler_enabled' => env('SCHEDULER_ENABLED', true), + 'is_experimental_enabled' => env('EXPERIMENTAL_ENABLED', false), ]; diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index bfcd42d90..f3293ea0b 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -159,7 +159,7 @@ class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-co
@if (!$server->isSwarm() && !$server->isBuildServer()) - @if (isDev()) + @if (isExperimentalEnabled())

Sentinel

@if ($server->isSentinelEnabled()) @@ -181,7 +181,7 @@ class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-co

Sentinel

Sentinel is not available in this version (soon).
@endif - @if (isDev()) + @if (isExperimentalEnabled())
Date: Thu, 24 Oct 2024 22:00:26 +0200 Subject: [PATCH 20/47] Refactor function and configuration names for experimental features --- app/Actions/Server/StartSentinel.php | 2 +- bootstrap/helpers/shared.php | 4 ++-- config/coolify.php | 2 +- docker-compose.prod.yml | 1 + resources/views/livewire/server/form.blade.php | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index ad5d4cdb2..a8ef8b1fe 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -12,7 +12,7 @@ class StartSentinel public function handle(Server $server, bool $restart = false) { // TODO: Sentinel is not available in this version (soon). - if (! isExperimentalEnabled()) { + if (! isExperimentalFeaturesEnabled()) { return; } $version = get_latest_sentinel_version(); diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 99b7b4c6f..a92b682d7 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -362,9 +362,9 @@ function isCloud(): bool return ! config('coolify.self_hosted'); } -function isExperimentalEnabled(): bool +function isExperimentalFeaturesEnabled(): bool { - return config('coolify.is_experimental_enabled'); + return config('coolify.is_experimental_features_enabled'); } function translate_cron_expression($expression_to_validate): string { diff --git a/config/coolify.php b/config/coolify.php index 0a93d86ea..e81e5ebab 100644 --- a/config/coolify.php +++ b/config/coolify.php @@ -13,5 +13,5 @@ 'helper_image' => env('HELPER_IMAGE', 'ghcr.io/coollabsio/coolify-helper'), 'is_horizon_enabled' => env('HORIZON_ENABLED', true), 'is_scheduler_enabled' => env('SCHEDULER_ENABLED', true), - 'is_experimental_enabled' => env('EXPERIMENTAL_ENABLED', false), + 'is_experimental_features_enabled' => env('EXPERIMENTAL_FEATURES', false), ]; diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index b15a109c3..da300fccc 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -73,6 +73,7 @@ services: - STRIPE_PRICE_ID_ULTIMATE_MONTHLY_OLD - STRIPE_PRICE_ID_ULTIMATE_YEARLY_OLD - STRIPE_EXCLUDED_PLANS + - EXPERIMENTAL_FEATURES ports: - "${APP_PORT:-8000}:80" expose: diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index f3293ea0b..3f3361124 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -159,7 +159,7 @@ class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-co
@if (!$server->isSwarm() && !$server->isBuildServer()) - @if (isExperimentalEnabled()) + @if (isExperimentalFeaturesEnabled())

Sentinel

@if ($server->isSentinelEnabled()) @@ -181,7 +181,7 @@ class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-co

Sentinel

Sentinel is not available in this version (soon).
@endif - @if (isExperimentalEnabled()) + @if (isExperimentalFeaturesEnabled())
Date: Fri, 25 Oct 2024 08:39:58 +0200 Subject: [PATCH 21/47] Refactor function and configuration names for experimental features --- app/Livewire/Admin/Index.php | 23 ++++++++++++----------- routes/web.php | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/app/Livewire/Admin/Index.php b/app/Livewire/Admin/Index.php index 26b31e515..16cd9152e 100644 --- a/app/Livewire/Admin/Index.php +++ b/app/Livewire/Admin/Index.php @@ -14,6 +14,18 @@ class Index extends Component public $search = ''; + public function mount() + { + if (! isCloud()) { + return redirect()->route('dashboard'); + } + + if (auth()->user()->id !== 0) { + return redirect()->route('dashboard'); + } + $this->getSubscribers(); + } + public function submitSearch() { if ($this->search !== '') { @@ -38,17 +50,6 @@ public function submitSearch() } } - public function mount() - { - if (! isCloud()) { - return redirect()->route('dashboard'); - } - if (auth()->user()->id !== 0) { - return redirect()->route('dashboard'); - } - $this->getSubscribers(); - } - public function getSubscribers() { $this->inactive_subscribers = User::whereDoesntHave('teams', function ($query) { diff --git a/routes/web.php b/routes/web.php index eb1480b9f..d4cdff7e5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -83,9 +83,9 @@ Route::get('/admin', AdminIndex::class)->name('admin.index'); -Route::post('/forgot-password', [Controller::class, 'forgot_password'])->name('password.forgot'); +Route::post('/forgot-password', [Controller::class, 'forgot_password'])->name('password.forgot')->middleware('throttle:forgot-password'); Route::get('/realtime', [Controller::class, 'realtime_test'])->middleware('auth'); -Route::get('/waitlist', WaitlistIndex::class)->name('waitlist.index'); +// Route::get('/waitlist', WaitlistIndex::class)->name('waitlist.index'); Route::get('/verify', [Controller::class, 'verify'])->middleware('auth')->name('verify.email'); Route::get('/email/verify/{id}/{hash}', [Controller::class, 'email_verify'])->middleware(['auth'])->name('verify.verify'); Route::middleware(['throttle:login'])->group(function () { From 35a1307e7b1a89584fbc813022d3ed9d57259f2d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 10:59:05 +0200 Subject: [PATCH 22/47] Refactor variable and function names for consistency --- app/Livewire/Tags/Deployments.php | 10 ++-- app/Livewire/Tags/Index.php | 47 ++++++++++--------- app/Livewire/Tags/Show.php | 4 +- .../views/livewire/tags/deployments.blade.php | 4 +- resources/views/livewire/tags/index.blade.php | 29 +++++------- resources/views/livewire/tags/show.blade.php | 3 -- 6 files changed, 48 insertions(+), 49 deletions(-) diff --git a/app/Livewire/Tags/Deployments.php b/app/Livewire/Tags/Deployments.php index 270aa176a..e4afa5b60 100644 --- a/app/Livewire/Tags/Deployments.php +++ b/app/Livewire/Tags/Deployments.php @@ -7,19 +7,19 @@ class Deployments extends Component { - public $deployments_per_tag_per_server = []; + public $deploymentsPerTagPerServer = []; - public $resource_ids = []; + public $resourceIds = []; public function render() { return view('livewire.tags.deployments'); } - public function get_deployments() + public function getDeployments() { try { - $this->deployments_per_tag_per_server = ApplicationDeploymentQueue::whereIn('status', ['in_progress', 'queued'])->whereIn('application_id', $this->resource_ids)->get([ + $this->deploymentsPerTagPerServer = ApplicationDeploymentQueue::whereIn('status', ['in_progress', 'queued'])->whereIn('application_id', $this->resourceIds)->get([ 'id', 'application_id', 'application_name', @@ -29,7 +29,7 @@ public function get_deployments() 'server_id', 'status', ])->sortBy('id')->groupBy('server_name')->toArray(); - $this->dispatch('deployments', $this->deployments_per_tag_per_server); + $this->dispatch('deployments', $this->deploymentsPerTagPerServer); } catch (\Exception $e) { return handleError($e, $this); } diff --git a/app/Livewire/Tags/Index.php b/app/Livewire/Tags/Index.php index a01d00a70..642b2bded 100644 --- a/app/Livewire/Tags/Index.php +++ b/app/Livewire/Tags/Index.php @@ -5,9 +5,11 @@ use App\Http\Controllers\Api\DeployController; use App\Models\Tag; use Illuminate\Support\Collection; +use Livewire\Attributes\Title; use Livewire\Attributes\Url; use Livewire\Component; +#[Title('Tags | Coolify')] class Index extends Component { #[Url()] @@ -21,33 +23,47 @@ class Index extends Component public $webhook = null; - public $deployments_per_tag_per_server = []; + public $deploymentsPerTagPerServer = []; - protected $listeners = ['deployments' => 'update_deployments']; + protected $listeners = ['deployments' => 'updateDeployments']; - public function update_deployments($deployments) + public function render() { - $this->deployments_per_tag_per_server = $deployments; + return view('livewire.tags.index'); } - public function tag_updated() + public function mount() + { + $this->tags = Tag::ownedByCurrentTeam()->get()->unique('name')->sortBy('name'); + if ($this->tag) { + $this->tagUpdated(); + } + } + + public function updateDeployments($deployments) + { + $this->deploymentsPerTagPerServer = $deployments; + } + + public function tagUpdated() { if ($this->tag == '') { return; } - $tag = $this->tags->where('name', $this->tag)->first(); + $sanitizedTag = htmlspecialchars($this->tag, ENT_QUOTES, 'UTF-8'); + $tag = $this->tags->where('name', $sanitizedTag)->first(); if (! $tag) { - $this->dispatch('error', "Tag ({$this->tag}) not found."); + $this->dispatch('error', 'Tag ('.e($sanitizedTag).') not found.'); $this->tag = ''; return; } - $this->webhook = generatTagDeployWebhook($tag->name); + $this->webhook = generateTagDeployWebhook($tag->name); $this->applications = $tag->applications()->get(); $this->services = $tag->services()->get(); } - public function redeploy_all() + public function redeployAll() { try { $this->applications->each(function ($resource) { @@ -63,17 +79,4 @@ public function redeploy_all() return handleError($e, $this); } } - - public function mount() - { - $this->tags = Tag::ownedByCurrentTeam()->get()->unique('name')->sortBy('name'); - if ($this->tag) { - $this->tag_updated(); - } - } - - public function render() - { - return view('livewire.tags.index'); - } } diff --git a/app/Livewire/Tags/Show.php b/app/Livewire/Tags/Show.php index 668101edb..0dffcce57 100644 --- a/app/Livewire/Tags/Show.php +++ b/app/Livewire/Tags/Show.php @@ -5,8 +5,10 @@ use App\Http\Controllers\Api\DeployController; use App\Models\ApplicationDeploymentQueue; use App\Models\Tag; +use Livewire\Attributes\Title; use Livewire\Component; +#[Title('Tags | Coolify')] class Show extends Component { public $tags; @@ -28,7 +30,7 @@ public function mount() if (! $tag) { return redirect()->route('tags.index'); } - $this->webhook = generatTagDeployWebhook($tag->name); + $this->webhook = generateTagDeployWebhook($tag->name); $this->applications = $tag->applications()->get(); $this->services = $tag->services()->get(); $this->tag = $tag; diff --git a/resources/views/livewire/tags/deployments.blade.php b/resources/views/livewire/tags/deployments.blade.php index 03da021f9..8f23d994d 100644 --- a/resources/views/livewire/tags/deployments.blade.php +++ b/resources/views/livewire/tags/deployments.blade.php @@ -1,5 +1,5 @@ -
- @forelse ($deployments_per_tag_per_server as $server_name => $deployments) +
+ @forelse ($deploymentsPerTagPerServer as $server_name => $deployments)

{{ $server_name }}

@foreach ($deployments as $deployment) diff --git a/resources/views/livewire/tags/index.blade.php b/resources/views/livewire/tags/index.blade.php index 287e1da55..3a98519a7 100644 --- a/resources/views/livewire/tags/index.blade.php +++ b/resources/views/livewire/tags/index.blade.php @@ -1,15 +1,12 @@
- - Tags | Coolify -

Tags

-
+ @endif @endif diff --git a/resources/views/livewire/tags/show.blade.php b/resources/views/livewire/tags/show.blade.php index 869b56dae..f135a8246 100644 --- a/resources/views/livewire/tags/show.blade.php +++ b/resources/views/livewire/tags/show.blade.php @@ -1,7 +1,4 @@
- - Tag | Coolify -

Tags

From 2877080a392831d38979393f4a9cb235c23743a1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 10:59:12 +0200 Subject: [PATCH 23/47] Refactor variable and function names for consistency --- app/Livewire/Server/Form.php | 3 +- app/Models/Server.php | 6 ++-- app/Notifications/Server/HighDiskUsage.php | 3 -- bootstrap/helpers/shared.php | 2 +- .../views/livewire/settings/index.blade.php | 33 ++++++++++--------- 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index 0e4263e53..335b17396 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -174,7 +174,8 @@ public function instantSave() $this->server->settings->refresh(); return handleError($e, $this); - } finally {} + } finally { + } } public function restartSentinel($notification = true) diff --git a/app/Models/Server.php b/app/Models/Server.php index 4ad034d7e..1c6692041 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -131,11 +131,11 @@ protected static function booted() protected $guarded = []; - public function type() { return 'server'; } + public static function isReachable() { return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true); @@ -575,7 +575,6 @@ public function isServerApiEnabled() return $this->settings->is_sentinel_enabled; } - public function checkSentinel() { // ray("Checking sentinel on server: {$this->name}"); @@ -1273,11 +1272,12 @@ public function isIpv6(): bool public function restartSentinel() { try { - StartSentinel::dispatch($this,true); + StartSentinel::dispatch($this, true); } catch (\Throwable $e) { loggy('Error restarting Sentinel: '.$e->getMessage()); } } + public function url() { return base_url().'/server/'.$this->uuid; diff --git a/app/Notifications/Server/HighDiskUsage.php b/app/Notifications/Server/HighDiskUsage.php index 3a01aabe4..e373abc03 100644 --- a/app/Notifications/Server/HighDiskUsage.php +++ b/app/Notifications/Server/HighDiskUsage.php @@ -3,9 +3,6 @@ namespace App\Notifications\Server; use App\Models\Server; -use App\Notifications\Channels\DiscordChannel; -use App\Notifications\Channels\EmailChannel; -use App\Notifications\Channels\TelegramChannel; use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index a92b682d7..d658be125 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -651,7 +651,7 @@ function queryResourcesByUuid(string $uuid) return $resource; } -function generatTagDeployWebhook($tag_name) +function generateTagDeployWebhook($tag_name) { $baseUrl = base_url(); $api = Url::fromString($baseUrl).'/api/v1'; diff --git a/resources/views/livewire/settings/index.blade.php b/resources/views/livewire/settings/index.blade.php index 91084bff9..8eba94681 100644 --- a/resources/views/livewire/settings/index.blade.php +++ b/resources/views/livewire/settings/index.blade.php @@ -142,22 +142,23 @@ class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-coolgray-300 tex helper="When disabled, you will not need to confirm actions with a text and user password. This significantly reduces security and may lead to accidental deletions or unwanted changes. Use with extreme caution, especially on production servers." />
@else -
- -
+
+ +
+
+

Warning!

+

Disabling two step confirmation reduces security (as anyone can easily delete anything) and increases + the + risk of accidental actions. This is not recommended for production servers.

+
@endif -
-

Warning!

-

Disabling two step confirmation reduces security (as anyone can easily delete anything) and increases the - risk of accidental actions. This is not recommended for production servers.

-
From d26a0f194b97dd14525d4cf88cf47fb720935df5 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 11:17:17 +0200 Subject: [PATCH 24/47] Refactor flexbox layout and button styles in show-private-key.blade.php --- .../views/livewire/server/show-private-key.blade.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/views/livewire/server/show-private-key.blade.php b/resources/views/livewire/server/show-private-key.blade.php index f84086bff..7c24a3a9b 100644 --- a/resources/views/livewire/server/show-private-key.blade.php +++ b/resources/views/livewire/server/show-private-key.blade.php @@ -14,17 +14,17 @@
@forelse ($privateKeys as $private_key) -
-
+
+
{{ $private_key->name }}
{{ $private_key->description }}
@if (data_get($server, 'privateKey.uuid') !== $private_key->uuid) - - Use this key + + Use this key @else - + Currently used @endif From 254bae9dbd5fbf767149caf6ab8770e6e2b3a79d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 11:40:59 +0200 Subject: [PATCH 25/47] Refactor variable and function names for consistency --- app/Console/Kernel.php | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 01e480af5..3ad8af98c 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,13 +2,13 @@ namespace App\Console; +use App\Jobs\CheckAndStartSentinelJob; use App\Jobs\CheckForUpdatesJob; use App\Jobs\CheckHelperImageJob; use App\Jobs\CleanupInstanceStuffsJob; use App\Jobs\CleanupStaleMultiplexedConnections; use App\Jobs\DatabaseBackupJob; use App\Jobs\DockerCleanupJob; -use App\Jobs\PullSentinelImageJob; use App\Jobs\PullTemplatesFromCDN; use App\Jobs\ScheduledTaskJob; use App\Jobs\ServerCheckJob; @@ -23,11 +23,11 @@ class Kernel extends ConsoleKernel { - private $all_servers; + private $allServers; protected function schedule(Schedule $schedule): void { - $this->all_servers = Server::all(); + $this->allServers = Server::all(); $settings = instanceSettings(); $schedule->job(new CleanupStaleMultiplexedConnections)->hourly(); @@ -37,9 +37,9 @@ protected function schedule(Schedule $schedule): void $schedule->command('horizon:snapshot')->everyMinute(); $schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer(); // Server Jobs - $this->check_scheduled_backups($schedule); - $this->check_resources($schedule); - $this->check_scheduled_tasks($schedule); + $this->checkScheduledBackups($schedule); + $this->checkResources($schedule); + $this->checkScheduledTasks($schedule); $schedule->command('uploads:clear')->everyTwoMinutes(); $schedule->command('telescope:prune')->daily(); @@ -51,32 +51,27 @@ protected function schedule(Schedule $schedule): void $schedule->command('cleanup:unreachable-servers')->daily()->onOneServer(); $schedule->job(new PullTemplatesFromCDN)->cron($settings->update_check_frequency)->timezone($settings->instance_timezone)->onOneServer(); $schedule->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer(); - $this->schedule_updates($schedule); + $this->scheduleUpdates($schedule); // Server Jobs - $this->check_scheduled_backups($schedule); - $this->check_resources($schedule); - $this->pull_images($schedule); - $this->check_scheduled_tasks($schedule); + $this->checkScheduledBackups($schedule); + $this->checkResources($schedule); + $this->pullImages($schedule); + $this->checkScheduledTasks($schedule); $schedule->command('cleanup:database --yes')->daily(); $schedule->command('uploads:clear')->everyTwoMinutes(); } } - private function pull_images($schedule) + private function pullImages($schedule): void { $settings = instanceSettings(); - $servers = $this->all_servers->where('settings.is_usable', true)->where('settings.is_reachable', true)->where('ip', '!=', '1.2.3.4'); + $servers = $this->allServers->where('settings.is_usable', true)->where('settings.is_reachable', true)->where('ip', '!=', '1.2.3.4'); foreach ($servers as $server) { if ($server->isSentinelEnabled()) { $schedule->job(function () use ($server) { - $sentinel_found = instant_remote_process(['docker inspect coolify-sentinel'], $server, false); - $sentinel_found = json_decode($sentinel_found, true); - $status = data_get($sentinel_found, '0.State.Status', 'exited'); - if ($status !== 'running') { - PullSentinelImageJob::dispatch($server); - } + CheckAndStartSentinelJob::dispatch($server); })->cron($settings->update_check_frequency)->timezone($settings->instance_timezone)->onOneServer(); } } @@ -86,7 +81,7 @@ private function pull_images($schedule) ->onOneServer(); } - private function schedule_updates($schedule) + private function scheduleUpdates($schedule): void { $settings = instanceSettings(); @@ -105,14 +100,14 @@ private function schedule_updates($schedule) } } - private function check_resources($schedule) + private function checkResources($schedule): void { if (isCloud()) { - $servers = $this->all_servers->whereNotNull('team.subscription')->where('team.subscription.stripe_trial_already_ended', false)->where('ip', '!=', '1.2.3.4'); + $servers = $this->allServers->whereNotNull('team.subscription')->where('team.subscription.stripe_trial_already_ended', false)->where('ip', '!=', '1.2.3.4'); $own = Team::find(0)->servers; $servers = $servers->merge($own); } else { - $servers = $this->all_servers->where('ip', '!=', '1.2.3.4'); + $servers = $this->allServers->where('ip', '!=', '1.2.3.4'); } foreach ($servers as $server) { $last_sentinel_update = $server->sentinel_updated_at; @@ -128,7 +123,7 @@ private function check_resources($schedule) } } - private function check_scheduled_backups($schedule) + private function checkScheduledBackups($schedule): void { $scheduled_backups = ScheduledDatabaseBackup::all(); if ($scheduled_backups->isEmpty()) { @@ -161,7 +156,7 @@ private function check_scheduled_backups($schedule) } } - private function check_scheduled_tasks($schedule) + private function checkScheduledTasks($schedule): void { $scheduled_tasks = ScheduledTask::all(); if ($scheduled_tasks->isEmpty()) { From 2bea26584a3eeadc2281b741b498efa3d1ccfb57 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 11:41:25 +0200 Subject: [PATCH 26/47] Refactor StartSentinel handle method to include latest version parameter --- app/Actions/Server/StartSentinel.php | 10 ++--- app/Jobs/CheckAndStartSentinelJob.php | 56 +++++++++++++++++++++++++++ app/Jobs/PullSentinelImageJob.php | 47 ---------------------- app/Models/Server.php | 23 ++++------- 4 files changed, 67 insertions(+), 69 deletions(-) create mode 100644 app/Jobs/CheckAndStartSentinelJob.php delete mode 100644 app/Jobs/PullSentinelImageJob.php diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index a8ef8b1fe..be57590a0 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -9,19 +9,15 @@ class StartSentinel { use AsAction; - public function handle(Server $server, bool $restart = false) + public function handle(Server $server, bool $restart = false, ?string $latestVersion = null) { - // TODO: Sentinel is not available in this version (soon). - if (! isExperimentalFeaturesEnabled()) { - return; - } - $version = get_latest_sentinel_version(); if ($server->isSwarm() || $server->isBuildServer()) { return; } if ($restart) { StopSentinel::run($server); } + $version = $latestVersion ?? get_latest_sentinel_version(); $metrics_history = data_get($server, 'settings.sentinel_metrics_history_days'); $refresh_rate = data_get($server, 'settings.sentinel_metrics_refresh_rate_seconds'); $push_interval = data_get($server, 'settings.sentinel_push_interval_seconds'); @@ -42,8 +38,8 @@ public function handle(Server $server, bool $restart = false) ]; if (isDev()) { // data_set($environments, 'DEBUG', 'true'); - $mount_dir = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/sentinel'; // $image = 'sentinel'; + $mount_dir = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/sentinel'; } $docker_environments = '-e "'.implode('" -e "', array_map(fn ($key, $value) => "$key=$value", array_keys($environments), $environments)).'"'; diff --git a/app/Jobs/CheckAndStartSentinelJob.php b/app/Jobs/CheckAndStartSentinelJob.php new file mode 100644 index 000000000..8fbeee663 --- /dev/null +++ b/app/Jobs/CheckAndStartSentinelJob.php @@ -0,0 +1,56 @@ +server, false); + $sentinelFoundJson = json_decode($sentinelFound, true); + $sentinelStatus = data_get($sentinelFoundJson, '0.State.Status', 'exited'); + if ($sentinelStatus !== 'running') { + StartSentinel::run(server: $this->server, restart: true, latestVersion: $latestVersion); + + return; + } + // If sentinel is running, check if it needs an update + $runningVersion = instant_remote_process(['docker exec coolify-sentinel sh -c "curl http://127.0.0.1:8888/api/version"'], $this->server, false); + if (empty($runningVersion)) { + $runningVersion = '0.0.0'; + } + if ($latestVersion === '0.0.0' && $runningVersion === '0.0.0') { + StartSentinel::run(server: $this->server, restart: true, latestVersion: 'latest'); + + return; + } else { + if (version_compare($runningVersion, $latestVersion, '<')) { + StartSentinel::run(server: $this->server, restart: true, latestVersion: $latestVersion); + + return; + } + } + } catch (\Throwable $e) { + throw $e; + } + } +} diff --git a/app/Jobs/PullSentinelImageJob.php b/app/Jobs/PullSentinelImageJob.php deleted file mode 100644 index 054f81d99..000000000 --- a/app/Jobs/PullSentinelImageJob.php +++ /dev/null @@ -1,47 +0,0 @@ -server, false); - if (empty($local_version)) { - $local_version = '0.0.0'; - } - if (version_compare($local_version, $version, '<')) { - StartSentinel::run($this->server, true); - - return; - } - ray('Sentinel image is up to date'); - } catch (\Throwable $e) { - // send_internal_notification('PullSentinelImageJob failed with: '.$e->getMessage()); - ray($e->getMessage()); - throw $e; - } - } -} diff --git a/app/Models/Server.php b/app/Models/Server.php index 1c6692041..bd8177dd0 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -5,7 +5,7 @@ use App\Actions\Server\InstallDocker; use App\Actions\Server\StartSentinel; use App\Enums\ProxyTypes; -use App\Jobs\PullSentinelImageJob; +use App\Jobs\CheckAndStartSentinelJob; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\SoftDeletes; @@ -577,18 +577,7 @@ public function isServerApiEnabled() public function checkSentinel() { - // ray("Checking sentinel on server: {$this->name}"); - if ($this->isSentinelEnabled()) { - $sentinel_found = instant_remote_process(['docker inspect coolify-sentinel'], $this, false); - $sentinel_found = json_decode($sentinel_found, true); - $status = data_get($sentinel_found, '0.State.Status', 'exited'); - if ($status !== 'running') { - // ray('Sentinel is not running, starting it...'); - PullSentinelImageJob::dispatch($this); - } else { - // ray('Sentinel is running'); - } - } + CheckAndStartSentinelJob::dispatch($this); } public function getCpuMetrics(int $mins = 5) @@ -1269,10 +1258,14 @@ public function isIpv6(): bool return str($this->ip)->contains(':'); } - public function restartSentinel() + public function restartSentinel(bool $async = true): void { try { - StartSentinel::dispatch($this, true); + if ($async) { + StartSentinel::dispatch($this, true); + } else { + StartSentinel::run($this, true); + } } catch (\Throwable $e) { loggy('Error restarting Sentinel: '.$e->getMessage()); } From ba86a75c4fb808ae4b969cb58bf303f9d32b2ddf Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 11:41:29 +0200 Subject: [PATCH 27/47] Refactor ServerStatusJob to remove unnecessary coolify.yaml file --- app/Jobs/ServerStatusJob.php | 60 ------------------------------------ 1 file changed, 60 deletions(-) delete mode 100644 app/Jobs/ServerStatusJob.php diff --git a/app/Jobs/ServerStatusJob.php b/app/Jobs/ServerStatusJob.php deleted file mode 100644 index fcc33c859..000000000 --- a/app/Jobs/ServerStatusJob.php +++ /dev/null @@ -1,60 +0,0 @@ -server->isServerReady($this->tries)) { - throw new \RuntimeException('Server is not ready.'); - } - try { - if ($this->server->isFunctional()) { - $this->remove_unnecessary_coolify_yaml(); - if ($this->server->isSentinelEnabled()) { - $this->server->checkSentinel(); - } - } - } catch (\Throwable $e) { - // send_internal_notification('ServerStatusJob failed with: '.$e->getMessage()); - ray($e->getMessage()); - - return handleError($e); - } - - } - - private function remove_unnecessary_coolify_yaml() - { - // This will remote the coolify.yaml file from the server as it is not needed on cloud servers - if (isCloud() && $this->server->id !== 0) { - $file = $this->server->proxyPath().'/dynamic/coolify.yaml'; - - return instant_remote_process([ - "rm -f $file", - ], $this->server, false); - } - } -} From 7ed0ebf106ee7e96faefc419671cf861eec80363 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 11:41:52 +0200 Subject: [PATCH 28/47] fix: generateSentinelUrl method --- app/Models/ServerSetting.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/Models/ServerSetting.php b/app/Models/ServerSetting.php index 5011009e6..b72fa3acf 100644 --- a/app/Models/ServerSetting.php +++ b/app/Models/ServerSetting.php @@ -106,12 +106,13 @@ public function generateSentinelUrl(bool $save = true) $domain = 'http://host.docker.internal:8000'; } elseif ($settings->fqdn) { $domain = $settings->fqdn; - } elseif ($settings->ipv4) { - $domain = $settings->ipv4.':8000'; - } elseif ($settings->ipv6) { - $domain = $settings->ipv6.':8000'; + } elseif ($settings->public_ipv4) { + $domain = 'http://'.$settings->public_ipv4.':8000'; + } elseif ($settings->public_ipv6) { + $domain = 'http://'.$settings->public_ipv6.':8000'; } $this->sentinel_custom_url = $domain; + loggy('Sentinel URL: '.$domain); if ($save) { $this->save(); } From b03767713f9880d1ebc7e2d9da98bf0858bf5cc4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 11:42:25 +0200 Subject: [PATCH 29/47] remove experimental features env variable --- config/coolify.php | 1 - docker-compose.prod.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/config/coolify.php b/config/coolify.php index e81e5ebab..f9878fff7 100644 --- a/config/coolify.php +++ b/config/coolify.php @@ -13,5 +13,4 @@ 'helper_image' => env('HELPER_IMAGE', 'ghcr.io/coollabsio/coolify-helper'), 'is_horizon_enabled' => env('HORIZON_ENABLED', true), 'is_scheduler_enabled' => env('SCHEDULER_ENABLED', true), - 'is_experimental_features_enabled' => env('EXPERIMENTAL_FEATURES', false), ]; diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index da300fccc..b15a109c3 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -73,7 +73,6 @@ services: - STRIPE_PRICE_ID_ULTIMATE_MONTHLY_OLD - STRIPE_PRICE_ID_ULTIMATE_YEARLY_OLD - STRIPE_EXCLUDED_PLANS - - EXPERIMENTAL_FEATURES ports: - "${APP_PORT:-8000}:80" expose: From 2263734129e4b4fe38bcd2f7c4b5beebfe81a3cc Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 11:42:37 +0200 Subject: [PATCH 30/47] save sentinel form update --- app/Livewire/Server/Form.php | 16 ++- bootstrap/helpers/shared.php | 7 -- .../views/livewire/server/form.blade.php | 109 +++++++++--------- 3 files changed, 67 insertions(+), 65 deletions(-) diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index 335b17396..82d9f5d8e 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -178,6 +178,19 @@ public function instantSave() } } + public function saveSentinel() + { + try { + $this->validate(); + $this->server->settings->save(); + $this->dispatch('success', 'Sentinel updated.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } finally { + $this->checkSyncStatus(); + } + } + public function restartSentinel($notification = true) { try { @@ -185,7 +198,8 @@ public function restartSentinel($notification = true) $this->validate([ 'server.settings.sentinel_custom_url' => 'required|url', ]); - $this->server->restartSentinel(); + $this->server->settings->save(); + $this->server->restartSentinel(async: false); if ($notification) { $this->dispatch('success', 'Sentinel restarted.'); } diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index d658be125..7ae9df749 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -173,9 +173,6 @@ function get_latest_sentinel_version(): string return data_get($versions, 'coolify.sentinel.version'); } catch (\Throwable $e) { - //throw $e; - ray($e->getMessage()); - return '0.0.0'; } } @@ -362,10 +359,6 @@ function isCloud(): bool return ! config('coolify.self_hosted'); } -function isExperimentalFeaturesEnabled(): bool -{ - return config('coolify.is_experimental_features_enabled'); -} function translate_cron_expression($expression_to_validate): string { if (isset(VALID_CRON_STRINGS[$expression_to_validate])) { diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 3f3361124..35ec6c71b 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -158,68 +158,63 @@ class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-co @endif
- @if (!$server->isSwarm() && !$server->isBuildServer()) - @if (isExperimentalFeaturesEnabled()) -
-

Sentinel

- @if ($server->isSentinelEnabled()) -
settings->sentinel_push_interval_seconds }}s="checkSyncStatus"> - @if ($server->isSentinelLive()) - - Restart - @else - - Sync - @endif -
- @endif -
- @else + + @if ($server->isFunctional() && !$server->isSwarm() && !$server->isBuildServer()) +
+

Sentinel

-
Sentinel is not available in this version (soon).
- @endif - @if (isExperimentalFeaturesEnabled()) -
-
- - @if ($server->isSentinelEnabled()) - + @if ($server->isSentinelEnabled()) +
+ @if ($server->isSentinelLive()) + + Save + Restart @else - + + Save + Sync @endif
+ @endif +
+
+
+ @if ($server->isSentinelEnabled()) -
- - Regenerate -
- - - -
-
- - - -
-
+ + @else + @endif
- @endif - @endif - + @if ($server->isSentinelEnabled()) +
+ + Regenerate +
+ + + +
+
+ + + +
+
+ @endif +
+ + @endif +
From c099936e76c3b9757318b55ebaf5fd10e1bbc86c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 11:43:55 +0200 Subject: [PATCH 31/47] Refactor StartSentinel handle method to use consistent variable naming conventions --- app/Actions/Server/StartSentinel.php | 33 +++++++++++++++------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index be57590a0..aef7282e3 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -18,12 +18,12 @@ public function handle(Server $server, bool $restart = false, ?string $latestVer StopSentinel::run($server); } $version = $latestVersion ?? get_latest_sentinel_version(); - $metrics_history = data_get($server, 'settings.sentinel_metrics_history_days'); - $refresh_rate = data_get($server, 'settings.sentinel_metrics_refresh_rate_seconds'); - $push_interval = data_get($server, 'settings.sentinel_push_interval_seconds'); + $metricsHistory = data_get($server, 'settings.sentinel_metrics_history_days'); + $refreshRate = data_get($server, 'settings.sentinel_metrics_refresh_rate_seconds'); + $pushInterval = data_get($server, 'settings.sentinel_push_interval_seconds'); $token = data_get($server, 'settings.sentinel_token'); $endpoint = data_get($server, 'settings.sentinel_custom_url'); - $mount_dir = '/data/coolify/sentinel'; + $mountDir = '/data/coolify/sentinel'; $image = "ghcr.io/coollabsio/sentinel:$version"; if (! $endpoint) { throw new \Exception('You should set FQDN in Instance Settings.'); @@ -31,26 +31,29 @@ public function handle(Server $server, bool $restart = false, ?string $latestVer $environments = [ 'TOKEN' => $token, 'PUSH_ENDPOINT' => $endpoint, - 'PUSH_INTERVAL_SECONDS' => $push_interval, + 'PUSH_INTERVAL_SECONDS' => $pushInterval, 'COLLECTOR_ENABLED' => $server->isMetricsEnabled() ? 'true' : 'false', - 'COLLECTOR_REFRESH_RATE_SECONDS' => $refresh_rate, - 'COLLECTOR_RETENTION_PERIOD_DAYS' => $metrics_history, + 'COLLECTOR_REFRESH_RATE_SECONDS' => $refreshRate, + 'COLLECTOR_RETENTION_PERIOD_DAYS' => $metricsHistory, + ]; + $labels = [ + 'coolify.managed' => 'true', ]; if (isDev()) { // data_set($environments, 'DEBUG', 'true'); // $image = 'sentinel'; - $mount_dir = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/sentinel'; + $mountDir = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/sentinel'; } - $docker_environments = '-e "'.implode('" -e "', array_map(fn ($key, $value) => "$key=$value", array_keys($environments), $environments)).'"'; - - $docker_command = "docker run -d $docker_environments --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v $mount_dir:/app/db --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 --add-host=host.docker.internal:host-gateway $image"; + $dockerEnvironments = '-e "'.implode('" -e "', array_map(fn ($key, $value) => "$key=$value", array_keys($environments), $environments)).'"'; + $dockerLabels = implode(' ', array_map(fn ($key, $value) => "$key=$value", array_keys($labels), $labels)); + $dockerCommand = "docker run -d $dockerEnvironments --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v $mountDir:/app/db --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 --add-host=host.docker.internal:host-gateway --label $dockerLabels $image"; instant_remote_process([ 'docker rm -f coolify-sentinel || true', - "mkdir -p $mount_dir", - $docker_command, - "chown -R 9999:root $mount_dir", - "chmod -R 700 $mount_dir", + "mkdir -p $mountDir", + $dockerCommand, + "chown -R 9999:root $mountDir", + "chmod -R 700 $mountDir", ], $server); $server->settings->is_sentinel_enabled = true; From fb75741aa89378334799a560d6a400c44c350e18 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 12:02:41 +0200 Subject: [PATCH 32/47] add sentinel check to servercheckjob --- app/Jobs/ServerCheckJob.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Jobs/ServerCheckJob.php b/app/Jobs/ServerCheckJob.php index 0013ab784..f4720d035 100644 --- a/app/Jobs/ServerCheckJob.php +++ b/app/Jobs/ServerCheckJob.php @@ -67,9 +67,14 @@ public function handle() ServerStorageCheckJob::dispatch($this->server); GetContainersStatus::run($this->server, $this->containers, $containerReplicates); + if ($this->server->isSentinelEnabled()) { + CheckAndStartSentinelJob::dispatch($this->server); + } + if ($this->server->isLogDrainEnabled()) { $this->checkLogDrainContainer(); } + if ($this->server->proxySet() && ! $this->server->proxy->force_stop) { $this->server->proxyType(); $foundProxyContainer = $this->containers->filter(function ($value, $key) { From 8c96ab52d7f6f7259b05bd2560578fce0f6945c1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 15:13:23 +0200 Subject: [PATCH 33/47] feat: notification rate limiter fix: limit server up / down notification limits --- app/Console/Kernel.php | 6 +- app/Jobs/PushServerUpdateJob.php | 12 -- app/Jobs/ServerCheckJob.php | 48 +---- app/Models/Server.php | 190 ++++++++---------- app/Models/ServerSetting.php | 19 +- .../Server/{Revived.php => Reachable.php} | 33 +-- app/Notifications/Server/Unreachable.php | 34 ++-- bootstrap/helpers/shared.php | 28 +++ scripts/run | 8 +- 9 files changed, 161 insertions(+), 217 deletions(-) rename app/Notifications/Server/{Revived.php => Reachable.php} (74%) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 3ad8af98c..1e55aa57f 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -110,11 +110,11 @@ private function checkResources($schedule): void $servers = $this->allServers->where('ip', '!=', '1.2.3.4'); } foreach ($servers as $server) { - $last_sentinel_update = $server->sentinel_updated_at; - if (Carbon::parse($last_sentinel_update)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) { + $lastSentinelUpdate = $server->sentinel_updated_at; + $serverTimezone = $server->settings->server_timezone; + if (Carbon::parse($lastSentinelUpdate)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) { $schedule->job(new ServerCheckJob($server))->everyMinute()->onOneServer(); } - $serverTimezone = $server->settings->server_timezone; if ($server->settings->force_docker_cleanup) { $schedule->job(new DockerCleanupJob($server))->cron($server->settings->docker_cleanup_frequency)->timezone($serverTimezone)->onOneServer(); } else { diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index 384deb80e..62f059129 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -97,8 +97,6 @@ public function handle() } $data = collect($this->data); - $this->serverStatus(); - $this->server->sentinelHeartbeat(); $this->containers = collect(data_get($data, 'containers')); @@ -212,16 +210,6 @@ public function handle() } - private function serverStatus() - { - if ($this->server->isFunctional() === false) { - throw new \Exception('Server is not ready.'); - } - if ($this->server->status() === false) { - throw new \Exception('Server is not reachable.'); - } - } - private function updateApplicationStatus(string $applicationId, string $containerStatus) { $application = $this->applications->where('id', $applicationId)->first(); diff --git a/app/Jobs/ServerCheckJob.php b/app/Jobs/ServerCheckJob.php index f4720d035..5ac98e954 100644 --- a/app/Jobs/ServerCheckJob.php +++ b/app/Jobs/ServerCheckJob.php @@ -43,22 +43,15 @@ public function __construct(public Server $server) {} public function handle() { try { + if ($this->server->serverStatus() === false) { + return 'Server is not reachable or not ready.'; + } + $this->applications = $this->server->applications(); $this->databases = $this->server->databases(); $this->services = $this->server->services()->get(); $this->previews = $this->server->previews(); - $up = $this->serverStatus(); - if (! $up) { - ray('Server is not reachable.'); - - return 'Server is not reachable.'; - } - if (! $this->server->isFunctional()) { - ray('Server is not ready.'); - - return 'Server is not ready.'; - } if (! $this->server->isSwarmWorker() && ! $this->server->isBuildServer()) { ['containers' => $this->containers, 'containerReplicates' => $containerReplicates] = $this->server->getContainers(); if (is_null($this->containers)) { @@ -111,39 +104,6 @@ public function handle() } - private function serverStatus() - { - ['uptime' => $uptime] = $this->server->validateConnection(false); - if ($uptime) { - if ($this->server->unreachable_notification_sent === true) { - $this->server->update(['unreachable_notification_sent' => false]); - } - } else { - // $this->server->team?->notify(new Unreachable($this->server)); - foreach ($this->applications as $application) { - $application->update(['status' => 'exited']); - } - foreach ($this->databases as $database) { - $database->update(['status' => 'exited']); - } - foreach ($this->services as $service) { - $apps = $service->applications()->get(); - $dbs = $service->databases()->get(); - foreach ($apps as $app) { - $app->update(['status' => 'exited']); - } - foreach ($dbs as $db) { - $db->update(['status' => 'exited']); - } - } - - return false; - } - - return true; - - } - private function checkLogDrainContainer() { $foundLogDrainContainer = $this->containers->filter(function ($value, $key) { diff --git a/app/Models/Server.php b/app/Models/Server.php index bd8177dd0..2f023a248 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -6,6 +6,8 @@ use App\Actions\Server\StartSentinel; use App\Enums\ProxyTypes; use App\Jobs\CheckAndStartSentinelJob; +use App\Notifications\Server\Reachable; +use App\Notifications\Server\Unreachable; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\SoftDeletes; @@ -61,6 +63,7 @@ protected static function booted() $payload['ip'] = str($server->ip)->trim(); } $server->forceFill($payload); + }); static::created(function ($server) { ServerSetting::create([ @@ -107,12 +110,15 @@ protected static function booted() }); } - public $casts = [ + protected $casts = [ 'proxy' => SchemalessAttributes::class, 'logdrain_axiom_api_key' => 'encrypted', 'logdrain_newrelic_license_key' => 'encrypted', 'delete_unused_volumes' => 'boolean', 'delete_unused_networks' => 'boolean', + 'unreachable_notification_sent' => 'boolean', + 'is_build_server' => 'boolean', + 'force_disabled' => 'boolean', ]; protected $schemalessAttributes = [ @@ -519,16 +525,14 @@ public function isForceDisabled() public function forceEnableServer() { - $this->settings->update([ - 'force_disabled' => false, - ]); + $this->settings->force_disabled = false; + $this->settings->save(); } public function forceDisableServer() { - $this->settings->update([ - 'force_disabled' => true, - ]); + $this->settings->force_disabled = true; + $this->settings->save(); $sshKeyFileLocation = "id.root@{$this->uuid}"; Storage::disk('ssh-keys')->delete($sshKeyFileLocation); Storage::disk('ssh-mux')->delete($this->muxFilename()); @@ -624,72 +628,6 @@ public function getMemoryMetrics(int $mins = 5) } } - public function isServerReady(int $tries = 3) - { - if ($this->skipServer()) { - return false; - } - $serverUptimeCheckNumber = $this->unreachable_count; - if ($this->unreachable_count < $tries) { - $serverUptimeCheckNumber = $this->unreachable_count + 1; - } - if ($this->unreachable_count > $tries) { - $serverUptimeCheckNumber = $tries; - } - - $serverUptimeCheckNumberMax = $tries; - - // ray('server: ' . $this->name); - // ray('serverUptimeCheckNumber: ' . $serverUptimeCheckNumber); - // ray('serverUptimeCheckNumberMax: ' . $serverUptimeCheckNumberMax); - - ['uptime' => $uptime] = $this->validateConnection(); - if ($uptime) { - if ($this->unreachable_notification_sent === true) { - $this->update(['unreachable_notification_sent' => false]); - } - - return true; - } else { - if ($serverUptimeCheckNumber >= $serverUptimeCheckNumberMax) { - // Reached max number of retries - if ($this->unreachable_notification_sent === false) { - ray('Server unreachable, sending notification...'); - // $this->team?->notify(new Unreachable($this)); - $this->update(['unreachable_notification_sent' => true]); - } - if ($this->settings->is_reachable === true) { - $this->settings()->update([ - 'is_reachable' => false, - ]); - } - - foreach ($this->applications() as $application) { - $application->update(['status' => 'exited']); - } - foreach ($this->databases() as $database) { - $database->update(['status' => 'exited']); - } - foreach ($this->services()->get() as $service) { - $apps = $service->applications()->get(); - $dbs = $service->databases()->get(); - foreach ($apps as $app) { - $app->update(['status' => 'exited']); - } - foreach ($dbs as $db) { - $db->update(['status' => 'exited']); - } - } - } else { - $this->update([ - 'unreachable_count' => $this->unreachable_count + 1, - ]); - } - - return false; - } - } - public function getDiskUsage(): ?string { return instant_remote_process(['df / --output=pcent | tr -cd 0-9'], $this, false); @@ -1038,29 +976,43 @@ public function isSwarmWorker() return data_get($this, 'settings.is_swarm_worker'); } + public function serverStatus(): bool + { + if ($this->status() === false) { + return false; + } + if ($this->isFunctional() === false) { + return false; + } + + return true; + } + public function status(): bool { + if ($this->skipServer()) { + return false; + } ['uptime' => $uptime] = $this->validateConnection(false); - if ($uptime) { - if ($this->unreachable_notification_sent === true) { - $this->update(['unreachable_notification_sent' => false]); + if ($uptime === false) { + foreach ($this->applications() as $application) { + $application->status = 'exited'; + $application->save(); } - } else { - // $this->server->team?->notify(new Unreachable($this->server)); - foreach ($this->applications as $application) { - $application->update(['status' => 'exited']); + foreach ($this->databases() as $database) { + $database->status = 'exited'; + $database->save(); } - foreach ($this->databases as $database) { - $database->update(['status' => 'exited']); - } - foreach ($this->services as $service) { + foreach ($this->services() as $service) { $apps = $service->applications()->get(); $dbs = $service->databases()->get(); foreach ($apps as $app) { - $app->update(['status' => 'exited']); + $app->status = 'exited'; + $app->save(); } foreach ($dbs as $db) { - $db->update(['status' => 'exited']); + $db->status = 'exited'; + $db->save(); } } @@ -1070,39 +1022,65 @@ public function status(): bool return true; } + public function isReachableChanged() + { + $this->refresh(); + $unreachableNotificationSent = (bool) $this->unreachable_notification_sent; + $isReachable = (bool) $this->settings->is_reachable; + loggy('Server setting is_reachable changed to '.$isReachable.' for server '.$this->id.'. Unreachable notification sent: '.$unreachableNotificationSent); + // If the server is reachable, send the reachable notification if it was sent before + if ($isReachable === true) { + if ($unreachableNotificationSent === true) { + $this->sendReachableNotification(); + } + } else { + // If the server is unreachable, send the unreachable notification if it was not sent before + if ($unreachableNotificationSent === false) { + $this->sendUnreachableNotification(); + } + } + } + + public function sendReachableNotification() + { + $this->unreachable_notification_sent = false; + $this->save(); + $this->refresh(); + $this->team->notify(new Reachable($this)); + } + + public function sendUnreachableNotification() + { + $this->unreachable_notification_sent = true; + $this->save(); + $this->refresh(); + $this->team->notify(new Unreachable($this)); + } + public function validateConnection($isManualCheck = true) { config()->set('constants.ssh.mux_enabled', ! $isManualCheck); - // ray('Manual Check: ' . ($isManualCheck ? 'true' : 'false')); - $server = Server::find($this->id); - if (! $server) { - return ['uptime' => false, 'error' => 'Server not found.']; - } - if ($server->skipServer()) { + if ($this->skipServer()) { return ['uptime' => false, 'error' => 'Server skipped.']; } try { // Make sure the private key is stored - if ($server->privateKey) { - $server->privateKey->storeInFileSystem(); + if ($this->privateKey) { + $this->privateKey->storeInFileSystem(); } - instant_remote_process(['ls /'], $server); - $server->settings()->update([ - 'is_reachable' => true, - ]); - $server->update([ - 'unreachable_count' => 0, - ]); - if (data_get($server, 'unreachable_notification_sent') === true) { - $server->update(['unreachable_notification_sent' => false]); + instant_remote_process(['ls /'], $this); + if ($this->settings->is_reachable === false) { + $this->settings->is_reachable = true; + $this->settings->save(); } return ['uptime' => true, 'error' => null]; } catch (\Throwable $e) { - $server->settings()->update([ - 'is_reachable' => false, - ]); + if ($this->settings->is_reachable === true) { + $this->settings->is_reachable = false; + $this->settings->save(); + } return ['uptime' => false, 'error' => $e->getMessage()]; } diff --git a/app/Models/ServerSetting.php b/app/Models/ServerSetting.php index b72fa3acf..7a8e7b8ed 100644 --- a/app/Models/ServerSetting.php +++ b/app/Models/ServerSetting.php @@ -54,6 +54,8 @@ class ServerSetting extends Model 'force_docker_cleanup' => 'boolean', 'docker_cleanup_threshold' => 'integer', 'sentinel_token' => 'encrypted', + 'is_reachable' => 'boolean', + 'is_usable' => 'boolean', ]; protected static function booted() @@ -70,15 +72,18 @@ protected static function booted() loggy('Error creating server setting: '.$e->getMessage()); } }); - static::updated(function ($setting) { + static::updated(function ($settings) { if ( - $setting->isDirty('sentinel_token') || - $setting->isDirty('sentinel_custom_url') || - $setting->isDirty('sentinel_metrics_refresh_rate_seconds') || - $setting->isDirty('sentinel_metrics_history_days') || - $setting->isDirty('sentinel_push_interval_seconds') + $settings->isDirty('sentinel_token') || + $settings->isDirty('sentinel_custom_url') || + $settings->isDirty('sentinel_metrics_refresh_rate_seconds') || + $settings->isDirty('sentinel_metrics_history_days') || + $settings->isDirty('sentinel_push_interval_seconds') ) { - $setting->server->restartSentinel(); + $settings->server->restartSentinel(); + } + if ($settings->isDirty('is_reachable')) { + $settings->server->isReachableChanged(); } }); } diff --git a/app/Notifications/Server/Revived.php b/app/Notifications/Server/Reachable.php similarity index 74% rename from app/Notifications/Server/Revived.php rename to app/Notifications/Server/Reachable.php index 8d1ceeaef..9b54501d9 100644 --- a/app/Notifications/Server/Revived.php +++ b/app/Notifications/Server/Reachable.php @@ -2,8 +2,6 @@ namespace App\Notifications\Server; -use App\Actions\Docker\GetContainersStatus; -use App\Jobs\ContainerStatusJob; use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; @@ -13,25 +11,28 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; -use Illuminate\Support\Facades\RateLimiter; -class Revived extends Notification implements ShouldQueue +class Reachable extends Notification implements ShouldQueue { use Queueable; public $tries = 1; + protected bool $isRateLimited = false; + public function __construct(public Server $server) { - if ($this->server->unreachable_notification_sent === false) { - return; - } - GetContainersStatus::dispatch($server)->onQueue('high'); - // dispatch(new ContainerStatusJob($server)); + $this->isRateLimited = isEmailRateLimited( + limiterKey: 'server-reachable:'.$this->server->id, + ); } public function via(object $notifiable): array { + if ($this->isRateLimited) { + return []; + } + $channels = []; $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); @@ -46,20 +47,8 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } - $executed = RateLimiter::attempt( - 'notification-server-revived-'.$this->server->uuid, - 1, - function () use ($channels) { - return $channels; - }, - 7200, - ); - if (! $executed) { - return []; - } - - return $executed; + return $channels; } public function toMail(): MailMessage diff --git a/app/Notifications/Server/Unreachable.php b/app/Notifications/Server/Unreachable.php index 65ea6a2ff..5bc568e82 100644 --- a/app/Notifications/Server/Unreachable.php +++ b/app/Notifications/Server/Unreachable.php @@ -11,7 +11,6 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; -use Illuminate\Support\Facades\RateLimiter; class Unreachable extends Notification implements ShouldQueue { @@ -19,10 +18,21 @@ class Unreachable extends Notification implements ShouldQueue public $tries = 1; - public function __construct(public Server $server) {} + protected bool $isRateLimited = false; + + public function __construct(public Server $server) + { + $this->isRateLimited = isEmailRateLimited( + limiterKey: 'server-unreachable:'.$this->server->id, + ); + } public function via(object $notifiable): array { + if ($this->isRateLimited) { + return []; + } + $channels = []; $isEmailEnabled = isEmailEnabled($notifiable); $isDiscordEnabled = data_get($notifiable, 'discord_enabled'); @@ -37,23 +47,11 @@ public function via(object $notifiable): array if ($isTelegramEnabled) { $channels[] = TelegramChannel::class; } - $executed = RateLimiter::attempt( - 'notification-server-unreachable-'.$this->server->uuid, - 1, - function () use ($channels) { - return $channels; - }, - 7200, - ); - if (! $executed) { - return []; - } - - return $executed; + return $channels; } - public function toMail(): MailMessage + public function toMail(): ?MailMessage { $mail = new MailMessage; $mail->subject("Coolify: Your server ({$this->server->name}) is unreachable."); @@ -64,7 +62,7 @@ public function toMail(): MailMessage return $mail; } - public function toDiscord(): DiscordMessage + public function toDiscord(): ?DiscordMessage { $message = new DiscordMessage( title: ':cross_mark: Server unreachable', @@ -77,7 +75,7 @@ public function toDiscord(): DiscordMessage return $message; } - public function toTelegram(): array + public function toTelegram(): ?array { return [ 'message' => "Coolify: Your server '{$this->server->name}' is unreachable. All automations & integrations are turned off! Please check your server! IMPORTANT: We automatically try to revive your server and turn on all automations & integrations.", diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 7ae9df749..dbab6861d 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -39,6 +39,7 @@ use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Process; +use Illuminate\Support\Facades\RateLimiter; use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Validator; @@ -4038,3 +4039,30 @@ function sslipDomainWarning(string $domains) return $showSslipHttpsWarning; } + +function isEmailRateLimited(string $limiterKey, int $decaySeconds = 3600, ?callable $callbackOnSuccess = null): bool +{ + if (isDev()) { + $decaySeconds = 120; + } + $rateLimited = false; + $executed = RateLimiter::attempt( + $limiterKey, + $maxAttempts = 0, + function () use (&$rateLimited, &$limiterKey, $callbackOnSuccess) { + isDev() && loggy('Rate limit not reached for '.$limiterKey); + $rateLimited = false; + + if ($callbackOnSuccess) { + $callbackOnSuccess(); + } + }, + $decaySeconds, + ); + if (! $executed) { + isDev() && loggy('Rate limit reached for '.$limiterKey.'. Rate limiter will be disabled for '.$decaySeconds.' seconds.'); + $rateLimited = true; + } + + return $rateLimited; +} diff --git a/scripts/run b/scripts/run index f8ac0f97d..f7e7b5264 100755 --- a/scripts/run +++ b/scripts/run @@ -20,6 +20,9 @@ function help { compgen -A function | cat -n } +function logs { + docker exec -t coolify tail -f storage/logs/laravel.log +} function test { docker exec -t coolify php artisan test --testsuite=Feature } @@ -35,11 +38,6 @@ function db:reset-prod { bash spin exec -u webuser coolify php artisan migrate:fresh --force --seed --seeder=ProductionSeeder || php artisan migrate:fresh --force --seed --seeder=ProductionSeeder } - -function mfs { - db:reset -} - function coolify { bash spin exec -u webuser coolify bash } From 898623ef8313f3f1d80a98453991f0a17de85c61 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:22:00 +0200 Subject: [PATCH 34/47] remove jupyterlab - as it is a personal image --- public/svgs/jupyterlab.svg | 90 ------------------------------- templates/compose/jupyterlab.yaml | 31 ----------- 2 files changed, 121 deletions(-) delete mode 100644 public/svgs/jupyterlab.svg delete mode 100644 templates/compose/jupyterlab.yaml diff --git a/public/svgs/jupyterlab.svg b/public/svgs/jupyterlab.svg deleted file mode 100644 index ab2550874..000000000 --- a/public/svgs/jupyterlab.svg +++ /dev/null @@ -1,90 +0,0 @@ - -Group.svg -Created using Figma 0.90 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/templates/compose/jupyterlab.yaml b/templates/compose/jupyterlab.yaml deleted file mode 100644 index 765e8cc06..000000000 --- a/templates/compose/jupyterlab.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# documentation: https://jupyterlab.readthedocs.io/en/latest/ -# slogan: JupyterLab Notebook with C++ (xeus-cling) and Javascript (Deno) Kernel -# tags: jupyter,notebook,python,cpp,deno,jupyterlab -# logo: svgs/jupyterlab.svg -# port: 8008 - -services: - jupyterlab: - image: yokowasis/jupyterlab - platform: linux/amd64 - expose: - - 8008 - environment: - - SERVICE_FQDN_JUPYTERLAB_8008 - - PORT=${PORT:-8008} - - TOKEN=${SERVICE_PASSWORD_TOKEN} - - CONDA_PACKAGES=${CONDA_PACKAGES:-pandas numpy matplotlib seaborn scikit-learn pytorch nltk openpyxl category_encoders scikit-learn tensorflow spacy} - - PIP_PACKAGES=${PIP_PACKAGES:-sastrawi} - volumes: - - jupyterlab-data:/home/mambauser/data - healthcheck: - test: - [ - "CMD", - "curl", - "-f", - "http://127.0.0.1:8008/login/", - ] - timeout: 5s - interval: 5s - retries: 5 From 999bb29ce6b74199d9706bfa5885f074a5730719 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:22:28 +0200 Subject: [PATCH 35/47] remove dashboard very outdated --- templates/compose/dashboard.yaml | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 templates/compose/dashboard.yaml diff --git a/templates/compose/dashboard.yaml b/templates/compose/dashboard.yaml deleted file mode 100644 index f977e3876..000000000 --- a/templates/compose/dashboard.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# documentation: https://github.com/phntxx/dashboard?tab=readme-ov-file#dashboard -# slogan: A dashboard, inspired by SUI. -# tags: dashboard, web, search, bookmarks -# port: 8080 - -services: - dashboard: - image: phntxx/dashboard:latest - environment: - - SERVICE_FQDN_DASHBOARD_8080 - volumes: - - dashboard-data:/app/data - healthcheck: - test: ["CMD", "curl", "-f", "http://127.0.0.1:8080"] - interval: 2s - timeout: 10s - retries: 15 From 7bb9a2b56f1c1ad91eb2c43c897562d1eddb32d4 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:23:25 +0200 Subject: [PATCH 36/47] remove homebox - not maintained anymore --- public/svgs/homebox.svg | 11 ----------- templates/compose/homebox.yaml | 21 --------------------- 2 files changed, 32 deletions(-) delete mode 100644 public/svgs/homebox.svg delete mode 100644 templates/compose/homebox.yaml diff --git a/public/svgs/homebox.svg b/public/svgs/homebox.svg deleted file mode 100644 index 08670bbb9..000000000 --- a/public/svgs/homebox.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/templates/compose/homebox.yaml b/templates/compose/homebox.yaml deleted file mode 100644 index f7c09ed31..000000000 --- a/templates/compose/homebox.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# documentation: https://github.com/hay-kot/homebox -# slogan: Homebox is a self-hosted file management solution. -# tags: homebox,file-management,self-hosted -# logo: svgs/homebox.svg -# port: 7745 - -services: - homebox: - image: ghcr.io/hay-kot/homebox:latest - environment: - - SERVICE_FQDN_HOMEBOX_7745 - - HBOX_LOG_LEVEL=${HBOX_LOG_LEVEL:-info} - - HBOX_LOG_FORMAT=${HBOX_LOG_FORMAT:-text} - - HBOX_WEB_MAX_UPLOAD_SIZE=${HBOX_WEB_MAX_UPLOAD_SIZE:-10} - volumes: - - homebox-data:/data/ - healthcheck: - test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:7745"] - interval: 5s - timeout: 20s - retries: 10 From 5fbaebe4616071afe57767fa42a96583058c64de Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:24:46 +0200 Subject: [PATCH 37/47] remove docker.io as it is not needed --- templates/compose/authentik.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/compose/authentik.yaml b/templates/compose/authentik.yaml index 85281e175..87128f6c4 100644 --- a/templates/compose/authentik.yaml +++ b/templates/compose/authentik.yaml @@ -72,7 +72,7 @@ services: redis: condition: service_healthy postgresql: - image: docker.io/library/postgres:16-alpine + image: postgres:16-alpine restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] @@ -86,7 +86,7 @@ services: - POSTGRES_USER=${SERVICE_USER_POSTGRESQL} - POSTGRES_DB=authentik redis: - image: docker.io/library/redis:alpine + image: redis:alpine command: --save 60 1 --loglevel warning restart: unless-stopped healthcheck: From bb6e374222b00fa02f46053b31b7badf53c83269 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:25:05 +0200 Subject: [PATCH 38/47] use mariadb:11 as the other one does not exist --- templates/compose/firefly.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/firefly.yaml b/templates/compose/firefly.yaml index 4dd8dda96..1b1c6bf65 100644 --- a/templates/compose/firefly.yaml +++ b/templates/compose/firefly.yaml @@ -29,7 +29,7 @@ services: mysql: condition: service_healthy mysql: - image: mariadb:lts + image: mariadb:11 environment: - MYSQL_USER=${SERVICE_USER_MYSQL} - MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL} From c3ee58026066919c321eb7f396617552675b8dff Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:25:24 +0200 Subject: [PATCH 39/47] remove docker.io not needed --- templates/compose/paperless.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/paperless.yaml b/templates/compose/paperless.yaml index af74b5ea1..76c7c5b55 100644 --- a/templates/compose/paperless.yaml +++ b/templates/compose/paperless.yaml @@ -5,7 +5,7 @@ services: redis: - image: docker.io/library/redis:7.4 + image: redis:7.4 volumes: - paperless-redis:/data healthcheck: From 176db977d10eed6ec88c2ea4975f812bca4ccd6e Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:25:28 +0200 Subject: [PATCH 40/47] Delete weird.yaml --- templates/compose/weird.yaml | 77 ------------------------------------ 1 file changed, 77 deletions(-) delete mode 100644 templates/compose/weird.yaml diff --git a/templates/compose/weird.yaml b/templates/compose/weird.yaml deleted file mode 100644 index 85a3afe19..000000000 --- a/templates/compose/weird.yaml +++ /dev/null @@ -1,77 +0,0 @@ -# ignore: true -services: - ghost: - image: ghost:5 - volumes: - - ~/configs:/etc/configs/:ro - - ./var/lib/ghost/content:/tmp/ghost2/content:ro - - /var/lib/ghost/content:/tmp/ghost/content:rw - - ghost-content-data:/var/lib/ghost/content - - type: volume - source: mydata - target: /data - volume: - nocopy: true - - type: bind - source: ./var/lib/ghost/data - target: /data - - type: bind - source: /tmp - target: /tmp - labels: - - "test.label=true" - ports: - - "3000" - - "3000-3005" - - "8000:8000" - - "9090-9091:8080-8081" - - "49100:22" - - "127.0.0.1:8001:8001" - - "127.0.0.1:5000-5010:5000-5010" - - "127.0.0.1::5000" - - "6060:6060/udp" - - "12400-12500:1240" - - target: 80 - published: 8080 - protocol: tcp - mode: host - networks: - - some-network - - other-network - environment: - - database__client=${DATABASE_CLIENT:-mysql} - - database__connection__database=${MYSQL_DATABASE:-ghost} - - database__connection__host=${DATABASE_CONNECTION_HOST:-mysql} - - test=${TEST:?true} - - url=$SERVICE_FQDN_GHOST - - database__connection__user=$SERVICE_USER_MYSQL - - database__connection__password=$SERVICE_PASSWORD_MYSQL - depends_on: - - mysql - mysql: - image: mysql:8.0 - volumes: - - ghost-mysql-data:/var/lib/mysql - environment: - - MYSQL_USER=${SERVICE_USER_MYSQL} - - MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL} - - MYSQL_DATABASE=$MYSQL_DATABASE - - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT} - - SESSION_SECRET - minio: - image: minio/minio - environment: - RACK_ENV: development - A: $A - SHOW: ${SHOW} - SHOW1: ${SHOW2-show1} - SHOW2: ${SHOW3:-show2} - SHOW3: ${SHOW4?show3} - SHOW4: ${SHOW5:?show4} - SHOW5: ${SERVICE_USER_MINIO} - SHOW6: ${SERVICE_PASSWORD_MINIO} - SHOW7: ${SERVICE_PASSWORD_64_MINIO} - SHOW8: ${SERVICE_BASE64_64_MINIO} - SHOW9: ${SERVICE_BASE64_128_MINIO} - SHOW10: ${SERVICE_BASE64_MINIO} - SHOW11: From a1bd218d163d80b65815fb6de2f423b7c99f3843 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:55:19 +0200 Subject: [PATCH 41/47] Update service-templates.json --- templates/service-templates.json | 51 +++----------------------------- 1 file changed, 4 insertions(+), 47 deletions(-) diff --git a/templates/service-templates.json b/templates/service-templates.json index d9b5e154b..ab7677bca 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -115,7 +115,7 @@ "authentik": { "documentation": "https://docs.goauthentik.io/docs/installation/docker-compose?utm_source=coolify.io", "slogan": "An open-source Identity Provider, focused on flexibility and versatility.", - "compose": "c2VydmljZXM6CiAgYXV0aGVudGlrLXNlcnZlcjoKICAgIGltYWdlOiAnZ2hjci5pby9nb2F1dGhlbnRpay9zZXJ2ZXI6JHtBVVRIRU5USUtfVEFHOi0yMDI0LjguMH0nCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgY29tbWFuZDogc2VydmVyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQVVUSEVOVElLU0VSVkVSXzkwMDAKICAgICAgLSAnQVVUSEVOVElLX1JFRElTX19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXBvc3RncmVzcWx9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX05BTUU9JHtQT1NUR1JFU19EQjotYXV0aGVudGlrfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1NFQ1JFVF9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0FVVEhFTlRJS1NFUlZFUn0nCiAgICAgIC0gJ0FVVEhFTlRJS19FUlJPUl9SRVBPUlRJTkdfX0VOQUJMRUQ9JHtBVVRIRU5USUtfRVJST1JfUkVQT1JUSU5HX19FTkFCTEVEOi10cnVlfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19IT1NUPSR7QVVUSEVOVElLX0VNQUlMX19IT1NUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19QT1JUPSR7QVVUSEVOVElLX0VNQUlMX19QT1JUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19VU0VSTkFNRT0ke0FVVEhFTlRJS19FTUFJTF9fVVNFUk5BTUV9JwogICAgICAtICdBVVRIRU5USUtfRU1BSUxfX1BBU1NXT1JEPSR7QVVUSEVOVElLX0VNQUlMX19QQVNTV09SRH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMUz0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMU30nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTD0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVD0ke0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fRlJPTT0ke0FVVEhFTlRJS19FTUFJTF9fRlJPTX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL21lZGlhOi9tZWRpYScKICAgICAgLSAnLi9jdXN0b20tdGVtcGxhdGVzOi90ZW1wbGF0ZXMnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgYXV0aGVudGlrLXdvcmtlcjoKICAgIGltYWdlOiAnZ2hjci5pby9nb2F1dGhlbnRpay9zZXJ2ZXI6JHtBVVRIRU5USUtfVEFHOi0yMDI0LjguMH0nCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgY29tbWFuZDogd29ya2VyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnQVVUSEVOVElLX1JFRElTX19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXBvc3RncmVzcWx9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX05BTUU9JHtQT1NUR1JFU19EQjotYXV0aGVudGlrfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1NFQ1JFVF9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0FVVEhFTlRJS1NFUlZFUn0nCiAgICAgIC0gJ0FVVEhFTlRJS19FUlJPUl9SRVBPUlRJTkdfX0VOQUJMRUQ9JHtBVVRIRU5USUtfRVJST1JfUkVQT1JUSU5HX19FTkFCTEVEfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19IT1NUPSR7QVVUSEVOVElLX0VNQUlMX19IT1NUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19QT1JUPSR7QVVUSEVOVElLX0VNQUlMX19QT1JUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19VU0VSTkFNRT0ke0FVVEhFTlRJS19FTUFJTF9fVVNFUk5BTUV9JwogICAgICAtICdBVVRIRU5USUtfRU1BSUxfX1BBU1NXT1JEPSR7QVVUSEVOVElLX0VNQUlMX19QQVNTV09SRH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMUz0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMU30nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTD0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVD0ke0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fRlJPTT0ke0FVVEhFTlRJS19FTUFJTF9fRlJPTX0nCiAgICB1c2VyOiByb290CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnLi9tZWRpYTovbWVkaWEnCiAgICAgIC0gJy4vY2VydHM6L2NlcnRzJwogICAgICAtICcuL2N1c3RvbS10ZW1wbGF0ZXM6L3RlbXBsYXRlcycKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdkb2NrZXIuaW8vbGlicmFyeS9wb3N0Z3JlczoxNi1hbHBpbmUnCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1kICQke1BPU1RHUkVTX0RCfSAtVSAkJHtQT1NUR1JFU19VU0VSfScKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgdm9sdW1lczoKICAgICAgLSAnYXV0aGVudGlrLWRiOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTH0nCiAgICAgIC0gUE9TVEdSRVNfREI9YXV0aGVudGlrCiAgcmVkaXM6CiAgICBpbWFnZTogJ2RvY2tlci5pby9saWJyYXJ5L3JlZGlzOmFscGluZScKICAgIGNvbW1hbmQ6ICctLXNhdmUgNjAgMSAtLWxvZ2xldmVsIHdhcm5pbmcnCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdyZWRpcy1jbGkgcGluZyB8IGdyZXAgUE9ORycKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXM6L2RhdGEnCg==", + "compose": "c2VydmljZXM6CiAgYXV0aGVudGlrLXNlcnZlcjoKICAgIGltYWdlOiAnZ2hjci5pby9nb2F1dGhlbnRpay9zZXJ2ZXI6JHtBVVRIRU5USUtfVEFHOi0yMDI0LjguMH0nCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgY29tbWFuZDogc2VydmVyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQVVUSEVOVElLU0VSVkVSXzkwMDAKICAgICAgLSAnQVVUSEVOVElLX1JFRElTX19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXBvc3RncmVzcWx9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX05BTUU9JHtQT1NUR1JFU19EQjotYXV0aGVudGlrfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1NFQ1JFVF9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0FVVEhFTlRJS1NFUlZFUn0nCiAgICAgIC0gJ0FVVEhFTlRJS19FUlJPUl9SRVBPUlRJTkdfX0VOQUJMRUQ9JHtBVVRIRU5USUtfRVJST1JfUkVQT1JUSU5HX19FTkFCTEVEOi10cnVlfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19IT1NUPSR7QVVUSEVOVElLX0VNQUlMX19IT1NUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19QT1JUPSR7QVVUSEVOVElLX0VNQUlMX19QT1JUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19VU0VSTkFNRT0ke0FVVEhFTlRJS19FTUFJTF9fVVNFUk5BTUV9JwogICAgICAtICdBVVRIRU5USUtfRU1BSUxfX1BBU1NXT1JEPSR7QVVUSEVOVElLX0VNQUlMX19QQVNTV09SRH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMUz0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMU30nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTD0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVD0ke0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fRlJPTT0ke0FVVEhFTlRJS19FTUFJTF9fRlJPTX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL21lZGlhOi9tZWRpYScKICAgICAgLSAnLi9jdXN0b20tdGVtcGxhdGVzOi90ZW1wbGF0ZXMnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgYXV0aGVudGlrLXdvcmtlcjoKICAgIGltYWdlOiAnZ2hjci5pby9nb2F1dGhlbnRpay9zZXJ2ZXI6JHtBVVRIRU5USUtfVEFHOi0yMDI0LjguMH0nCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgY29tbWFuZDogd29ya2VyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnQVVUSEVOVElLX1JFRElTX19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXBvc3RncmVzcWx9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX05BTUU9JHtQT1NUR1JFU19EQjotYXV0aGVudGlrfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1NFQ1JFVF9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0FVVEhFTlRJS1NFUlZFUn0nCiAgICAgIC0gJ0FVVEhFTlRJS19FUlJPUl9SRVBPUlRJTkdfX0VOQUJMRUQ9JHtBVVRIRU5USUtfRVJST1JfUkVQT1JUSU5HX19FTkFCTEVEfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19IT1NUPSR7QVVUSEVOVElLX0VNQUlMX19IT1NUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19QT1JUPSR7QVVUSEVOVElLX0VNQUlMX19QT1JUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19VU0VSTkFNRT0ke0FVVEhFTlRJS19FTUFJTF9fVVNFUk5BTUV9JwogICAgICAtICdBVVRIRU5USUtfRU1BSUxfX1BBU1NXT1JEPSR7QVVUSEVOVElLX0VNQUlMX19QQVNTV09SRH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMUz0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMU30nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTD0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVD0ke0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fRlJPTT0ke0FVVEhFTlRJS19FTUFJTF9fRlJPTX0nCiAgICB1c2VyOiByb290CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnLi9tZWRpYTovbWVkaWEnCiAgICAgIC0gJy4vY2VydHM6L2NlcnRzJwogICAgICAtICcuL2N1c3RvbS10ZW1wbGF0ZXM6L3RlbXBsYXRlcycKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1kICQke1BPU1RHUkVTX0RCfSAtVSAkJHtQT1NUR1JFU19VU0VSfScKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgdm9sdW1lczoKICAgICAgLSAnYXV0aGVudGlrLWRiOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTH0nCiAgICAgIC0gUE9TVEdSRVNfREI9YXV0aGVudGlrCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOmFscGluZScKICAgIGNvbW1hbmQ6ICctLXNhdmUgNjAgMSAtLWxvZ2xldmVsIHdhcm5pbmcnCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdyZWRpcy1jbGkgcGluZyB8IGdyZXAgUE9ORycKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXM6L2RhdGEnCg==", "tags": [ "identity", "login", @@ -408,20 +408,6 @@ "minversion": "0.0.0", "port": "8000" }, - "dashboard": { - "documentation": "https://github.com/phntxx/dashboard?tab=readme-ov-file#dashboard?utm_source=coolify.io", - "slogan": "A dashboard, inspired by SUI.", - "compose": "c2VydmljZXM6CiAgZGFzaGJvYXJkOgogICAgaW1hZ2U6ICdwaG50eHgvZGFzaGJvYXJkOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9EQVNIQk9BUkRfODA4MAogICAgdm9sdW1lczoKICAgICAgLSAnZGFzaGJvYXJkLWRhdGE6L2FwcC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwODAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUK", - "tags": [ - "dashboard", - "web", - "search", - "bookmarks" - ], - "logo": "svgs/coolify.png", - "minversion": "0.0.0", - "port": "8080" - }, "directus-with-postgresql": { "documentation": "https://directus.io?utm_source=coolify.io", "slogan": "Directus wraps databases with a dynamic API, and provides an intuitive app for managing its content.", @@ -643,7 +629,7 @@ "firefly": { "documentation": "https://firefly-iii.org?utm_source=coolify.io", "slogan": "A personal finances manager that can help you save money.", - "compose": "c2VydmljZXM6CiAgZmlyZWZseToKICAgIGltYWdlOiAnZmlyZWZseWlpaS9jb3JlOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9GSVJFRkxZXzgwODAKICAgICAgLSBBUFBfS0VZPSRTRVJWSUNFX0JBU0U2NF9BUFBLRVkKICAgICAgLSBEQl9IT1NUPW15c3FsCiAgICAgIC0gREJfUE9SVD0zMzA2CiAgICAgIC0gREJfQ09OTkVDVElPTj1teXNxbAogICAgICAtICdEQl9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi1maXJlZmx5fScKICAgICAgLSBEQl9VU0VSTkFNRT0kU0VSVklDRV9VU0VSX01ZU1FMCiAgICAgIC0gREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTVlTUUwKICAgICAgLSBTVEFUSUNfQ1JPTl9UT0tFTj0kU0VSVklDRV9CQVNFNjRfQ1JPTlRPS0VOCiAgICAgIC0gJ1RSVVNURURfUFJPWElFUz0qJwogICAgdm9sdW1lczoKICAgICAgLSAnZmlyZWZseS11cGxvYWQ6L3Zhci93d3cvaHRtbC9zdG9yYWdlL3VwbG9hZCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MDgwJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBteXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIG15c3FsOgogICAgaW1hZ2U6ICdtYXJpYWRiOmx0cycKICAgIGVudmlyb25tZW50OgogICAgICAtICdNWVNRTF9VU0VSPSR7U0VSVklDRV9VU0VSX01ZU1FMfScKICAgICAgLSAnTVlTUUxfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMfScKICAgICAgLSAnTVlTUUxfREFUQUJBU0U9JHtNWVNRTF9EQVRBQkFTRTotZmlyZWZseX0nCiAgICAgIC0gJ01ZU1FMX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMUk9PVH0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbWFyaWFkYi1hZG1pbgogICAgICAgIC0gcGluZwogICAgICAgIC0gJy1oJwogICAgICAgIC0gMTI3LjAuMC4xCiAgICAgICAgLSAnLXVyb290JwogICAgICAgIC0gJy1wJHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMUk9PVH0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ZpcmVmbHktbXlzcWwtZGF0YTovdmFyL2xpYi9teXNxbCcKICBjcm9uOgogICAgaW1hZ2U6IGFscGluZQogICAgZW50cnlwb2ludDoKICAgICAgLSAvZW50cnlwb2ludC5zaAogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vZW50cnlwb2ludC5zaAogICAgICAgIHRhcmdldDogL2VudHJ5cG9pbnQuc2gKICAgICAgICBjb250ZW50OiAiIyEvYmluL3NoXG4jIFN1YnN0aXR1dGUgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIGludG8gdGhlIGNyb24gY29tbWFuZFxuQ1JPTl9DT01NQU5EPVwiMCAzICogKiAqIHdnZXQgLXFPLSBodHRwOi8vZmlyZWZseTo4MDgwL2FwaS92MS9jcm9uLyR7U1RBVElDX0NST05fVE9LRU59XCJcbiMgQWRkIHRoZSBjcm9uIGNvbW1hbmQgdG8gdGhlIGNyb250YWJcbmVjaG8gXCIkQ1JPTl9DT01NQU5EXCIgfCBjcm9udGFiIC1cbiMgU3RhcnQgdGhlIGNyb24gZGFlbW9uIGluIHRoZSBmb3JlZ3JvdW5kIHdpdGggbG9nZ2luZyB0byBzdGRvdXRcbmNyb25kIC1mIC1MIC9kZXYvc3Rkb3V0IgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU1RBVElDX0NST05fVE9LRU49JFNFUlZJQ0VfQkFTRTY0X0NST05UT0tFTgo=", + "compose": "c2VydmljZXM6CiAgZmlyZWZseToKICAgIGltYWdlOiAnZmlyZWZseWlpaS9jb3JlOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9GSVJFRkxZXzgwODAKICAgICAgLSBBUFBfS0VZPSRTRVJWSUNFX0JBU0U2NF9BUFBLRVkKICAgICAgLSBEQl9IT1NUPW15c3FsCiAgICAgIC0gREJfUE9SVD0zMzA2CiAgICAgIC0gREJfQ09OTkVDVElPTj1teXNxbAogICAgICAtICdEQl9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi1maXJlZmx5fScKICAgICAgLSBEQl9VU0VSTkFNRT0kU0VSVklDRV9VU0VSX01ZU1FMCiAgICAgIC0gREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTVlTUUwKICAgICAgLSBTVEFUSUNfQ1JPTl9UT0tFTj0kU0VSVklDRV9CQVNFNjRfQ1JPTlRPS0VOCiAgICAgIC0gJ1RSVVNURURfUFJPWElFUz0qJwogICAgdm9sdW1lczoKICAgICAgLSAnZmlyZWZseS11cGxvYWQ6L3Zhci93d3cvaHRtbC9zdG9yYWdlL3VwbG9hZCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MDgwJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBteXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIG15c3FsOgogICAgaW1hZ2U6ICdtYXJpYWRiOjExJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01ZU1FMX1VTRVI9JHtTRVJWSUNFX1VTRVJfTVlTUUx9JwogICAgICAtICdNWVNRTF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTVlTUUx9JwogICAgICAtICdNWVNRTF9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi1maXJlZmx5fScKICAgICAgLSAnTVlTUUxfUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTVlTUUxST09UfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBtYXJpYWRiLWFkbWluCiAgICAgICAgLSBwaW5nCiAgICAgICAgLSAnLWgnCiAgICAgICAgLSAxMjcuMC4wLjEKICAgICAgICAtICctdXJvb3QnCiAgICAgICAgLSAnLXAke1NFUlZJQ0VfUEFTU1dPUkRfTVlTUUxST09UfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogICAgdm9sdW1lczoKICAgICAgLSAnZmlyZWZseS1teXNxbC1kYXRhOi92YXIvbGliL215c3FsJwogIGNyb246CiAgICBpbWFnZTogYWxwaW5lCiAgICBlbnRyeXBvaW50OgogICAgICAtIC9lbnRyeXBvaW50LnNoCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9lbnRyeXBvaW50LnNoCiAgICAgICAgdGFyZ2V0OiAvZW50cnlwb2ludC5zaAogICAgICAgIGNvbnRlbnQ6ICIjIS9iaW4vc2hcbiMgU3Vic3RpdHV0ZSB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUgaW50byB0aGUgY3JvbiBjb21tYW5kXG5DUk9OX0NPTU1BTkQ9XCIwIDMgKiAqICogd2dldCAtcU8tIGh0dHA6Ly9maXJlZmx5OjgwODAvYXBpL3YxL2Nyb24vJHtTVEFUSUNfQ1JPTl9UT0tFTn1cIlxuIyBBZGQgdGhlIGNyb24gY29tbWFuZCB0byB0aGUgY3JvbnRhYlxuZWNobyBcIiRDUk9OX0NPTU1BTkRcIiB8IGNyb250YWIgLVxuIyBTdGFydCB0aGUgY3JvbiBkYWVtb24gaW4gdGhlIGZvcmVncm91bmQgd2l0aCBsb2dnaW5nIHRvIHN0ZG91dFxuY3JvbmQgLWYgLUwgL2Rldi9zdGRvdXQiCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTVEFUSUNfQ1JPTl9UT0tFTj0kU0VSVklDRV9CQVNFNjRfQ1JPTlRPS0VOCg==", "tags": [ "finance", "money", @@ -1091,19 +1077,6 @@ "minversion": "0.0.0", "port": "7575" }, - "homebox": { - "documentation": "https://github.com/hay-kot/homebox?utm_source=coolify.io", - "slogan": "Homebox is a self-hosted file management solution.", - "compose": "c2VydmljZXM6CiAgaG9tZWJveDoKICAgIGltYWdlOiAnZ2hjci5pby9oYXkta290L2hvbWVib3g6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0hPTUVCT1hfNzc0NQogICAgICAtICdIQk9YX0xPR19MRVZFTD0ke0hCT1hfTE9HX0xFVkVMOi1pbmZvfScKICAgICAgLSAnSEJPWF9MT0dfRk9STUFUPSR7SEJPWF9MT0dfRk9STUFUOi10ZXh0fScKICAgICAgLSAnSEJPWF9XRUJfTUFYX1VQTE9BRF9TSVpFPSR7SEJPWF9XRUJfTUFYX1VQTE9BRF9TSVpFOi0xMH0nCiAgICB2b2x1bWVzOgogICAgICAtICdob21lYm94LWRhdGE6L2RhdGEvJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctcScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjc3NDUnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", - "tags": [ - "homebox", - "file-management", - "self-hosted" - ], - "logo": "svgs/homebox.svg", - "minversion": "0.0.0", - "port": "7745" - }, "homepage": { "documentation": "https://gethomepage.dev/latest/?utm_source=coolify.io", "slogan": "A modern, fully static, fast, secure fully proxied, highly customizable application dashboard", @@ -1211,22 +1184,6 @@ "minversion": "0.0.0", "port": "22300" }, - "jupyterlab": { - "documentation": "https://jupyterlab.readthedocs.io/en/latest/?utm_source=coolify.io", - "slogan": "JupyterLab Notebook with C++ (xeus-cling) and Javascript (Deno) Kernel", - "compose": "c2VydmljZXM6CiAganVweXRlcmxhYjoKICAgIGltYWdlOiB5b2tvd2FzaXMvanVweXRlcmxhYgogICAgcGxhdGZvcm06IGxpbnV4L2FtZDY0CiAgICBleHBvc2U6CiAgICAgIC0gODAwOAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0pVUFlURVJMQUJfODAwOAogICAgICAtICdQT1JUPSR7UE9SVDotODAwOH0nCiAgICAgIC0gJ1RPS0VOPSR7U0VSVklDRV9QQVNTV09SRF9UT0tFTn0nCiAgICAgIC0gJ0NPTkRBX1BBQ0tBR0VTPSR7Q09OREFfUEFDS0FHRVM6LXBhbmRhcyBudW1weSBtYXRwbG90bGliIHNlYWJvcm4gc2Npa2l0LWxlYXJuIHB5dG9yY2ggbmx0ayBvcGVucHl4bCBjYXRlZ29yeV9lbmNvZGVycyBzY2lraXQtbGVhcm4gdGVuc29yZmxvdyBzcGFjeX0nCiAgICAgIC0gJ1BJUF9QQUNLQUdFUz0ke1BJUF9QQUNLQUdFUzotc2FzdHJhd2l9JwogICAgdm9sdW1lczoKICAgICAgLSAnanVweXRlcmxhYi1kYXRhOi9ob21lL21hbWJhdXNlci9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwMDgvbG9naW4vJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogNQo=", - "tags": [ - "jupyter", - "notebook", - "python", - "cpp", - "deno", - "jupyterlab" - ], - "logo": "svgs/jupyterlab.svg", - "minversion": "0.0.0", - "port": "8008" - }, "keycloak-with-postgres": { "documentation": "https://www.keycloak.org?utm_source=coolify.io", "slogan": "Keycloak is an open-source Identity and Access Management tool.", @@ -1651,7 +1608,7 @@ "mosquitto": { "documentation": "https://mosquitto.org/documentation/?utm_source=coolify.io", "slogan": "Mosquitto is lightweight and suitable for use on all devices, from low-power single-board computers to full servers.", - "compose": "c2VydmljZXM6CiAgbW9zcXVpdHRvOgogICAgaW1hZ2U6IGVjbGlwc2UtbW9zcXVpdHRvCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTU9TUVVJVFRPXzE4ODMKICAgICAgLSAnTVFUVF9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9NT1NRVUlUVE99JwogICAgICAtICdNUVRUX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE99JwogICAgICAtICdSRVFVSVJFX0NFUlRJRklDQVRFPSR7UkVRVUlSRV9DRVJUSUZJQ0FURTotZmFsc2V9JwogICAgICAtICdBTExPV19BTk9OWU1PVVM9JHtBTExPV19BTk9OWU1PVVM6LXRydWV9JwogICAgdm9sdW1lczoKICAgICAgLSAnbW9zcXVpdHRvLWNvbmZpZzovbW9zcXVpdHRvL2NvbmZpZycKICAgICAgLSAnbW9zcXVpdHRvLWNlcnRzOi9jZXJ0cycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICBlbnRyeXBvaW50OiAic2ggLWMgXCIgaWYgWyAnJFJFUVVJUkVfQ0VSVElGSUNBVEUnID0gJ3RydWUnIF07IHRoZW4gZWNobyAnbGlzdGVuZXIgODg4MycgPiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdjYWZpbGUgL2NlcnRzL2NhLmNydCcgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgZWNobyAnY2VydGZpbGUgL2NlcnRzL3NlcnZlci5jcnQnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIGVjaG8gJ2tleWZpbGUgIC9jZXJ0cy9zZXJ2ZXIua2V5JyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZjsgZWxzZSBlY2hvICdsaXN0ZW5lciAxODgzJyA+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mOyBmaSAmJiBlY2hvICdyZXF1aXJlX2NlcnRpZmljYXRlICckUkVRVUlSRV9DRVJUSUZJQ0FURSA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdhbGxvd19hbm9ueW1vdXMgJyRBTExPV19BTk9OWU1PVVMgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgaWYgWyAtbiAnJFNFUlZJQ0VfVVNFUl9NT1NRVUlUVE8nXSAmJiBbIC1uICckU0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE8nIF07IHRoZW4gZWNobyAncGFzc3dvcmRfZmlsZSAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIHRvdWNoIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAmJiBjaG1vZCAwNzAwIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAmJiBjaG93biByb290OnJvb3QgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICYmIG1vc3F1aXR0b19wYXNzd2QgLWIgLWMgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICRTRVJWSUNFX1VTRVJfTU9TUVVJVFRPICRTRVJWSUNFX1BBU1NXT1JEX01PU1FVSVRUTyAmJiBjaG93biBtb3NxdWl0dG86bW9zcXVpdHRvIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkczsgZmkgJiYgZXhlYyBtb3NxdWl0dG8gLWMgL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgXCIiCiAgICBsYWJlbHM6CiAgICAgIC0gdHJhZWZpay50Y3Aucm91dGVycy5tcXR0LmVudHJ5cG9pbnRzPW1xdHQKICAgICAgLSB0cmFlZmlrLnRjcC5yb3V0ZXJzLm1xdHRzLmVudHJ5cG9pbnRzPW1xdHRzCg==", + "compose": "c2VydmljZXM6CiAgbW9zcXVpdHRvOgogICAgaW1hZ2U6IGVjbGlwc2UtbW9zcXVpdHRvCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTU9TUVVJVFRPXzE4ODMKICAgICAgLSAnTVFUVF9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9NT1NRVUlUVE99JwogICAgICAtICdNUVRUX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE99JwogICAgICAtICdSRVFVSVJFX0NFUlRJRklDQVRFPSR7UkVRVUlSRV9DRVJUSUZJQ0FURTotZmFsc2V9JwogICAgICAtICdBTExPV19BTk9OWU1PVVM9JHtBTExPV19BTk9OWU1PVVM6LXRydWV9JwogICAgdm9sdW1lczoKICAgICAgLSAnbW9zcXVpdHRvLWNvbmZpZzovbW9zcXVpdHRvL2NvbmZpZycKICAgICAgLSAnbW9zcXVpdHRvLWNlcnRzOi9jZXJ0cycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICBlbnRyeXBvaW50OiAic2ggLWMgXCIgaWYgWyAnJFJFUVVJUkVfQ0VSVElGSUNBVEUnID0gJ3RydWUnIF07IHRoZW4gZWNobyAnbGlzdGVuZXIgODg4MycgPiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdjYWZpbGUgL2NlcnRzL2NhLmNydCcgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgZWNobyAnY2VydGZpbGUgL2NlcnRzL3NlcnZlci5jcnQnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIGVjaG8gJ2tleWZpbGUgIC9jZXJ0cy9zZXJ2ZXIua2V5JyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZjsgZWxzZSBlY2hvICdsaXN0ZW5lciAxODgzJyA+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mOyBmaSAmJiBlY2hvICdyZXF1aXJlX2NlcnRpZmljYXRlICckUkVRVUlSRV9DRVJUSUZJQ0FURSA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdhbGxvd19hbm9ueW1vdXMgJyRBTExPV19BTk9OWU1PVVMgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmY7IGlmIFsgLW4gJyRTRVJWSUNFX1VTRVJfTU9TUVVJVFRPJ10gJiYgWyAtbiAnJFNFUlZJQ0VfUEFTU1dPUkRfTU9TUVVJVFRPJyBdOyB0aGVuIGVjaG8gJ3Bhc3N3b3JkX2ZpbGUgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzJyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiB0b3VjaCAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMgJiYgY2htb2QgMDcwMCAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMgJiYgY2hvd24gcm9vdDpyb290IC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAmJiBtb3NxdWl0dG9fcGFzc3dkIC1iIC1jIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAkU0VSVklDRV9VU0VSX01PU1FVSVRUTyAkU0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE8gJiYgY2hvd24gbW9zcXVpdHRvOm1vc3F1aXR0byAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHM7IGZpICYmIGV4ZWMgbW9zcXVpdHRvIC1jIC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mIFwiIgogICAgbGFiZWxzOgogICAgICAtIHRyYWVmaWsudGNwLnJvdXRlcnMubXF0dC5lbnRyeXBvaW50cz1tcXR0CiAgICAgIC0gdHJhZWZpay50Y3Aucm91dGVycy5tcXR0cy5lbnRyeXBvaW50cz1tcXR0cwo=", "tags": [ "mosquitto", "mqtt", @@ -1965,7 +1922,7 @@ "paperless": { "documentation": "https://docs.paperless-ngx.com/configuration/?utm_source=coolify.io", "slogan": "Paperless-ngx is a community-supported open-source document management system that transforms your physical documents into a searchable online archive so you can keep, well, less paper.", - "compose": "c2VydmljZXM6CiAgcmVkaXM6CiAgICBpbWFnZTogJ2RvY2tlci5pby9saWJyYXJ5L3JlZGlzOjcuNCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3BhcGVybGVzcy1yZWRpczovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICBwYXBlcmxlc3M6CiAgICBpbWFnZTogJ3BhcGVybGVzc25neC9wYXBlcmxlc3Mtbmd4OmxhdGVzdCcKICAgIGRlcGVuZHNfb246CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mcycKICAgICAgICAtICctUycKICAgICAgICAtICctLW1heC10aW1lJwogICAgICAgIC0gJzInCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo4MDAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiA1CiAgICB2b2x1bWVzOgogICAgICAtICdwYXBlcmxlc3MtZGF0YTovdXNyL3NyYy9wYXBlcmxlc3MvZGF0YScKICAgICAgLSAncGFwZXJsZXNzLW1lZGlhOi91c3Ivc3JjL3BhcGVybGVzcy9tZWRpYScKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vZXhwb3J0CiAgICAgICAgdGFyZ2V0OiAvdXNyL3NyYy9wYXBlcmxlc3MvZXhwb3J0CiAgICAgICAgaXNfZGlyZWN0b3J5OiB0cnVlCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2NvbnN1bWUKICAgICAgICB0YXJnZXQ6IC91c3Ivc3JjL3BhcGVybGVzcy9jb25zdW1lCiAgICAgICAgaXNfZGlyZWN0b3J5OiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUEFQRVJMRVNTXzgwMDAKICAgICAgLSBQQVBFUkxFU1NfVVJMPSRTRVJWSUNFX0ZRRE5fUEFQRVJMRVNTXzgwMDAKICAgICAgLSAnUEFQRVJMRVNTX0FETUlOX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QQVBFUkxFU1N9JwogICAgICAtICdQQVBFUkxFU1NfQURNSU5fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QQVBFUkxFU1N9JwogICAgICAtICdQQVBFUkxFU1NfUkVESVM9cmVkaXM6Ly9yZWRpczo2Mzc5JwogICAgICAtICdQQVBFUkxFU1NfU0VDUkVUX0tFWT0ke1NFUlZJQ0VfUkVBTEJBU0U2NF82NF9QQVBFUkxFU1N9Jwo=", + "compose": "c2VydmljZXM6CiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjcuNCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3BhcGVybGVzcy1yZWRpczovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICBwYXBlcmxlc3M6CiAgICBpbWFnZTogJ3BhcGVybGVzc25neC9wYXBlcmxlc3Mtbmd4OmxhdGVzdCcKICAgIGRlcGVuZHNfb246CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mcycKICAgICAgICAtICctUycKICAgICAgICAtICctLW1heC10aW1lJwogICAgICAgIC0gJzInCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo4MDAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiA1CiAgICB2b2x1bWVzOgogICAgICAtICdwYXBlcmxlc3MtZGF0YTovdXNyL3NyYy9wYXBlcmxlc3MvZGF0YScKICAgICAgLSAncGFwZXJsZXNzLW1lZGlhOi91c3Ivc3JjL3BhcGVybGVzcy9tZWRpYScKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vZXhwb3J0CiAgICAgICAgdGFyZ2V0OiAvdXNyL3NyYy9wYXBlcmxlc3MvZXhwb3J0CiAgICAgICAgaXNfZGlyZWN0b3J5OiB0cnVlCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2NvbnN1bWUKICAgICAgICB0YXJnZXQ6IC91c3Ivc3JjL3BhcGVybGVzcy9jb25zdW1lCiAgICAgICAgaXNfZGlyZWN0b3J5OiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUEFQRVJMRVNTXzgwMDAKICAgICAgLSBQQVBFUkxFU1NfVVJMPSRTRVJWSUNFX0ZRRE5fUEFQRVJMRVNTXzgwMDAKICAgICAgLSAnUEFQRVJMRVNTX0FETUlOX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QQVBFUkxFU1N9JwogICAgICAtICdQQVBFUkxFU1NfQURNSU5fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QQVBFUkxFU1N9JwogICAgICAtICdQQVBFUkxFU1NfUkVESVM9cmVkaXM6Ly9yZWRpczo2Mzc5JwogICAgICAtICdQQVBFUkxFU1NfU0VDUkVUX0tFWT0ke1NFUlZJQ0VfUkVBTEJBU0U2NF82NF9QQVBFUkxFU1N9Jwo=", "tags": null, "logo": "svgs/paperless.svg", "minversion": "0.0.0", From 62c0eba139101949cb434ddff31445b76a2dc82d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 17:13:07 +0200 Subject: [PATCH 42/47] Refactor code to remove experimental features and update documentation links --- .../views/livewire/project/application/general.blade.php | 6 +++--- resources/views/livewire/server/form.blade.php | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index b30078237..34c71d3a1 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -5,7 +5,7 @@ Save - {{-- + {{-- Download Config @@ -238,9 +238,9 @@ class="underline" href="https://coolify.io/docs/knowledge-base/docker/registry" @if ($application->build_pack !== 'dockercompose')
+ label="Use a Build Server?" />
@endif @if ($application->could_set_build_commands()) diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 35ec6c71b..385620ecb 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -179,6 +179,8 @@ class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-co @endif
+
Experimental feature
@if ($server->isSentinelEnabled()) From dd3aeb10235849e14d5b2cb95c33e3870b40c1fe Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 17:29:56 +0200 Subject: [PATCH 43/47] stop logdrain before restarting it --- app/Actions/Server/InstallLogDrain.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Actions/Server/InstallLogDrain.php b/app/Actions/Server/InstallLogDrain.php index 9b6741211..43376efe5 100644 --- a/app/Actions/Server/InstallLogDrain.php +++ b/app/Actions/Server/InstallLogDrain.php @@ -209,6 +209,8 @@ public function handle(Server $server) ]; $command = array_merge($command, $add_envs_command, $restart_command); + StopLogDrain::run($server); + return instant_remote_process($command, $server); } catch (\Throwable $e) { return handleError($e); From 50519a86a9f57d2ebf3b70323c480d23a4583ec9 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 17:38:14 +0200 Subject: [PATCH 44/47] fix: numberOfLines could be null --- app/Livewire/Project/Shared/GetLogs.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Livewire/Project/Shared/GetLogs.php b/app/Livewire/Project/Shared/GetLogs.php index 0e140b8c1..f3d9da07d 100644 --- a/app/Livewire/Project/Shared/GetLogs.php +++ b/app/Livewire/Project/Shared/GetLogs.php @@ -39,7 +39,7 @@ class GetLogs extends Component public ?bool $showTimeStamps = true; - public int $numberOfLines = 100; + public ?int $numberOfLines = 100; public function mount() { @@ -98,7 +98,7 @@ public function getLogs($refresh = false) if (! $refresh && ($this->resource?->getMorphClass() === 'App\Models\Service' || str($this->container)->contains('-pr-'))) { return; } - if ($this->numberOfLines <= 0) { + if ($this->numberOfLines <= 0 || is_null($this->numberOfLines)) { $this->numberOfLines = 1000; } if ($this->container) { From 29ad9656563fb49acab296f190fe50e97f619bf7 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 17:46:39 +0200 Subject: [PATCH 45/47] Refactor code to use loggy() function for server storage check logging --- app/Jobs/ServerStorageCheckJob.php | 3 +-- bootstrap/helpers/shared.php | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Jobs/ServerStorageCheckJob.php b/app/Jobs/ServerStorageCheckJob.php index 7c3916954..c646f77eb 100644 --- a/app/Jobs/ServerStorageCheckJob.php +++ b/app/Jobs/ServerStorageCheckJob.php @@ -10,7 +10,6 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\RateLimiter; class ServerStorageCheckJob implements ShouldBeEncrypted, ShouldQueue @@ -39,7 +38,7 @@ public function handle() if (is_null($this->percentage)) { $this->percentage = $this->server->storageCheck(); - Log::info('Server storage check percentage: '.$this->percentage); + loggy('Server storage check percentage: '.$this->percentage); } if (! $this->percentage) { return 'No percentage could be retrieved.'; diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index dbab6861d..1374070e4 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -30,6 +30,7 @@ use App\Notifications\Internal\GeneralNotification; use DanHarrin\LivewireRateLimiting\Exceptions\TooManyRequestsException; use Illuminate\Database\UniqueConstraintViolationException; +use Illuminate\Log\LogManager; use Illuminate\Mail\Message; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Process\Pool; @@ -4013,7 +4014,7 @@ function loadConfigFromGit(string $repository, string $branch, string $base_dire } } -function loggy($message = null, array $context = []) +function loggy($message = null, array $context = []): LogManager { if (! isDev()) { return; From 394dfe9e645b5f9bb9c38ad8b5ebb15228431d25 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 25 Oct 2024 17:49:16 +0200 Subject: [PATCH 46/47] Refactor code to remove unused import and update loggy() function signature --- bootstrap/helpers/shared.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 1374070e4..dbab6861d 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -30,7 +30,6 @@ use App\Notifications\Internal\GeneralNotification; use DanHarrin\LivewireRateLimiting\Exceptions\TooManyRequestsException; use Illuminate\Database\UniqueConstraintViolationException; -use Illuminate\Log\LogManager; use Illuminate\Mail\Message; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Process\Pool; @@ -4014,7 +4013,7 @@ function loadConfigFromGit(string $repository, string $branch, string $base_dire } } -function loggy($message = null, array $context = []): LogManager +function loggy($message = null, array $context = []) { if (! isDev()) { return; From 0df717a39718a4e110a272f6714d670064003195 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 28 Oct 2024 08:54:58 +0100 Subject: [PATCH 47/47] Refactor code to add #[Locked] attribute to Member component --- app/Livewire/Team/Member.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Livewire/Team/Member.php b/app/Livewire/Team/Member.php index 680cb901b..fa0cf6122 100644 --- a/app/Livewire/Team/Member.php +++ b/app/Livewire/Team/Member.php @@ -4,10 +4,12 @@ use App\Models\User; use Illuminate\Support\Facades\Cache; +use Livewire\Attributes\Locked; use Livewire\Component; class Member extends Component { + #[Locked] public User $member; public function makeAdmin()