From 11c6cdc5732b83d11d6e7da42d33098744ba1251 Mon Sep 17 00:00:00 2001 From: biersoeckli Date: Thu, 16 Jan 2025 18:01:15 +0000 Subject: [PATCH] feat: update README and contributing guidelines, add markdown preview extension to devcontainer --- .devcontainer/devcontainer.json | 3 ++- CONTRIBUTING.md | 4 +++- README.md | 9 ++++++--- public/quickstack-repo-heading.png | Bin 0 -> 26112 bytes 4 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 public/quickstack-repo-heading.png diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 75cb22b..b5fb83f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -21,7 +21,8 @@ "mhutchie.git-graph", "donjayamanne.githistory", "qwtel.sqlite-viewer", - "mindaro.mindaro" + "mindaro.mindaro", + "shd101wyy.markdown-preview-enhanced" ] } }, diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7633118..b84aec8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,9 @@ The `type` should be one of the following: - `chore`: Changes to the build process or auxiliary tools. The `description` should be a short, descriptive summary of the changes. + The `body` is optional and should provide more detailed information about the changes. + The `footer` is optional and should contain any breaking changes, issues closed, or other relevant information. Here is an example of a commit message: @@ -74,7 +76,7 @@ yarn test To setup a developement environment, use the provided devcontainer configuration. This will setup a development environment with all necessary dependencies and the correct node version. Additionally to the devcontainer, you need a running k3s cluster. -To connect to your own k3s test cluster, provide the kuberentes cretendials in the file `k3s-config.yaml` in the root of the project with the following content. +To connect to your own k3s test cluster, provide the kuberentes credentials in the file `k3s-config.yaml` in the root of the project with the following content. #### Install Dependencies ```sh diff --git a/README.md b/README.md index 0dfb4af..07bfcbf 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -QuickStack Logo -QuickStack is a open source self-hosted Platform-as-a-Service (PaaS) solution designed to simplify the management of containerized applications on Virtual Private Server (VPS) infrastructures. -Developed as part of a student project at the [Eastern Switzerland University of Applied Sciences](https://ost.ch/), QuickStack provides a scalable and cost-effective alternative to commercial cloud PaaS offerings like Vercel, Digital Ocean App Platform or Azure App Service. +QuickStack Logo + +QuickStack is a self-hosted PaaS solution designed to simplify the management of your applications on one or more virtual private servers (VPS). + +Developed as part of a student project by [glueh-wyy-huet](https://github.com/glueh-wyy-huet) and [biersoeckli](https://github.com/biersoeckli) at the [Eastern Switzerland University of Applied Sciences](https://ost.ch/), QuickStack provides a scalable and cost-effective alternative to commercial cloud PaaS offerings like Vercel, Digital Ocean App Platform or Azure App Service. ## Key Features @@ -14,6 +16,7 @@ Developed as part of a student project at the [Eastern Switzerland University of * **SSL Certificate Management:** Automatic SSL certificate generation via Let's Encrypt. * **Resource Management:** Set resource limits (CPU, RAM, storage) for each application. * **Monitoring Dashboard:** Track resource consumption and application performance. +* **Backups:** Create backups of application data and databases to a S3-compatible storage. * **Cluster Support:** Scale applications across multiple VPS nodes. * **Persistent Storage:** Cluster-wide persistent storage volumes for applications. diff --git a/public/quickstack-repo-heading.png b/public/quickstack-repo-heading.png new file mode 100644 index 0000000000000000000000000000000000000000..f9601ec3968c409e6ab3311ea2376d48d63fbb53 GIT binary patch literal 26112 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Νei_9yF3(0{2?ecCm(td~+|0X{rlHx-vxRXt!IUav0zjTyPTDy1GxOqoW?foJGc{j+X*76qU|6#sSw7&9q5SXK66kHcvy|u&oh|0* zQ2tZr&fEelHDN*+l8qhM2bU{%2Fo(hy?a=G9_@us+csAz81jwx5i_d|SnzL5z+qpI zR8NW?ekA%NI)j93D1Kyuh$?@-+1z+9R1&tA62IB`n)qeQ(?aJ5*Xa9S0_aF{&^8p2 zZCG)y(xxuuQ-UyA2F*IufGSVudUC7JXyosjN%IjyA&ckdcP`r%M{b8Wl-aDj^&INs zZaa}G^+8S02KHhUv=rcPSdYlHa$_v{FrI@ZX}LeS8BiT7y>EycU)YuN38gC zoA;eOH*nRPyv?K}Et0EC%NS(6L7c82@Bc*qjLcN1M_#NJpJKv{o^ER_?OA z69U%4Wbs!vN5reCvLe0tC-A8B4UQ~CFtQU*UAKQ;^%TJPkjgEws_99Mvp4v*oX*+y z9Z1Hx8iBgY?@X;a_T|Rp?)eEm5ooy+kWwzQZmWmZRLjX5@}*(t7tLbX`8X5NCKUVh zGTg>qZG+zvwGd{Iu@Lqvc6DPQ@M>+-FfteS0tmTXcy@oeT|Z*BsV|Ze$oXp`!|&vr zI>M?U3%z!iD&Vdf|Cq6h`=R34bimB!ENZ+3IqBEaGz=>vSZtueE?gw*QJ!b`^*u%_ zzC5FzBkN`~Bp#9He=dYgDYX zy6D7L>-pDkzkCTQ?1&P~u$C$9J$m?0*o+&6a8AL{)>;i22_OXRb@WnC%Ca8ibbD;k zT9TFuk?QIOS9b~J8CCkl>JC5W_|wQH09CoCiNgBv*fSLe?=WlgDX!XBYZpJfX%mTI zR#tr8BO`omaIPoI^u9Q3fEi>W^5gGNNFrC&$3UESgo%`V zFn>&5U5I@1R*vW&x2zhnTxLT8fyiwl+}_1&J5k&qMQfxgnn8A){a_>~z7u#@xq3!b{5LT2s3Z$E0;1`F@A zC*>#+ZUZp-4O~e4#aOY;ZU~lLX;BhZQ*FST+$1%LgI58ZZJZRu9k?ebvw6SDy@I~- z8VtvhasuKrYLxa>DiIE~@l#S$=^{T`Ltxs%ESQ0!={3XCZfmdREWyilEjLsq9TXXC zwM?q^kO59tjDY?2Q&yXKnR51G&QtQ_gsm``a%PhKO2sEil(1Hkv0nm)wisat^S7(c zlh0u15Hg;gd-i3Jc99#-#?|^*m7gtj=WfzF-6inZV>!2ZX&*80p-VldTJHD|eCmp< zVtBXchhP?k!-YK~RD+yYonSh}3HrTX4wytJY`3RtpdVt^kHwERv)csggO$UAd*y7? z&V#`%Z~zY2ZLbw=&X?s~T{Bf!?>k$_V>yk1%oHS@Nz1o8DnpEDy#)Uudg zd+@ETJ^UbBRKH}IISHh{jE+|Il|@%*%TfIIScpD8Ed!nX;~V2MTC~0Z^#P?X9h&k$ z`Be+i;GPlw+Vz-QE=>X*=Xd5 zLX)|aT53RTjNKvcf$}U%?eFX0u<{m)U4J8hS_C*22u6nl6*DRFGIM8_xkvcFTyzU_ zTs*<-Ld1r0!raJOO<;(m@y~0XM233=o_9rSkrfmaX<#_?K*hh6XV}_NrKb0LVJ&*No4<7P8&u7J_&I?`{+R9rlAF6M%m%3a{t#w@HeNfs@@sx9nN7XN+o~HFvx8*6u<6#cLa8+e=jbhKu*i>mDB?!`WuT z<%}bb5`ezkncKK4$e^$3V~JA%+=&y62;W;_#f?laDa_rVmhMPem)+WzEJ|=^`D(9j zjdlNK5y5#V1Ve`=MlaaO5&ygq6kRJ;;AATM$O@;Iq{SHSIPFp%v6!|?VeK2e z$-t`bp$XZ_6p0~1mE!czm!Yl%MJ`1=e!6o^gGm(fSs}_vvB0YP-$Os~NQv9+tq4fz z6omJfA!lZ0cq@W3*HpU|5tQyW$VlrqQQQB0ej# z1U{J(xNZv%h0tG@7(<2eo5d|Mp1+>aZ42_mtKe-*T=<@pUD54;N|jCPY}se$3D11y zgE1m5(;w`X6k2`*`!?$$=CBl@#yL;J10^ocI}s-1)hRvI8o*CXB>omoY95Q_-B+C4 z|0n_wwe%jn9lloQ(<*w*?HidWNPZ^WcR;W{;gTK(2A~Pb(;o6=MEKWFN3C)$_lQ~% z-5;#nt2yM4S%!tNb4Y(7?q_S)-zSumP>Ew2G-N{W3(L}az$S`-)hbK0jJzEF*zaAk zGrTJ%ruL6KiJ1L=YmvYDM@LA^WY^AEx7efIK&1n?_Uw?~#KaElj4O$W9s5U*=s!39 z$2b7-5fBOfzl|L8`_(&Nv9R-xfdB7+7wro;`VJ&*ZGCRXkFCsYuf8+&{`0>8`LT;O literal 0 HcmV?d00001