Compare commits

..

55 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
e3446b6367 fix(homepage): preserve config directory during updates
Fixes #10985 - The update script was deleting user config files due to
CLEAN_INSTALL=1 flag. Now backs up and restores both .env and config/
directory to preserve user configurations.
2026-01-20 13:06:52 +01:00
community-scripts-pr-app[bot]
76912641bb Update CHANGELOG.md (#10987)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-20 00:14:01 +00:00
community-scripts-pr-app[bot]
11f67d3e50 Update versions.json (#10986)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-20 01:13:41 +01:00
community-scripts-pr-app[bot]
7b0ea03295 Update CHANGELOG.md (#10983)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 21:41:22 +00:00
CanbiZ (MickLesk)
eaf911be0b fix(pangolin): use dynamic badger plugin version (#10867) (#10975) 2026-01-19 22:41:01 +01:00
community-scripts-pr-app[bot]
245ec06d77 Update CHANGELOG.md (#10982)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 21:40:45 +00:00
CanbiZ (MickLesk)
9a489f0b53 fix(tautulli): add version detection and proper update script (#10842) (#10976) 2026-01-19 22:40:27 +01:00
community-scripts-pr-app[bot]
f75f2a24d7 Update CHANGELOG.md (#10981)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 21:40:20 +00:00
CanbiZ (MickLesk)
9e69c7a76e feat(core): add RFC 1123/952 compliant hostname/FQDN validation (#10977) 2026-01-19 22:39:57 +01:00
community-scripts-pr-app[bot]
72631c0099 Update CHANGELOG.md (#10980)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 20:47:00 +00:00
community-scripts-pr-app[bot]
1aa0475e62 Update CHANGELOG.md (#10979)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 20:46:49 +00:00
CanbiZ (MickLesk)
56c2e6cf1c fix(apache-guacamole): move jdbc cleanup after schema upgrade (#10942) (#10974)
- Temp files were deleted before schema upgrade could access them
- Fixes update script failing on MySQL schema upgrade step
2026-01-19 21:46:35 +01:00
community-scripts-pr-app[bot]
379faaa3d6 Update CHANGELOG.md (#10978)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 20:46:23 +00:00
CanbiZ (MickLesk)
0edd8fcfe3 fix(outline): prevent corepack interactive prompt blocking installation (#10973)
- Add COREPACK_ENABLE_DOWNLOAD_PROMPT=0 to skip yarn download confirmation
- Fixes installation hanging on 'Configuring Outline (Patience)'
2026-01-19 21:46:18 +01:00
CanbiZ (MickLesk)
c8c1c454ce fix(firefly): prevent nested storage directories during update (#10967) (#10972)
- Remove existing backup directory before creating new backup
- Clean up temporary files after successful update
2026-01-19 21:45:59 +01:00
community-scripts-pr-app[bot]
69b0e5b858 Update .app files (#10971)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-19 21:07:22 +01:00
community-scripts-pr-app[bot]
41384d0764 Update CHANGELOG.md (#10970)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 19:40:53 +00:00
community-scripts-pr-app[bot]
1e6f37057b Update date in json (#10969)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-19 19:40:27 +00:00
push-app-to-main[bot]
7a71414d0e Add yubal (ct) (#10955) 2026-01-19 20:40:05 +01:00
CanbiZ (MickLesk)
de20a41423 Prioritize eth0 IP lookup in get_lxc_ip function
The get_lxc_ip function now attempts to retrieve the IP address directly from eth0 before falling back to hostname -I. This improves reliability for LXC containers where eth0 is typically the primary interface.
2026-01-19 17:41:17 +01:00
CanbiZ (MickLesk)
008f6af0bd Call get_lxc_ip explicitly after network is up
Moved the get_lxc_ip call from automatic execution in load_functions to explicit calls in alpine-install.func and install.func, ensuring the LXC IP is retrieved only after the network is up inside the container. Updated comments to clarify usage.
2026-01-19 17:40:25 +01:00
CanbiZ (MickLesk)
d6811a3383 Fix ip import (#10964)
* Rename import_local_ip to get_local_ip

Replaces all references to the helper function import_local_ip with get_local_ip across scripts and documentation for consistency. Updates usage examples and comments to reflect the new function name.

* Rename get_local_ip to get_lxc_ip and update usage

Replaces all references to get_local_ip with get_lxc_ip across scripts, documentation, and templates for clarity and consistency. Updates the implementation in core.func to improve IP detection for LXC containers, and adjusts helper functions in addon scripts accordingly.
2026-01-19 17:32:44 +01:00
community-scripts-pr-app[bot]
38a0757e4e Update CHANGELOG.md (#10963)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 16:20:48 +00:00
Chris
cb8a900d84 PeaNUT: change default port (#10962) 2026-01-19 17:20:25 +01:00
community-scripts-pr-app[bot]
3bf08df691 Update CHANGELOG.md (#10960)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 15:33:41 +00:00
Slaviša Arežina
90f73d1d24 Remove custom IP fetching (#10954)
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
2026-01-19 16:33:08 +01:00
community-scripts-pr-app[bot]
bc53369bab Update CHANGELOG.md (#10957)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 14:46:08 +00:00
Slaviša Arežina
56ab6a6cb8 Refactor: Homepage (#10950) 2026-01-19 15:45:41 +01:00
community-scripts-pr-app[bot]
4f389c01f9 Update CHANGELOG.md (#10956)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 14:43:34 +00:00
Slaviša Arežina
db5a6bacf4 [core]: Make LXC IP a global variable (#10951) 2026-01-19 15:43:12 +01:00
community-scripts-pr-app[bot]
3e6cfe2766 Update CHANGELOG.md (#10952)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 13:53:48 +00:00
Robert Castley
de14cab715 Update/splunk enterprise (#10949) 2026-01-19 14:53:25 +01:00
community-scripts-pr-app[bot]
187cd4825e Update CHANGELOG.md (#10948)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 12:38:03 +00:00
community-scripts-pr-app[bot]
4dbbbf1545 Update CHANGELOG.md (#10947)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 12:37:53 +00:00
CanbiZ (MickLesk)
9e2c801d29 Refactor: copyparty (#10941) 2026-01-19 13:37:39 +01:00
community-scripts-pr-app[bot]
2903c3d8ad Update CHANGELOG.md (#10946)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 12:37:25 +00:00
Slaviša Arežina
f029460bc6 Refactor (#10945) 2026-01-19 13:36:59 +01:00
community-scripts-pr-app[bot]
6578f3c5f7 Update versions.json (#10944)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 13:06:52 +01:00
community-scripts-pr-app[bot]
973e7e0325 Update CHANGELOG.md (#10940)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 09:04:45 +00:00
CanbiZ (MickLesk)
73944792b5 Remove phpIPAM (#10939) 2026-01-19 10:04:19 +01:00
community-scripts-pr-app[bot]
afe9d08233 Update CHANGELOG.md (#10937)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 00:15:29 +00:00
community-scripts-pr-app[bot]
9e1354a87b Update versions.json (#10936)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-19 01:15:07 +01:00
community-scripts-pr-app[bot]
f2aca758ea Update .app files (#10933)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-18 22:25:32 +01:00
community-scripts-pr-app[bot]
3f4e291203 Update CHANGELOG.md (#10935)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-18 21:24:46 +00:00
community-scripts-pr-app[bot]
ab86f00c68 Update CHANGELOG.md (#10934)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-18 21:24:30 +00:00
community-scripts-pr-app[bot]
9d6c2ba2ae Update date in json (#10932)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-18 21:24:25 +00:00
push-app-to-main[bot]
ac68ce48de Termix (#10887)
* Add termix (ct)

* refactor

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-01-18 22:24:04 +01:00
community-scripts-pr-app[bot]
4aa6eb7fb5 Update CHANGELOG.md (#10931)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-18 21:05:32 +00:00
Slaviša Arežina
dbf551d162 Refactor (#10928) 2026-01-18 22:05:08 +01:00
community-scripts-pr-app[bot]
7a52b83eb8 Update CHANGELOG.md (#10930)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-18 20:20:43 +00:00
Slaviša Arežina
ca97009d1e Remove iVentoy script (#10924) 2026-01-18 21:20:26 +01:00
community-scripts-pr-app[bot]
2c1756cad9 Update CHANGELOG.md (#10929)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-18 20:20:18 +00:00
CanbiZ (MickLesk)
6e66359d8f Improve password handling and validation logic (#10925) 2026-01-18 21:19:53 +01:00
community-scripts-pr-app[bot]
e21ab1500b Update CHANGELOG.md (#10922)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-18 17:18:21 +00:00
Christiaan Goossens
fe5108f7ca Fix escaping of the map block (#10920) 2026-01-18 18:18:00 +01:00
115 changed files with 2162 additions and 3218 deletions

View File

@@ -10,24 +10,84 @@
> [!CAUTION] > [!CAUTION]
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes. Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
## 2026-01-20
## 2026-01-19
### 🆕 New Scripts
- yubal ([#10955](https://github.com/community-scripts/ProxmoxVE/pull/10955))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Apache-Guacamole: move jdbc cleanup after schema upgrade [@MickLesk](https://github.com/MickLesk) ([#10974](https://github.com/community-scripts/ProxmoxVE/pull/10974))
- Outline: prevent corepack interactive prompt blocking installation [@MickLesk](https://github.com/MickLesk) ([#10973](https://github.com/community-scripts/ProxmoxVE/pull/10973))
- firefly: prevent nested storage directories during update (#10967) [@MickLesk](https://github.com/MickLesk) ([#10972](https://github.com/community-scripts/ProxmoxVE/pull/10972))
- PeaNUT: change default port [@vhsdream](https://github.com/vhsdream) ([#10962](https://github.com/community-scripts/ProxmoxVE/pull/10962))
- Update/splunk enterprise [@rcastley](https://github.com/rcastley) ([#10949](https://github.com/community-scripts/ProxmoxVE/pull/10949))
- #### ✨ New Features
- Pangolin: use dynamic badger plugin version [@MickLesk](https://github.com/MickLesk) ([#10975](https://github.com/community-scripts/ProxmoxVE/pull/10975))
- Tautulli: add version detection and add proper update script [@MickLesk](https://github.com/MickLesk) ([#10976](https://github.com/community-scripts/ProxmoxVE/pull/10976))
- #### 🔧 Refactor
- Refactor: Remove custom IP fetching in scripts [@tremor021](https://github.com/tremor021) ([#10954](https://github.com/community-scripts/ProxmoxVE/pull/10954))
- Refactor: Homepage [@tremor021](https://github.com/tremor021) ([#10950](https://github.com/community-scripts/ProxmoxVE/pull/10950))
- Refactor: hev-socks5-server [@tremor021](https://github.com/tremor021) ([#10945](https://github.com/community-scripts/ProxmoxVE/pull/10945))
### 🗑️ Deleted Scripts
- Remove: phpIPAM [@MickLesk](https://github.com/MickLesk) ([#10939](https://github.com/community-scripts/ProxmoxVE/pull/10939))
### 💾 Core
- #### ✨ New Features
- core: add RFC 1123/952 compliant hostname/FQDN validation [@MickLesk](https://github.com/MickLesk) ([#10977](https://github.com/community-scripts/ProxmoxVE/pull/10977))
- [core]: Make LXC IP a global variable [@tremor021](https://github.com/tremor021) ([#10951](https://github.com/community-scripts/ProxmoxVE/pull/10951))
### 🧰 Tools
- #### 🔧 Refactor
- Refactor: copyparty [@MickLesk](https://github.com/MickLesk) ([#10941](https://github.com/community-scripts/ProxmoxVE/pull/10941))
## 2026-01-18 ## 2026-01-18
### 🆕 New Scripts ### 🆕 New Scripts
- Termix ([#10887](https://github.com/community-scripts/ProxmoxVE/pull/10887))
- ThingsBoard ([#10904](https://github.com/community-scripts/ProxmoxVE/pull/10904)) - ThingsBoard ([#10904](https://github.com/community-scripts/ProxmoxVE/pull/10904))
### 🚀 Updated Scripts ### 🚀 Updated Scripts
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes
- Fix Patchmon install script (escaping) [@christiaangoossens](https://github.com/christiaangoossens) ([#10920](https://github.com/community-scripts/ProxmoxVE/pull/10920))
- refactor: peanut entrypoint [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10902](https://github.com/community-scripts/ProxmoxVE/pull/10902)) - refactor: peanut entrypoint [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10902](https://github.com/community-scripts/ProxmoxVE/pull/10902))
- #### 💥 Breaking Changes - #### 💥 Breaking Changes
- Update Patchmon default Nginx config (IPv6 and correct scheme) [@christiaangoossens](https://github.com/christiaangoossens) ([#10917](https://github.com/community-scripts/ProxmoxVE/pull/10917)) - Update Patchmon default Nginx config (IPv6 and correct scheme) [@christiaangoossens](https://github.com/christiaangoossens) ([#10917](https://github.com/community-scripts/ProxmoxVE/pull/10917))
- #### 🔧 Refactor
- Refactor: FluidCalendar [@tremor021](https://github.com/tremor021) ([#10928](https://github.com/community-scripts/ProxmoxVE/pull/10928))
### 🗑️ Deleted Scripts
- Remove iVentoy script [@tremor021](https://github.com/tremor021) ([#10924](https://github.com/community-scripts/ProxmoxVE/pull/10924))
### 💾 Core ### 💾 Core
- #### ✨ New Features
- core: improve password handling and validation logic [@MickLesk](https://github.com/MickLesk) ([#10925](https://github.com/community-scripts/ProxmoxVE/pull/10925))
- #### 🔧 Refactor - #### 🔧 Refactor
- hwaccel: improve NVIDIA version matching and GPU selection UI [@MickLesk](https://github.com/MickLesk) ([#10901](https://github.com/community-scripts/ProxmoxVE/pull/10901)) - hwaccel: improve NVIDIA version matching and GPU selection UI [@MickLesk](https://github.com/MickLesk) ([#10901](https://github.com/community-scripts/ProxmoxVE/pull/10901))

View File

@@ -92,7 +92,6 @@ function update_script() {
curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-jdbc-${LATEST_SERVER}.tar.gz" -o "/tmp/guacamole-auth-jdbc.tar.gz" curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-jdbc-${LATEST_SERVER}.tar.gz" -o "/tmp/guacamole-auth-jdbc.tar.gz"
$STD tar -xf /tmp/guacamole-auth-jdbc.tar.gz -C /tmp $STD tar -xf /tmp/guacamole-auth-jdbc.tar.gz -C /tmp
mv /tmp/guacamole-auth-jdbc-"${LATEST_SERVER}"/mysql/guacamole-auth-jdbc-mysql-"${LATEST_SERVER}".jar /etc/guacamole/extensions/ mv /tmp/guacamole-auth-jdbc-"${LATEST_SERVER}"/mysql/guacamole-auth-jdbc-mysql-"${LATEST_SERVER}".jar /etc/guacamole/extensions/
rm -rf /tmp/guacamole-auth-jdbc*
echo "${LATEST_SERVER}" >~/.guacamole_auth_jdbc echo "${LATEST_SERVER}" >~/.guacamole_auth_jdbc
msg_ok "Updated Guacamole Auth JDBC" msg_ok "Updated Guacamole Auth JDBC"
else else
@@ -140,6 +139,7 @@ function update_script() {
fi fi
done done
fi fi
rm -rf /tmp/guacamole-auth-jdbc*
msg_ok "MySQL Schema updated" msg_ok "MySQL Schema updated"
fi fi

View File

@@ -43,7 +43,6 @@ function update_script() {
if [ "$UPD" == "2" ]; then if [ "$UPD" == "2" ]; then
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
if check_for_gh_release "cronicle" "jhuckaby/Cronicle"; then if check_for_gh_release "cronicle" "jhuckaby/Cronicle"; then
IP=$(hostname -I | awk '{print $1}')
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt-get install -y \ $STD apt-get install -y \
git \ git \
@@ -59,7 +58,7 @@ function update_script() {
cd /opt/cronicle cd /opt/cronicle
$STD npm install $STD npm install
$STD node bin/build.js dist $STD node bin/build.js dist
sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json sed -i "s/localhost:3012/${LOCAL_IP}:3012/g" /opt/cronicle/conf/config.json
$STD /opt/cronicle/bin/control.sh start $STD /opt/cronicle/bin/control.sh start
msg_ok "Installed Cronicle Worker" msg_ok "Installed Cronicle Worker"
echo -e "\n Add Masters secret key to /opt/cronicle/conf/config.json \n" echo -e "\n Add Masters secret key to /opt/cronicle/conf/config.json \n"

View File

@@ -32,6 +32,7 @@ function update_script() {
if check_for_gh_release "firefly" "firefly-iii/firefly-iii"; then if check_for_gh_release "firefly" "firefly-iii/firefly-iii"; then
systemctl stop apache2 systemctl stop apache2
cp /opt/firefly/.env /opt/.env cp /opt/firefly/.env /opt/.env
rm -rf /opt/storage
cp -r /opt/firefly/storage /opt/storage cp -r /opt/firefly/storage /opt/storage
if [[ -d /opt/firefly/dataimporter ]]; then if [[ -d /opt/firefly/dataimporter ]]; then
@@ -82,6 +83,7 @@ function update_script() {
chown -R www-data:www-data /opt/firefly/dataimporter chown -R www-data:www-data /opt/firefly/dataimporter
msg_ok "Updated Firefly Importer" msg_ok "Updated Firefly Importer"
fi fi
rm -rf /opt/storage /opt/.env /opt/dataimporter.env
systemctl start apache2 systemctl start apache2
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi fi

View File

@@ -34,11 +34,10 @@ function update_script() {
msg_info "Stopped Service" msg_info "Stopped Service"
cp /opt/fluid-calendar/.env /opt/fluid.env cp /opt/fluid-calendar/.env /opt/fluid.env
rm -rf /opt/fluid-calendar CLEAN_INSTALL=1 fetch_and_deploy_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar" "tarball"
fetch_and_deploy_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar" "tarball" mv /opt/fluid.env /opt/fluid-calendar/.env
msg_info "Updating Fluid Calendar" msg_info "Updating Fluid Calendar"
mv /opt/fluid.env /opt/fluid-calendar/.env
cd /opt/fluid-calendar cd /opt/fluid-calendar
export NEXT_TELEMETRY_DISABLED=1 export NEXT_TELEMETRY_DISABLED=1
$STD npm install --legacy-peer-deps $STD npm install --legacy-peer-deps

View File

@@ -49,14 +49,13 @@ function update_script() {
if [[ ! -f /opt/gitea-mirror.env ]]; then if [[ ! -f /opt/gitea-mirror.env ]]; then
msg_info "Detected old Enviroment, updating files" msg_info "Detected old Enviroment, updating files"
APP_SECRET=$(openssl rand -base64 32) APP_SECRET=$(openssl rand -base64 32)
HOST_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/opt/gitea-mirror.env cat <<EOF >/opt/gitea-mirror.env
# See here for config options: https://github.com/RayLabsHQ/gitea-mirror/blob/main/docs/ENVIRONMENT_VARIABLES.md # See here for config options: https://github.com/RayLabsHQ/gitea-mirror/blob/main/docs/ENVIRONMENT_VARIABLES.md
NODE_ENV=production NODE_ENV=production
HOST=0.0.0.0 HOST=0.0.0.0
PORT=4321 PORT=4321
DATABASE_URL=sqlite://data/gitea-mirror.db DATABASE_URL=sqlite://data/gitea-mirror.db
BETTER_AUTH_URL=http://${HOST_IP}:4321 BETTER_AUTH_URL=http://${LOCAL_IP}:4321
BETTER_AUTH_SECRET=${APP_SECRET} BETTER_AUTH_SECRET=${APP_SECRET}
npm_package_version=${APP_VERSION} npm_package_version=${APP_VERSION}
EOF EOF

View File

@@ -1,6 +0,0 @@
_ _ __ __
(_) | / /__ ____ / /_____ __ __
/ /| | / / _ \/ __ \/ __/ __ \/ / / /
/ / | |/ / __/ / / / /_/ /_/ / /_/ /
/_/ |___/\___/_/ /_/\__/\____/\__, /
/____/

View File

@@ -1,6 +0,0 @@
__ ________ ___ __ ___
____ / /_ ____ / _/ __ \/ | / |/ /
/ __ \/ __ \/ __ \ / // /_/ / /| | / /|_/ /
/ /_/ / / / / /_/ // // ____/ ___ |/ / / /
/ .___/_/ /_/ .___/___/_/ /_/ |_/_/ /_/
/_/ /_/

6
ct/headers/termix Normal file
View File

@@ -0,0 +1,6 @@
______ _
/_ __/__ _________ ___ (_) __
/ / / _ \/ ___/ __ `__ \/ / |/_/
/ / / __/ / / / / / / / /> <
/_/ \___/_/ /_/ /_/ /_/_/_/|_|

6
ct/headers/yubal Normal file
View File

@@ -0,0 +1,6 @@
__ __ __ __
\ \/ /_ __/ /_ ____ _/ /
\ / / / / __ \/ __ `/ /
/ / /_/ / /_/ / /_/ / /
/_/\__,_/_.___/\__,_/_/

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}" var_ram="${var_ram:-512}"
var_disk="${var_disk:-2}" var_disk="${var_disk:-2}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-12}" var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"
@@ -29,26 +29,18 @@ function update_script() {
exit exit
fi fi
RELEASE=$(curl -fsSL https://api.github.com/repos/heiher/${APP}/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then if check_for_gh_release "hev-socks5-server" "heiher/hev-socks5-server"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop hev-socks5-server systemctl stop hev-socks5-server
msg_ok "Stopped Service" msg_ok "Stopped Service"
msg_info "Updating $APP to v${RELEASE}" fetch_and_deploy_gh_release "hev-socks5-server" "heiher/hev-socks5-server" "singlefile" "latest" "/opt" "hev-socks5-server-linux-x86_64"
curl -L -o "${APP}" "https://github.com/heiher/${APP}/releases/download/${RELEASE}/hev-socks5-server-linux-x86_64"
mv ${APP} /opt/${APP}
chmod +x /opt/${APP}
msg_ok "Updated hev-socks5-server to v${RELEASE}"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start hev-socks5-server systemctl start hev-socks5-server
msg_ok "Started Service" msg_ok "Started Service"
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at v${RELEASE}"
fi fi
exit exit
} }

View File

@@ -69,7 +69,6 @@ function update_script() {
exit exit
fi fi
if [ "$UPD" == "4" ]; then if [ "$UPD" == "4" ]; then
IP=$(hostname -I | awk '{print $1}')
msg_info "Installing FileBrowser" msg_info "Installing FileBrowser"
RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g')
$STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin $STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin
@@ -95,7 +94,7 @@ WantedBy=default.target" >$service_path
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
echo -e "FileBrowser should be reachable by going to the following URL. echo -e "FileBrowser should be reachable by going to the following URL.
${BL}http://$IP:8080${CL} admin|helper-scripts.com\n" ${BL}http://$LOCAL_IP:8080${CL} admin|helper-scripts.com\n"
exit exit
fi fi
} }

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}" var_ram="${var_ram:-4096}"
var_disk="${var_disk:-6}" var_disk="${var_disk:-6}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-12}" var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"
@@ -28,6 +28,7 @@ function update_script() {
exit exit
fi fi
get_lxc_ip
NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs
if ! command -v jq &>/dev/null; then if ! command -v jq &>/dev/null; then
$STD msg_info "Installing jq..." $STD msg_info "Installing jq..."
@@ -37,16 +38,21 @@ function update_script() {
exit exit
} }
fi fi
LOCAL_IP=$(hostname -I | awk '{print $1}')
RELEASE=$(curl -fsSL https://api.github.com/repos/gethomepage/homepage/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') if check_for_gh_release "homepage" "gethomepage/homepage"; then
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then msg_info "Stopping service"
msg_info "Updating Homepage to v${RELEASE} (Patience)"
systemctl stop homepage systemctl stop homepage
curl -fsSL "https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz" -o $(basename "https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz") msg_ok "Stopped service"
tar -xzf v${RELEASE}.tar.gz
rm -rf v${RELEASE}.tar.gz cp /opt/homepage/.env /opt/homepage.env
cp -r homepage-${RELEASE}/* /opt/homepage/ cp -r /opt/homepage/config /opt/homepage_config_backup
rm -rf homepage-${RELEASE} CLEAN_INSTALL=1 fetch_and_deploy_gh_release "homepage" "gethomepage/homepage" "tarball"
mv /opt/homepage.env /opt/homepage
rm -rf /opt/homepage/config
mv /opt/homepage_config_backup /opt/homepage/config
msg_info "Updating Homepage (Patience)"
RELEASE=$(get_latest_github_release "gethomepage/homepage")
cd /opt/homepage cd /opt/homepage
$STD pnpm install $STD pnpm install
$STD pnpm update --no-save caniuse-lite $STD pnpm update --no-save caniuse-lite
@@ -55,14 +61,12 @@ function update_script() {
export NEXT_PUBLIC_BUILDTIME=$(curl -fsSL https://api.github.com/repos/gethomepage/homepage/releases/latest | jq -r '.published_at') export NEXT_PUBLIC_BUILDTIME=$(curl -fsSL https://api.github.com/repos/gethomepage/homepage/releases/latest | jq -r '.published_at')
export NEXT_TELEMETRY_DISABLED=1 export NEXT_TELEMETRY_DISABLED=1
$STD pnpm build $STD pnpm build
if [[ ! -f /opt/homepage/.env ]]; then msg_ok "Updated Homepage"
echo "HOMEPAGE_ALLOWED_HOSTS=localhost:3000,${LOCAL_IP}:3000" >/opt/homepage/.env
fi msg_info "Starting service"
systemctl start homepage systemctl start homepage
echo "${RELEASE}" >/opt/${APP}_version.txt msg_ok "Started service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at v${RELEASE}"
fi fi
exit exit
} }

View File

@@ -1,41 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.iventoy.com/en/index.html
APP="iVentoy"
var_tags="${var_tags:-pxe-tool}"
var_disk="${var_disk:-2}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-0}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/iventoy ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:26000${CL}"

View File

@@ -29,13 +29,12 @@ function update_script() {
fi fi
if [ ! -f /opt/n8n.env ]; then if [ ! -f /opt/n8n.env ]; then
sed -i 's|^Environment="N8N_SECURE_COOKIE=false"$|EnvironmentFile=/opt/n8n.env|' /etc/systemd/system/n8n.service sed -i 's|^Environment="N8N_SECURE_COOKIE=false"$|EnvironmentFile=/opt/n8n.env|' /etc/systemd/system/n8n.service
HOST_IP=$(hostname -I | awk '{print $1}')
mkdir -p /opt mkdir -p /opt
cat <<EOF >/opt/n8n.env cat <<EOF >/opt/n8n.env
N8N_SECURE_COOKIE=false N8N_SECURE_COOKIE=false
N8N_PORT=5678 N8N_PORT=5678
N8N_PROTOCOL=http N8N_PROTOCOL=http
N8N_HOST=$HOST_IP N8N_HOST=$LOCAL_IP
EOF EOF
fi fi
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs

View File

@@ -49,7 +49,6 @@ function update_script() {
if [[ -f /opt/netvisor/oidc.toml ]]; then if [[ -f /opt/netvisor/oidc.toml ]]; then
mv /opt/netvisor/oidc.toml /opt/scanopy/oidc.toml mv /opt/netvisor/oidc.toml /opt/scanopy/oidc.toml
fi fi
LOCAL_IP="$(hostname -I | awk '{print $1}')"
if ! grep -q "PUBLIC_URL" /opt/scanopy/.env; then if ! grep -q "PUBLIC_URL" /opt/scanopy/.env; then
sed -i "\|_PATH=|a\NETVISOR_PUBLIC_URL=http://${LOCAL_IP}:60072" /opt/scanopy/.env sed -i "\|_PATH=|a\NETVISOR_PUBLIC_URL=http://${LOCAL_IP}:60072" /opt/scanopy/.env
fi fi

View File

@@ -41,16 +41,17 @@ function update_script() {
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "outline" "outline/outline" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "outline" "outline/outline" "tarball"
msg_info "Updating ${APP}" msg_info "Updating Outline"
cd /opt/outline cd /opt/outline
mv /opt/.env /opt/outline mv /opt/.env /opt/outline
export NODE_ENV=development export NODE_ENV=development
export NODE_OPTIONS="--max-old-space-size=3584" export NODE_OPTIONS="--max-old-space-size=3584"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
$STD corepack enable $STD corepack enable
$STD yarn install --immutable $STD yarn install --immutable
export NODE_ENV=production export NODE_ENV=production
$STD yarn build $STD yarn build
msg_ok "Updated ${APP}" msg_ok "Updated Outline"
msg_info "Starting Services" msg_info "Starting Services"
systemctl start outline systemctl start outline

View File

@@ -60,6 +60,11 @@ function update_script() {
rm -f /opt/pangolin_config_backup.tar.gz rm -f /opt/pangolin_config_backup.tar.gz
msg_ok "Restored config" msg_ok "Restored config"
msg_info "Updating Badger plugin version"
BADGER_VERSION=$(get_latest_github_release "fosrl/badger" "false")
sed -i "s/version: \"v[0-9.]*\"/version: \"$BADGER_VERSION\"/g" /opt/pangolin/config/traefik/traefik_config.yml
msg_ok "Updated Badger plugin version"
msg_info "Starting Services" msg_info "Starting Services"
systemctl start pangolin systemctl start pangolin
systemctl start gerbil systemctl start gerbil

View File

@@ -70,4 +70,4 @@ description
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}" echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"

View File

@@ -1,64 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: bvdberg01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://phpipam.net/
APP="phpIPAM"
var_tags="${var_tags:-network}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/phpipam ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
setup_mariadb
if check_for_gh_release "phpipam" "phpipam/phpipam"; then
msg_info "Stopping Service"
systemctl stop apache2
msg_ok "Stopped Service"
PHP_VERSION="8.4" PHP_APACHE="YES" PHP_FPM="YES" PHP_MODULE="mysql,gmp,snmp,ldap,apcu" setup_php
msg_info "Installing PHP-PEAR"
$STD apt install -y \
php-pear \
php-dev
msg_ok "Installed PHP-PEAR"
mv /opt/phpipam/ /opt/phpipam-backup
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "phpipam" "phpipam/phpipam" "prebuild" "latest" "/opt/phpipam" "phpipam-v*.zip"
cp /opt/phpipam-backup/config.php /opt/phpipam
rm -r /opt/phpipam-backup
msg_info "Starting Service"
systemctl start apache2
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

View File

@@ -65,7 +65,6 @@ function update_script() {
exit exit
fi fi
if [ "$UPD" == "3" ]; then if [ "$UPD" == "3" ]; then
import_local_ip
msg_info "Installing FileBrowser" msg_info "Installing FileBrowser"
$STD curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash $STD curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
$STD filebrowser config init -a '0.0.0.0' $STD filebrowser config init -a '0.0.0.0'

View File

@@ -56,7 +56,6 @@ function update_script() {
if [[ -f /opt/scanopy.oidc.toml ]]; then if [[ -f /opt/scanopy.oidc.toml ]]; then
mv /opt/scanopy.oidc.toml /opt/scanopy/oidc.toml mv /opt/scanopy.oidc.toml /opt/scanopy/oidc.toml
fi fi
LOCAL_IP="$(hostname -I | awk '{print $1}')"
if ! grep -q "PUBLIC_URL" /opt/scanopy/.env; then if ! grep -q "PUBLIC_URL" /opt/scanopy/.env; then
sed -i "\|_PATH=|a\scanopy_PUBLIC_URL=http://${LOCAL_IP}:60072" /opt/scanopy/.env sed -i "\|_PATH=|a\scanopy_PUBLIC_URL=http://${LOCAL_IP}:60072" /opt/scanopy/.env
fi fi

View File

@@ -10,8 +10,8 @@ var_tags="${var_tags:-monitoring}"
var_cpu="${var_cpu:-4}" var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-8192}" var_ram="${var_ram:-8192}"
var_disk="${var_disk:-40}" var_disk="${var_disk:-40}"
var_os="${var_os:-ubuntu}" var_os="${var_os:-debian}"
var_version="${var_version:-24.04}" var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"

View File

@@ -27,11 +27,42 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
if check_for_gh_release "Tautulli" "Tautulli/Tautulli"; then
PYTHON_VERSION="3.13" setup_uv
msg_info "Stopping Service"
systemctl stop tautulli
msg_ok "Stopped Service"
msg_info "Backing up config"
cp -r /opt/Tautulli/config /opt/tautulli_config_backup
msg_ok "Backed up config"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Tautulli" "Tautulli/Tautulli" "tarball"
msg_info "Updating Tautulli" msg_info "Updating Tautulli"
$STD apt update cd /opt/Tautulli
$STD apt upgrade -y TAUTULLI_VERSION=$(get_latest_github_release "Tautulli/Tautulli" "false")
echo "${TAUTULLI_VERSION}" >/opt/Tautulli/version.txt
echo "master" >/opt/Tautulli/branch.txt
source /opt/Tautulli/.venv/bin/activate
$STD pip install --upgrade uv
$STD uv pip install -q -r requirements.txt
$STD uv pip install -q pyopenssl
deactivate
msg_ok "Updated Tautulli" msg_ok "Updated Tautulli"
msg_info "Restoring config"
cp -r /opt/tautulli_config_backup/* /opt/Tautulli/config/
rm -rf /opt/tautulli_config_backup
msg_ok "Restored config"
msg_info "Starting Service"
systemctl start tautulli
msg_ok "Started Service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi
exit exit
} }

90
ct/termix.sh Normal file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Termix-SSH/Termix
APP="Termix"
var_tags="${var_tags:-ssh;terminal;management}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/termix ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "termix" "Termix-SSH/Termix"; then
msg_info "Stopping Service"
systemctl stop termix
msg_ok "Stopped Service"
msg_info "Backing up Data"
cp -r /opt/termix/data /opt/termix_data_backup
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "termix" "Termix-SSH/Termix"
msg_info "Building Frontend"
cd /opt/termix
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
find public/fonts -name "*.ttf" ! -name "*Regular.ttf" ! -name "*Bold.ttf" ! -name "*Italic.ttf" -delete 2>/dev/null || true
$STD npm install --ignore-scripts --force
$STD npm run build
msg_ok "Built Frontend"
msg_info "Building Backend"
$STD npm rebuild better-sqlite3 --force
$STD npm run build:backend
msg_ok "Built Backend"
msg_info "Setting up Production Dependencies"
$STD npm ci --only=production --ignore-scripts --force
$STD npm rebuild better-sqlite3 bcryptjs --force
$STD npm cache clean --force
msg_ok "Set up Production Dependencies"
msg_info "Restoring Data"
mkdir -p /opt/termix/data
cp -r /opt/termix_data_backup/. /opt/termix/data
rm -rf /opt/termix_data_backup
msg_ok "Restored Data"
msg_info "Updating Frontend Files"
rm -rf /opt/termix/html/*
cp -r /opt/termix/dist/* /opt/termix/html/ 2>/dev/null || true
cp -r /opt/termix/src/locales /opt/termix/html/locales 2>/dev/null || true
cp -r /opt/termix/public/fonts /opt/termix/html/fonts 2>/dev/null || true
msg_ok "Updated Frontend Files"
msg_info "Starting Service"
systemctl start termix
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

66
ct/yubal.sh Normal file
View File

@@ -0,0 +1,66 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Crazywolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/guillevc/yubal
APP="Yubal"
var_tags="${var_tags:-music;media}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-15}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/yubal ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "yubal" "guillevc/yubal"; then
msg_info "Stopping Services"
systemctl stop yubal
msg_ok "Stopped Services"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "yubal" "guillevc/yubal" "tarball" "latest" "/opt/yubal"
msg_info "Building Frontend"
cd /opt/yubal/web
$STD bun install --frozen-lockfile
VERSION=$(get_latest_github_release "guillevc/yubal")
VITE_VERSION=$VERSION VITE_COMMIT_SHA=$VERSION VITE_IS_RELEASE=true $STD bun run build
msg_ok "Built Frontend"
msg_info "Installing Python Dependencies"
cd /opt/yubal
$STD uv sync --no-dev --frozen
msg_ok "Installed Python Dependencies"
msg_info "Starting Services"
systemctl start yubal
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"

View File

@@ -1,868 +0,0 @@
# 🤖 AI Contribution Guidelines for ProxmoxVE
> **This documentation is intended for all AI assistants (GitHub Copilot, Claude, ChatGPT, etc.) contributing to this project.**
## 🎯 Core Principles
### 1. **Maximum Use of `tools.func` Functions**
We have an extensive library of helper functions. **NEVER** implement your own solutions when a function already exists!
### 2. **No Pointless Variables**
Only create variables when they:
- Are used multiple times
- Improve readability
- Are intended for configuration
### 3. **Consistent Script Structure**
All scripts follow an identical structure. Deviations are not acceptable.
### 4. **Bare-Metal Installation**
We do **NOT use Docker** for our installation scripts. All applications are installed directly on the system.
---
## 📁 Script Types and Their Structure
### CT Script (`ct/AppName.sh`)
```bash
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: AuthorName (GitHubUsername)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://application-url.com
APP="AppName"
var_tags="${var_tags:-tag1;tag2;tag3}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/appname ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "appname" "YourUsername/YourRepo"; then
msg_info "Stopping Service"
systemctl stop appname
msg_ok "Stopped Service"
msg_info "Backing up Data"
cp -r /opt/appname/data /opt/appname_data_backup
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
# Build steps...
msg_info "Restoring Data"
cp -r /opt/appname_data_backup/. /opt/appname/data
rm -rf /opt/appname_data_backup
msg_ok "Restored Data"
msg_info "Starting Service"
systemctl start appname
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:PORT${CL}"
```
### Install Script (`install/AppName-install.sh`)
```bash
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: AuthorName (GitHubUsername)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://application-url.com
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
dependency1 \
dependency2
msg_ok "Installed Dependencies"
# Runtime Setup (ALWAYS use our functions!)
NODE_VERSION="22" setup_nodejs
# or
PG_VERSION="16" setup_postgresql
# or
setup_uv
# etc.
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
msg_info "Setting up Application"
cd /opt/appname
# Build/Setup Schritte...
msg_ok "Set up Application"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/appname.service
[Unit]
Description=AppName Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/appname
ExecStart=/path/to/executable
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now appname
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
```
---
## 🔧 Available Helper Functions
### Release Management
| Function | Description | Example |
| ----------------------------- | ----------------------------------- | ------------------------------------------------------------- |
| `fetch_and_deploy_gh_release` | Fetches and installs GitHub Release | `fetch_and_deploy_gh_release "app" "owner/repo"` |
| `check_for_gh_release` | Checks for new version | `if check_for_gh_release "app" "YourUsername/YourRepo"; then` |
**Modes for `fetch_and_deploy_gh_release`:**
```bash
# Tarball/Source (Standard)
fetch_and_deploy_gh_release "appname" "owner/repo"
# Binary (.deb)
fetch_and_deploy_gh_release "appname" "owner/repo" "binary"
# Prebuilt Archive
fetch_and_deploy_gh_release "appname" "owner/repo" "prebuild" "latest" "/opt/appname" "filename.tar.gz"
# Single Binary
fetch_and_deploy_gh_release "appname" "owner/repo" "singlefile" "latest" "/opt/appname" "binary-linux-amd64"
```
**Clean Install Flag:**
```bash
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo"
```
### Runtime/Language Setup
| Function | Variable(s) | Example |
| -------------- | ----------------------------- | ---------------------------------------------------- |
| `setup_nodejs` | `NODE_VERSION`, `NODE_MODULE` | `NODE_VERSION="22" setup_nodejs` |
| `setup_uv` | `PYTHON_VERSION` | `PYTHON_VERSION="3.12" setup_uv` |
| `setup_go` | `GO_VERSION` | `GO_VERSION="1.22" setup_go` |
| `setup_rust` | `RUST_VERSION`, `RUST_CRATES` | `RUST_CRATES="monolith" setup_rust` |
| `setup_ruby` | `RUBY_VERSION` | `RUBY_VERSION="3.3" setup_ruby` |
| `setup_java` | `JAVA_VERSION` | `JAVA_VERSION="21" setup_java` |
| `setup_php` | `PHP_VERSION`, `PHP_MODULES` | `PHP_VERSION="8.3" PHP_MODULES="redis,gd" setup_php` |
### Database Setup
| Function | Variable(s) | Example |
| --------------------- | ------------------------------------ | ----------------------------------------------------------- |
| `setup_postgresql` | `PG_VERSION`, `PG_MODULES` | `PG_VERSION="16" setup_postgresql` |
| `setup_postgresql_db` | `PG_DB_NAME`, `PG_DB_USER` | `PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db` |
| `setup_mariadb_db` | `MARIADB_DB_NAME`, `MARIADB_DB_USER` | `MARIADB_DB_NAME="mydb" setup_mariadb_db` |
| `setup_mysql` | `MYSQL_VERSION` | `setup_mysql` |
| `setup_mongodb` | `MONGO_VERSION` | `setup_mongodb` |
| `setup_clickhouse` | - | `setup_clickhouse` |
### Tools & Utilities
| Function | Description |
| ------------------- | ---------------------------------- |
| `setup_adminer` | Installs Adminer for DB management |
| `setup_composer` | Install PHP Composer |
| `setup_ffmpeg` | Install FFmpeg |
| `setup_imagemagick` | Install ImageMagick |
| `setup_gs` | Install Ghostscript |
| `setup_hwaccel` | Configure hardware acceleration |
### Helper Utilities
| Function | Description | Example |
| ----------------------------- | ---------------------------- | ----------------------------------------- |
| `import_local_ip` | Sets `$LOCAL_IP` variable | `import_local_ip` |
| `ensure_dependencies` | Checks/installs dependencies | `ensure_dependencies curl jq` |
| `install_packages_with_retry` | APT install with retry | `install_packages_with_retry nginx redis` |
---
## ❌ Anti-Patterns (NEVER use!)
### 1. Pointless Variables
```bash
# ❌ WRONG - unnecessary variables
APP_NAME="myapp"
APP_DIR="/opt/${APP_NAME}"
APP_USER="root"
APP_PORT="3000"
cd $APP_DIR
# ✅ CORRECT - use directly
cd /opt/myapp
```
### 2. Custom Download Logic
```bash
# ❌ WRONG - custom wget/curl logic
RELEASE=$(curl -s https://api.github.com/repos/YourUsername/YourRepo/releases/latest | jq -r '.tag_name')
wget https://github.com/YourUsername/YourRepo/archive/${RELEASE}.tar.gz
tar -xzf ${RELEASE}.tar.gz
mv repo-${RELEASE} /opt/myapp
# ✅ CORRECT - use our function
fetch_and_deploy_gh_release "myapp" "YourUsername/YourRepo" "tarball" "latest" "/opt/myapp"
```
### 3. Custom Version-Check Logic
```bash
# ❌ WRONG - custom version check
CURRENT=$(cat /opt/myapp/version.txt)
LATEST=$(curl -s https://api.github.com/repos/YourUsername/YourRepo/releases/latest | jq -r '.tag_name')
if [[ "$CURRENT" != "$LATEST" ]]; then
# update...
fi
# ✅ CORRECT - use our function
if check_for_gh_release "myapp" "YourUsername/YourRepo"; then
# update...
fi
```
### 4. Docker-based Installation
```bash
# ❌ WRONG - using Docker
docker pull myapp/myapp:latest
docker run -d --name myapp myapp/myapp:latest
# ✅ CORRECT - Bare-Metal Installation
fetch_and_deploy_gh_release "myapp" "YourUsername/YourRepo"
npm install && npm run build
```
### 5. Custom Runtime Installation
```bash
# ❌ WRONG - custom Node.js installation
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs
# ✅ CORRECT - use our function
NODE_VERSION="22" setup_nodejs
```
### 6. Redundant echo Statements
```bash
# ❌ WRONG - custom logging messages
echo "Installing dependencies..."
apt install -y curl
echo "Done!"
# ✅ CORRECT - use msg_info/msg_ok
msg_info "Installing Dependencies"
$STD apt install -y curl
msg_ok "Installed Dependencies"
```
### 7. Missing $STD Usage
```bash
# ❌ WRONG - apt without $STD
apt install -y nginx
# ✅ CORRECT - with $STD for silent output
$STD apt install -y nginx
```
### 8. Wrapping `tools.func` Functions in msg Blocks
```bash
# ❌ WRONG - tools.func functions have their own msg_info/msg_ok!
msg_info "Installing Node.js"
NODE_VERSION="22" setup_nodejs
msg_ok "Installed Node.js"
msg_info "Updating Application"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
msg_ok "Updated Application"
# ✅ CORRECT - call directly without msg wrapper
NODE_VERSION="22" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
```
**Functions with built-in messages (NEVER wrap in msg blocks):**
- `fetch_and_deploy_gh_release`
- `check_for_gh_release`
- `setup_nodejs`
- `setup_postgresql` / `setup_postgresql_db`
- `setup_mariadb` / `setup_mariadb_db`
- `setup_mongodb`
- `setup_mysql`
- `setup_ruby`
- `setup_go`
- `setup_java`
- `setup_php`
- `setup_uv`
- `setup_rust`
- `setup_composer`
- `setup_ffmpeg`
- `setup_imagemagick`
- `setup_gs`
- `setup_adminer`
- `setup_hwaccel`
### 9. Creating Unnecessary System Users
```bash
# ❌ WRONG - LXC containers run as root, no separate user needed
useradd -m -s /usr/bin/bash appuser
chown -R appuser:appuser /opt/appname
sudo -u appuser npm install
# ✅ CORRECT - run directly as root
cd /opt/appname
$STD npm install
```
### 10. Using `export` in .env Files
```bash
# ❌ WRONG - export is unnecessary in .env files
cat <<EOF >/opt/appname/.env
export DATABASE_URL=postgres://...
export SECRET_KEY=abc123
export NODE_ENV=production
EOF
# ✅ CORRECT - simple KEY=VALUE format (files are sourced with set -a)
cat <<EOF >/opt/appname/.env
DATABASE_URL=postgres://...
SECRET_KEY=abc123
NODE_ENV=production
EOF
```
### 11. Using External Shell Scripts
```bash
# ❌ WRONG - external script that gets executed
cat <<'EOF' >/opt/appname/install_script.sh
#!/bin/bash
cd /opt/appname
npm install
npm run build
EOF
chmod +x /opt/appname/install_script.sh
$STD bash /opt/appname/install_script.sh
rm -f /opt/appname/install_script.sh
# ✅ CORRECT - run commands directly
cd /opt/appname
$STD npm install
$STD npm run build
```
### 12. Using `sudo` in LXC Containers
```bash
# ❌ WRONG - sudo is unnecessary in LXC (already root)
sudo -u postgres psql -c "CREATE DATABASE mydb;"
sudo -u appuser npm install
# ✅ CORRECT - use functions or run directly as root
PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db
cd /opt/appname
$STD npm install
```
### 13. Unnecessary `systemctl daemon-reload`
```bash
# ❌ WRONG - daemon-reload is only needed when MODIFYING existing services
cat <<EOF >/etc/systemd/system/appname.service
# ... service config ...
EOF
systemctl daemon-reload # Unnecessary for new services!
systemctl enable -q --now appname
# ✅ CORRECT - new services don't need daemon-reload
cat <<EOF >/etc/systemd/system/appname.service
# ... service config ...
EOF
systemctl enable -q --now appname
```
### 14. Creating Custom Credentials Files
```bash
# ❌ WRONG - custom credentials file is not part of the standard template
msg_info "Saving Credentials"
cat <<EOF >~/appname.creds
Database User: ${DB_USER}
Database Pass: ${DB_PASS}
EOF
msg_ok "Saved Credentials"
# ✅ CORRECT - credentials are stored in .env or shown in final message only
# If you use setup_postgresql_db / setup_mariadb_db, a standard ~/[appname].creds is created automatically
```
### 15. Wrong Footer Pattern
```bash
# ❌ WRONG - old cleanup pattern with msg blocks
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
# ✅ CORRECT - use cleanup_lxc function
motd_ssh
customize
cleanup_lxc
```
### 16. Manual Database Creation Instead of Functions
```bash
# ❌ WRONG - manual database creation
DB_USER="myuser"
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE mydb WITH OWNER $DB_USER;"
$STD sudo -u postgres psql -d mydb -c "CREATE EXTENSION IF NOT EXISTS postgis;"
# ✅ CORRECT - use setup_postgresql_db function
# This sets PG_DB_USER, PG_DB_PASS, PG_DB_NAME automatically
PG_DB_NAME="mydb" PG_DB_USER="myuser" PG_DB_EXTENSIONS="postgis" setup_postgresql_db
```
### 17. Writing Files Without Heredocs
```bash
# ❌ WRONG - echo / printf / tee
echo "# Config" > /opt/app/config.yml
echo "port: 3000" >> /opt/app/config.yml
printf "# Config\nport: 3000\n" > /opt/app/config.yml
cat config.yml | tee /opt/app/config.yml
```
```bash
# ✅ CORRECT - always use a single heredoc
cat <<EOF >/opt/app/config.yml
# Config
port: 3000
EOF
```
---
## 📝 Important Rules
### Variable Declarations (CT Script)
```bash
# Standard declarations (ALWAYS present)
APP="AppName"
var_tags="${var_tags:-tag1;tag2}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
```
### Update-Script Pattern
```bash
function update_script() {
header_info
check_container_storage
check_container_resources
# 1. Check if installation exists
if [[ ! -d /opt/appname ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
# 2. Check for update
if check_for_gh_release "appname" "YourUsername/YourRepo"; then
# 3. Stop service
msg_info "Stopping Service"
systemctl stop appname
msg_ok "Stopped Service"
# 4. Backup data (if present)
msg_info "Backing up Data"
cp -r /opt/appname/data /opt/appname_data_backup
msg_ok "Backed up Data"
# 5. Perform clean install
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
# 6. Rebuild (if needed)
cd /opt/appname
$STD npm install
$STD npm run build
# 7. Restore data
msg_info "Restoring Data"
cp -r /opt/appname_data_backup/. /opt/appname/data
rm -rf /opt/appname_data_backup
msg_ok "Restored Data"
# 8. Start service
msg_info "Starting Service"
systemctl start appname
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit # IMPORTANT: Always end with exit!
}
```
### Systemd Service Pattern
```bash
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/appname.service
[Unit]
Description=AppName Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/appname
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /opt/appname/server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now appname
msg_ok "Created Service"
```
### Installation Script Footer
```bash
# ALWAYS at the end of the install script:
motd_ssh
customize
cleanup_lxc
```
---
## 📖 Reference: Good Example Scripts
Look at these recent well-implemented applications as reference:
### Container Scripts (Latest 10)
- [ct/thingsboard.sh](../ct/thingsboard.sh) - IoT platform with proper update_script
- [ct/unifi-os-server.sh](../ct/unifi-os-server.sh) - Complex setup with podman
- [ct/trip.sh](../ct/trip.sh) - Simple Ruby app
- [ct/fladder.sh](../ct/fladder.sh) - Media app with database
- [ct/qui.sh](../ct/qui.sh) - Lightweight utility
- [ct/kutt.sh](../ct/kutt.sh) - Node.js with PostgreSQL
- [ct/flatnotes.sh](../ct/flatnotes.sh) - Python notes app
- [ct/investbrain.sh](../ct/investbrain.sh) - Finance app
- [ct/gwn-manager.sh](../ct/gwn-manager.sh) - Network management
- [ct/sportarr.sh](../ct/sportarr.sh) - Specialized \*Arr variant
### Install Scripts (Latest)
- [install/unifi-os-server-install.sh](../install/unifi-os-server-install.sh) - Complex setup with API integration
- [install/trip-install.sh](../install/trip-install.sh) - Rails application setup
- [install/mail-archiver-install.sh](../install/mail-archiver-install.sh) - Email-related service
**Key things to notice:**
- Proper error handling with `catch_errors`
- Use of `check_for_gh_release` and `fetch_and_deploy_gh_release`
- Correct backup/restore patterns in `update_script`
- Footer always ends with `motd_ssh`, `customize`, `cleanup_lxc`
- JSON metadata files created for each app
---
## <20> JSON Metadata Files
Every application requires a JSON metadata file in `frontend/public/json/<appname>.json`.
### JSON Structure
```json
{
"name": "AppName",
"slug": "appname",
"categories": [1],
"date_created": "2026-01-16",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://docs.appname.com/",
"website": "https://appname.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/appname.webp",
"config_path": "/opt/appname/.env",
"description": "Short description of the application and its purpose.",
"install_methods": [
{
"type": "default",
"script": "ct/appname.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}
```
### Required Fields
| Field | Type | Description |
| --------------------- | ------- | -------------------------------------------------- |
| `name` | string | Display name of the application |
| `slug` | string | Lowercase, no spaces, used for filenames |
| `categories` | array | Category ID(s) - see category list below |
| `date_created` | string | Creation date (YYYY-MM-DD) |
| `type` | string | `ct` for container, `vm` for virtual machine |
| `updateable` | boolean | Whether update_script is implemented |
| `privileged` | boolean | Whether container needs privileged mode |
| `interface_port` | number | Primary web interface port (or `null`) |
| `documentation` | string | Link to official docs |
| `website` | string | Link to official website |
| `logo` | string | URL to application logo (preferably selfhst icons) |
| `config_path` | string | Path to main config file (or empty string) |
| `description` | string | Brief description of the application |
| `install_methods` | array | Installation configurations |
| `default_credentials` | object | Default username/password (or null) |
| `notes` | array | Additional notes/warnings |
### Categories
| ID | Category |
| --- | ------------------------- |
| 0 | Miscellaneous |
| 1 | Proxmox & Virtualization |
| 2 | Operating Systems |
| 3 | Containers & Docker |
| 4 | Network & Firewall |
| 5 | Adblock & DNS |
| 6 | Authentication & Security |
| 7 | Backup & Recovery |
| 8 | Databases |
| 9 | Monitoring & Analytics |
| 10 | Dashboards & Frontends |
| 11 | Files & Downloads |
| 12 | Documents & Notes |
| 13 | Media & Streaming |
| 14 | \*Arr Suite |
| 15 | NVR & Cameras |
| 16 | IoT & Smart Home |
| 17 | ZigBee, Z-Wave & Matter |
| 18 | MQTT & Messaging |
| 19 | Automation & Scheduling |
| 20 | AI / Coding & Dev-Tools |
| 21 | Webservers & Proxies |
| 22 | Bots & ChatOps |
| 23 | Finance & Budgeting |
| 24 | Gaming & Leisure |
| 25 | Business & ERP |
### Notes Format
```json
"notes": [
{
"text": "Change the default password after first login!",
"type": "warning"
},
{
"text": "Requires at least 4GB RAM for optimal performance.",
"type": "info"
}
]
```
**Note types:** `info`, `warning`, `error`
### Examples with Credentials
```json
"default_credentials": {
"username": "admin",
"password": "admin"
}
```
Or no credentials:
```json
"default_credentials": {
"username": null,
"password": null
}
```
---
## 🔍 Checklist Before PR Creation
- [ ] No Docker installation used
- [ ] `fetch_and_deploy_gh_release` used for GitHub releases
- [ ] `check_for_gh_release` used for update checks
- [ ] `setup_*` functions used for runtimes (nodejs, postgresql, etc.)
- [ ] **`tools.func` functions NOT wrapped in msg_info/msg_ok blocks**
- [ ] No redundant variables (only when used multiple times)
- [ ] `$STD` before all apt/npm/build commands
- [ ] `msg_info`/`msg_ok`/`msg_error` for logging (only for custom code)
- [ ] Correct script structure followed (see templates)
- [ ] Update function present and functional (CT scripts)
- [ ] Data backup implemented in update function (if applicable)
- [ ] `motd_ssh`, `customize`, `cleanup_lxc` at the end of install scripts
- [ ] No custom download/version-check logic
- [ ] All links point to `community-scripts/ProxmoxVE` (not `ProxmoxVED`!)
- [ ] JSON metadata file created in `frontend/public/json/<appname>.json`
- [ ] Category IDs are valid (0-25)
- [ ] Default OS version is Debian 13 or newer (unless special requirement)
- [ ] Default resources are reasonable for the application
---
## 💡 Tips for AI Assistants
1. **ALWAYS search `tools.func` first** before implementing custom solutions
2. **Use recent scripts as reference** (Thingsboard, UniFi OS, Trip, Flatnotes, etc.)
3. **Ask when uncertain** instead of introducing wrong patterns
4. **Test via GitHub** - push to your fork and test with curl (not local bash)
```bash
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
# Wait 10-30 seconds after pushing - GitHub takes time to update files
```
5. **Consistency > Creativity** - follow established patterns strictly
6. **Check the templates** - they show the correct structure
7. **Don't wrap tools.func functions** - they handle their own msg_info/msg_ok output
8. **Minimal variables** - only create variables that are truly reused multiple times
9. **Always use $STD** - ensures silent/non-interactive execution
10. **Reference good examples** - look at recent additions in each category
---
## 🍒 Important: Cherry-Picking Your Files for PR Submission
⚠️ **CRITICAL**: When you submit your PR, you must use git cherry-pick to send ONLY your 3-4 files!
Why? Because `setup-fork.sh` modifies 600+ files to update links. If you commit all changes, your PR will be impossible to merge.
**See**: [README.md - Cherry-Pick Section](README.md#-cherry-pick-submitting-only-your-changes) for complete instructions on:
- Creating a clean submission branch
- Cherry-picking only your files (ct/myapp.sh, install/myapp-install.sh, frontend/public/json/myapp.json)
- Verifying your PR has only 3 file changes (not 600+)
**Quick reference**:
```bash
# Create clean branch from upstream
git fetch upstream
git checkout -b submit/myapp upstream/main
# Cherry-pick your commit(s) or manually add your 3-4 files
# Then push to your fork and create PR
```
---
## 📚 Further Documentation
- [CONTRIBUTING.md](CONTRIBUTING.md) - General contribution guidelines
- [GUIDE.md](GUIDE.md) - Detailed developer documentation
- [HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md) - Complete tools.func reference
- [README.md](README.md) - Cherry-pick guide and workflow instructions
- [../TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md) - Technical deep dive
- [../EXIT_CODES.md](../EXIT_CODES.md) - Exit code reference
- [templates_ct/](templates_ct/) - CT script templates
- [templates_install/](templates_install/) - Install script templates
- [templates_json/](templates_json/) - JSON metadata templates

View File

@@ -1,41 +1,14 @@
# 🧪 Code Audit: LXC Script Flow <div align="center">
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo.png" height="100px" />
</div>
<h2><div align="center">Exploring the Scripts and Steps Involved in an Application LXC Installation</div></h2>
This guide explains the current execution flow and what to verify during reviews. 1) [adguard.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/adguard.sh): This script collects system parameters. (Also holds the function to update the application.)
2) [build.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/build.func): Adds user settings and integrates collected information.
3) [create_lxc.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/create_lxc.sh): Constructs the LXC container.
4) [adguard-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/install.func), and installs the application.
5) [adguard.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/adguard.sh) (again): To display the completion message.
## Execution Flow (CT + Install) The installation process uses reusable scripts: [build.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/build.func), [create_lxc.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/create_lxc.sh), and [install.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/install.func), which are not specific to any particular application.
1. `ct/appname.sh` runs on the Proxmox host and sources `misc/build.func`. To gain a better understanding, focus on reviewing [adguard-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/install/adguard-install.sh). This script contains the commands and configurations for installing and configuring AdGuard Home within the LXC container.
2. `build.func` orchestrates prompts, container creation, and invokes the install script.
3. Inside the container, `misc/install.func` exposes helper functions via `$FUNCTIONS_FILE_PATH`.
4. `install/appname-install.sh` performs the application install.
5. The CT script prints the completion message.
## Audit Checklist
### CT Script (ct/)
- Sources `misc/build.func` from `community-scripts/ProxmoxVE/main` (setup-fork.sh updates for forks).
- Uses `check_for_gh_release` + `fetch_and_deploy_gh_release` for updates.
- No Docker-based installs.
### Install Script (install/)
- Sources `$FUNCTIONS_FILE_PATH`.
- Uses `tools.func` helpers (setup\_\*).
- Ends with `motd_ssh`, `customize`, `cleanup_lxc`.
### JSON Metadata
- File in `frontend/public/json/<appname>.json` matches template schema.
### Testing
- Test via curl from your fork (CT script only).
- Wait 10-30 seconds after push.
## References
- `docs/contribution/templates_ct/AppName.sh`
- `docs/contribution/templates_install/AppName-install.sh`
- `docs/contribution/templates_json/AppName.json`
- `docs/contribution/GUIDE.md`

View File

@@ -81,22 +81,11 @@ git clone https://github.com/yourUserName/ForkName
git switch -c your-feature-branch git switch -c your-feature-branch
``` ```
### 4. Run setup-fork.sh to auto-configure your fork ### 4. Change paths in build.func install.func and AppName.sh
```bash To be able to develop from your own branch you need to change `https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main` to `https://raw.githubusercontent.com/[USER]/[REPOSITORY]/refs/heads/[BRANCH]`. You need to make this change atleast in misc/build.func misc/install.func and in your ct/AppName.sh. This change is only for testing. Before opening a Pull Request you should change this line change all this back to point to `https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main`.
bash docs/contribution/setup-fork.sh --full
```
This script automatically: ### 4. Commit changes (without build.func and install.func!)
- Detects your GitHub username
- Updates ALL curl URLs to point to your fork (for testing)
- Creates `.git-setup-info` with your config
- Backs up all modified files (\*.backup)
**IMPORTANT**: This modifies 600+ files! Use cherry-pick when submitting your PR (see below).
### 5. Commit ONLY your new application files
```bash ```bash
git commit -m "Your commit message" git commit -m "Your commit message"
@@ -108,42 +97,9 @@ git commit -m "Your commit message"
git push origin your-feature-branch git push origin your-feature-branch
``` ```
### 6. Cherry-Pick: Submit Only Your Files for PR ### 6. Create a Pull Request
⚠️ **IMPORTANT**: setup-fork.sh modified 600+ files. You MUST only submit your 3 new files! Open a Pull Request from your feature branch to the main repository branch. You must only include your **$AppName.sh**, **$AppName-install.sh** and **$AppName.json** files in the pull request.
See [README.md - Cherry-Pick Guide](README.md#-cherry-pick-submitting-only-your-changes) for step-by-step instructions.
Quick version:
```bash
# Create clean branch from upstream
git fetch upstream
git checkout -b submit/myapp upstream/main
# Copy only your files
cp ../your-work-branch/ct/myapp.sh ct/myapp.sh
cp ../your-work-branch/install/myapp-install.sh install/myapp-install.sh
cp ../your-work-branch/frontend/public/json/myapp.json frontend/public/json/myapp.json
# Commit and verify
git add ct/myapp.sh install/myapp-install.sh frontend/public/json/myapp.json
git commit -m "feat: add MyApp"
git diff upstream/main --name-only # Should show ONLY your 3 files
# Push and create PR
git push origin submit/myapp
```
### 7. Create a Pull Request
Open a Pull Request from `submit/myapp``community-scripts/ProxmoxVE/main`.
Verify the PR shows ONLY these 3 files:
- `ct/myapp.sh`
- `install/myapp-install.sh`
- `frontend/public/json/myapp.json`
--- ---

View File

@@ -10,7 +10,7 @@ git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
cd ProxmoxVE cd ProxmoxVE
# Run setup script (auto-detects your username from git) # Run setup script (auto-detects your username from git)
bash docs/contribution/setup-fork.sh --full bash setup-fork.sh
``` ```
That's it! ✅ That's it! ✅
@@ -22,101 +22,64 @@ That's it! ✅
The `setup-fork.sh` script automatically: The `setup-fork.sh` script automatically:
1. **Detects** your GitHub username from git config 1. **Detects** your GitHub username from git config
2. **Updates ALL hardcoded links** to point to your fork: 2. **Updates** 22 hardcoded links in documentation to point to your fork
- Documentation links pointing to `community-scripts/ProxmoxVE` 3. **Creates** `.git-setup-info` with recommended git workflows
- **Curl download URLs** in scripts (e.g., `curl ... github.com/community-scripts/ProxmoxVE/main/...`) 4. **Backs up** all modified files (*.backup)
3. **Creates** `.git-setup-info` with your configuration details
4. **Backs up** all modified files (\*.backup for safety)
### Why Updating Curl Links Matters
Your scripts contain `curl` commands that download dependencies from GitHub (build.func, tools.func, etc.):
```bash
# First line of ct/myapp.sh
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
```
**WITHOUT setup-fork.sh:**
- Script URLs still point to `community-scripts/ProxmoxVE/main`
- If you test locally with `bash ct/myapp.sh`, you're testing local files, but the script's curl commands would download from **upstream** repo
- Your modifications aren't actually being tested via the curl commands! ❌
**AFTER setup-fork.sh:**
- Script URLs are updated to `YourUsername/ProxmoxVE/main`
- When you test via curl from GitHub: `bash -c "$(curl ... YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"`, it downloads from **your fork**
- The script's curl commands also point to your fork, so you're actually testing your changes! ✅
- ⏱️ **Important:** GitHub takes 10-30 seconds to recognize pushed files - wait before testing!
```bash
# Example: What setup-fork.sh changes
# BEFORE (points to upstream):
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# AFTER (points to your fork):
source <(curl -fsSL https://raw.githubusercontent.com/john/ProxmoxVE/main/misc/build.func)
```
--- ---
## Usage ## Usage
### Auto-Detect (Recommended) ### Auto-Detect (Recommended)
```bash ```bash
bash docs/contribution/setup-fork.sh --full bash setup-fork.sh
``` ```
Automatically reads your GitHub username from `git remote origin url` Automatically reads your GitHub username from `git remote origin url`
### Specify Username ### Specify Username
```bash ```bash
bash docs/contribution/setup-fork.sh --full john bash setup-fork.sh john
``` ```
Updates links to `github.com/john/ProxmoxVE` Updates links to `github.com/john/ProxmoxVE`
### Custom Repository Name ### Custom Repository Name
```bash ```bash
bash docs/contribution/setup-fork.sh --full john my-fork bash setup-fork.sh john my-fork
``` ```
Updates links to `github.com/john/my-fork` Updates links to `github.com/john/my-fork`
--- ---
## What Gets Updated? ## What Gets Updated?
The script updates hardcoded links in these areas when using `--full`: The script updates these documentation files:
- `docs/CONTRIBUTION_GUIDE.md` (4 links)
- `ct/`, `install/`, `vm/` scripts - `docs/README.md` (1 link)
- `misc/` function libraries - `docs/INDEX.md` (3 links)
- `docs/` (including `docs/contribution/`) - `docs/EXIT_CODES.md` (2 links)
- Code examples in documentation - `docs/DEFAULTS_SYSTEM_GUIDE.md` (2 links)
- `docs/api/README.md` (1 link)
- `docs/APP-ct.md` (1 link)
- `docs/APP-install.md` (1 link)
- `docs/alpine-install.func.md` (2 links)
- `docs/install.func.md` (1 link)
- And code examples in documentation
--- ---
## After Setup ## After Setup
1. **Review changes** 1. **Review changes**
```bash ```bash
git diff docs/ git diff docs/
``` ```
2. **Read git workflow tips** 2. **Read git workflow tips**
```bash ```bash
cat .git-setup-info cat .git-setup-info
``` ```
3. **Start contributing** 3. **Start contributing**
```bash ```bash
git checkout -b feature/my-app git checkout -b feature/my-app
# Make your changes... # Make your changes...
@@ -125,7 +88,7 @@ The script updates hardcoded links in these areas when using `--full`:
4. **Follow the guide** 4. **Follow the guide**
```bash ```bash
cat docs/contribution/GUIDE.md cat docs/CONTRIBUTION_GUIDE.md
``` ```
--- ---
@@ -133,7 +96,6 @@ The script updates hardcoded links in these areas when using `--full`:
## Common Workflows ## Common Workflows
### Keep Your Fork Updated ### Keep Your Fork Updated
```bash ```bash
# Add upstream if you haven't already # Add upstream if you haven't already
git remote add upstream https://github.com/community-scripts/ProxmoxVE.git git remote add upstream https://github.com/community-scripts/ProxmoxVE.git
@@ -145,7 +107,6 @@ git push origin main
``` ```
### Create a Feature Branch ### Create a Feature Branch
```bash ```bash
git checkout -b feature/docker-improvements git checkout -b feature/docker-improvements
# Make changes... # Make changes...
@@ -154,7 +115,6 @@ git push origin feature/docker-improvements
``` ```
### Sync Before Contributing ### Sync Before Contributing
```bash ```bash
git fetch upstream git fetch upstream
git rebase upstream/main git rebase upstream/main
@@ -167,16 +127,14 @@ git checkout -b feature/my-feature
## Troubleshooting ## Troubleshooting
### "Git is not installed" or "not a git repository" ### "Git is not installed" or "not a git repository"
```bash ```bash
# Make sure you cloned the repo first # Make sure you cloned the repo first
git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
cd ProxmoxVE cd ProxmoxVE
bash docs/contribution/setup-fork.sh --full bash setup-fork.sh
``` ```
### "Could not auto-detect GitHub username" ### "Could not auto-detect GitHub username"
```bash ```bash
# Your git origin URL isn't set up correctly # Your git origin URL isn't set up correctly
git remote -v git remote -v
@@ -184,32 +142,29 @@ git remote -v
# Fix it: # Fix it:
git remote set-url origin https://github.com/YOUR_USERNAME/ProxmoxVE.git git remote set-url origin https://github.com/YOUR_USERNAME/ProxmoxVE.git
bash docs/contribution/setup-fork.sh --full bash setup-fork.sh
``` ```
### "Permission denied" ### "Permission denied"
```bash ```bash
# Make script executable # Make script executable
chmod +x docs/contribution/setup-fork.sh chmod +x setup-fork.sh
bash docs/contribution/setup-fork.sh --full bash setup-fork.sh
``` ```
### Reverted Changes by Accident? ### Reverted Changes by Accident?
```bash ```bash
# Backups are created automatically # Backups are created automatically
git checkout docs/*.backup git checkout docs/*.backup
# Or just re-run setup-fork.sh # Or just re-run setup-fork.sh
bash docs/contribution/setup-fork.sh --full
``` ```
--- ---
## Next Steps ## Next Steps
1. ✅ Run `bash docs/contribution/setup-fork.sh --full` 1. ✅ Run `bash setup-fork.sh`
2. 📖 Read [docs/contribution/GUIDE.md](GUIDE.md) 2. 📖 Read [docs/CONTRIBUTION_GUIDE.md](docs/CONTRIBUTION_GUIDE.md)
3. 🍴 Choose your contribution path: 3. 🍴 Choose your contribution path:
- **Containers** → [docs/ct/README.md](docs/ct/README.md) - **Containers** → [docs/ct/README.md](docs/ct/README.md)
- **Installation** → [docs/install/README.md](docs/install/README.md) - **Installation** → [docs/install/README.md](docs/install/README.md)
@@ -222,10 +177,10 @@ bash docs/contribution/setup-fork.sh --full
## Questions? ## Questions?
- **Fork Setup Issues?** → See [Troubleshooting](#troubleshooting) above - **Fork Setup Issues?** → See [Troubleshooting](#troubleshooting) above
- **How to Contribute?** → [docs/contribution/GUIDE.md](GUIDE.md) - **How to Contribute?** → [docs/CONTRIBUTION_GUIDE.md](docs/CONTRIBUTION_GUIDE.md)
- **Git Workflows?** → `cat .git-setup-info` - **Git Workflows?** → `cat .git-setup-info`
- **Project Structure?** → [docs/README.md](docs/README.md) - **Project Structure?** → [docs/README.md](docs/README.md)
--- ---
## Happy Contributing! 🚀 **Happy Contributing! 🚀**

View File

@@ -38,8 +38,8 @@ git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
cd ProxmoxVE cd ProxmoxVE
# 3. Run fork setup script (automatically configures everything) # 3. Run fork setup script (automatically configures everything)
bash docs/contribution/setup-fork.sh --full bash setup-fork.sh
# --full updates ct/, install/, vm/, docs/, misc/ links for fork testing # This auto-detects your username and updates all documentation links
# 4. Read the git workflow tips # 4. Read the git workflow tips
cat .git-setup-info cat .git-setup-info
@@ -51,29 +51,28 @@ cat .git-setup-info
# 1. Create feature branch # 1. Create feature branch
git checkout -b add/my-awesome-app git checkout -b add/my-awesome-app
# 2. Create application scripts from templates # 2. Create application scripts
cp docs/contribution/templates_ct/AppName.sh ct/myapp.sh cp ct/example.sh ct/myapp.sh
cp docs/contribution/templates_install/AppName-install.sh install/myapp-install.sh cp install/example-install.sh install/myapp-install.sh
cp docs/contribution/templates_json/AppName.json frontend/public/json/myapp.json
# 3. Edit your scripts # 3. Edit your scripts
nano ct/myapp.sh nano ct/myapp.sh
nano install/myapp-install.sh nano install/myapp-install.sh
nano frontend/public/json/myapp.json
# 4. Commit and push to your fork # 4. Test locally
git add ct/myapp.sh install/myapp-install.sh frontend/public/json/myapp.json bash ct/myapp.sh # Will prompt for container creation
git commit -m "feat: add MyApp container and install scripts"
# 5. Commit and push
git add ct/myapp.sh install/myapp-install.sh
git commit -m "feat: add MyApp container"
git push origin add/my-awesome-app git push origin add/my-awesome-app
# 5. Test via curl from your fork (GitHub may take 10-30 seconds) # 6. Open Pull Request on GitHub
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" # Click: New Pull Request (GitHub will show this automatically)
# 6. Use cherry-pick to submit only your files (see Cherry-Pick section) # 7. Keep your fork updated
# DO NOT submit the 600+ files modified by setup-fork.sh! git fetch upstream
git rebase upstream/main
# 7. Open Pull Request on GitHub
# Create PR from: your-fork/add/my-awesome-app → community-scripts/ProxmoxVE/main
``` ```
**💡 Tip**: See `../FORK_SETUP.md` for detailed fork setup and troubleshooting **💡 Tip**: See `../FORK_SETUP.md` for detailed fork setup and troubleshooting
@@ -113,9 +112,9 @@ ProxmoxVE/
│ └── alpine-tools.func # Alpine tools │ └── alpine-tools.func # Alpine tools
├── docs/ # 📚 Documentation ├── docs/ # 📚 Documentation
│ ├── ct/DETAILED_GUIDE.md # Container script guide │ ├── UPDATED_APP-ct.md # Container script guide
│ ├── install/DETAILED_GUIDE.md # Install script guide │ ├── UPDATED_APP-install.md # Install script guide
│ └── contribution/README.md # Contribution overview │ └── CONTRIBUTING.md # (This file!)
├── tools/ # 🔧 Proxmox management tools ├── tools/ # 🔧 Proxmox management tools
│ └── pve/ │ └── pve/
@@ -138,7 +137,6 @@ Examples:
``` ```
**Rules**: **Rules**:
- Container script name: **Title Case** (PiHole, Docker, NextCloud) - Container script name: **Title Case** (PiHole, Docker, NextCloud)
- Install script name: **lowercase** with **hyphens** (pihole-install, docker-install) - Install script name: **lowercase** with **hyphens** (pihole-install, docker-install)
- Must match: `ct/AppName.sh``install/appname-install.sh` - Must match: `ct/AppName.sh``install/appname-install.sh`
@@ -158,7 +156,6 @@ Examples:
- Ubuntu 20.04 / Debian 11+ on host - Ubuntu 20.04 / Debian 11+ on host
2. **Git** installed 2. **Git** installed
```bash ```bash
apt-get install -y git apt-get install -y git
``` ```
@@ -201,33 +198,32 @@ git rebase upstream/main
git push origin feat/add-myapp git push origin feat/add-myapp
``` ```
#### Option B: Testing on a Proxmox Host (still via curl) #### Option B: Local Testing on Proxmox Host
```bash ```bash
# 1. SSH into Proxmox host # 1. SSH into Proxmox host
ssh root@192.168.1.100 ssh root@192.168.1.100
# 2. Test via curl from your fork (CT script only) # 2. Download your script
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" curl -O https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/ct/myapp.sh
# ⏱️ Wait 10-30 seconds after pushing - GitHub takes time to update
# 3. Make it executable
chmod +x myapp.sh
# 4. Update URLs to your fork
# Edit: curl -s https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/...
# 5. Run and test
bash myapp.sh
# 6. If container created successfully, script is working!
``` ```
> **Note:** Do not edit URLs manually or run install scripts directly. The CT script calls the install script inside the container. #### Option C: Docker Testing (Without Proxmox)
#### Option C: Using Curl (Recommended for Real Testing)
```bash ```bash
# Always test via curl from your fork (GitHub takes 10-30 seconds after push) # You can test script syntax/functionality locally
git push origin feature/myapp # Note: Won't fully test (no Proxmox, no actual container)
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
# This tests the actual GitHub URLs, not local files
```
#### Option D: Static Checks (Without Proxmox)
```bash
# You can validate syntax and linting locally (limited)
# Note: This does NOT replace real Proxmox testing
# Run ShellCheck # Run ShellCheck
shellcheck ct/myapp.sh shellcheck ct/myapp.sh
@@ -245,18 +241,18 @@ bash -n install/myapp-install.sh
### Step 1: Choose Your Template ### Step 1: Choose Your Template
**For Simple Web Apps** (Node.js, Python, PHP): **For Simple Web Apps** (Node.js, Python, PHP):
```bash ```bash
cp ct/example.sh ct/myapp.sh cp ct/example.sh ct/myapp.sh
cp install/example-install.sh install/myapp-install.sh cp install/example-install.sh install/myapp-install.sh
``` ```
**For Database Apps** (PostgreSQL, MariaDB, MongoDB): **For Database Apps** (PostgreSQL, MongoDB):
```bash
Use the standard templates and the database helpers from `tools.func` (no Docker). cp ct/docker.sh ct/myapp.sh # Use Docker container
# OR manual setup for more control
```
**For Alpine Linux Apps** (lightweight): **For Alpine Linux Apps** (lightweight):
```bash ```bash
# Use ct/alpine.sh as reference # Use ct/alpine.sh as reference
# Edit install script to use Alpine packages (apk not apt) # Edit install script to use Alpine packages (apk not apt)
@@ -268,7 +264,7 @@ Use the standard templates and the database helpers from `tools.func` (no Docker
```bash ```bash
#!/usr/bin/env bash #!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/misc/build.func) source <(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/misc/build.func)
# Update these: # Update these:
APP="MyAwesomeApp" # Display name APP="MyAwesomeApp" # Display name
@@ -295,19 +291,17 @@ function update_script() {
exit exit
fi fi
if check_for_gh_release "myapp" "owner/repo"; then # Get latest version
msg_info "Stopping Service" RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
systemctl stop myapp grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
msg_ok "Stopped Service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "myapp" "owner/repo" "tarball" "latest" "/opt/myapp" if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Updating ${APP} to v${RELEASE}"
# ... update logic (migrations, rebuilds, etc.) ... # ... update logic ...
echo "${RELEASE}" > /opt/${APP}_version.txt
msg_info "Starting Service" msg_ok "Updated ${APP}"
systemctl start myapp else
msg_ok "Started Service" msg_ok "No update required. ${APP} is already at v${RELEASE}."
msg_ok "Updated successfully!"
fi fi
exit exit
} }
@@ -323,7 +317,6 @@ echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:PORT${CL}"
``` ```
**Checklist**: **Checklist**:
- [ ] APP variable matches filename - [ ] APP variable matches filename
- [ ] var_tags semicolon-separated (no spaces) - [ ] var_tags semicolon-separated (no spaces)
- [ ] Realistic CPU/RAM/disk values - [ ] Realistic CPU/RAM/disk values
@@ -352,12 +345,24 @@ update_os
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt-get install -y \ $STD apt-get install -y \
curl \
wget \
git \
build-essential build-essential
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
msg_info "Setting up Node.js"
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
msg_ok "Node.js installed"
fetch_and_deploy_gh_release "myapp" "owner/repo" "tarball" "latest" "/opt/myapp" msg_info "Downloading Application"
cd /opt
wget -q "https://github.com/user/repo/releases/download/v1.0.0/myapp.tar.gz"
tar -xzf myapp.tar.gz
rm -f myapp.tar.gz
msg_ok "Application installed"
echo "1.0.0" > /opt/${APP}_version.txt
motd_ssh motd_ssh
customize customize
@@ -365,7 +370,6 @@ cleanup_lxc
``` ```
**Checklist**: **Checklist**:
- [ ] Functions loaded from `$FUNCTIONS_FILE_PATH` - [ ] Functions loaded from `$FUNCTIONS_FILE_PATH`
- [ ] All installation phases present (deps, tools, app, config, cleanup) - [ ] All installation phases present (deps, tools, app, config, cleanup)
- [ ] Using `$STD` for output suppression - [ ] Using `$STD` for output suppression
@@ -652,19 +656,27 @@ shellcheck install/myapp-install.sh
# 1. SSH into Proxmox host # 1. SSH into Proxmox host
ssh root@YOUR_PROXMOX_IP ssh root@YOUR_PROXMOX_IP
# 2. Test via curl from your fork (CT script only) # 2. Download your script
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" curl -O https://raw.githubusercontent.com/YOUR_USER/ProxmoxVE/feat/myapp/ct/myapp.sh
# ⏱️ Wait 10-30 seconds after pushing - GitHub takes time to update
# 3. Test interaction: # 3. Make executable
chmod +x myapp.sh
# 4. UPDATE URLS IN SCRIPT to point to your fork
sed -i 's|community-scripts|YOUR_USER|g' myapp.sh
# 5. Run script
bash myapp.sh
# 6. Test interaction:
# - Select installation mode # - Select installation mode
# - Confirm settings # - Confirm settings
# - Monitor installation # - Monitor installation
# 4. Verify container created # 7. Verify container created
pct list | grep myapp pct list | grep myapp
# 5. Log into container and verify app # 8. Log into container and verify app
pct exec 100 bash pct exec 100 bash
``` ```
@@ -685,9 +697,9 @@ pct exec 100 bash
# Verify script handles gracefully # Verify script handles gracefully
# Test 4: Update function # Test 4: Update function
# Create initial container (via curl from fork) # Create initial container
# Wait for new release # Wait for new release
# Test update: bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" # Run update: bash ct/myapp.sh
# Verify it detects and applies update # Verify it detects and applies update
``` ```
@@ -762,19 +774,16 @@ Use this template:
```markdown ```markdown
## Description ## Description
Brief description of what this PR adds/fixes Brief description of what this PR adds/fixes
## Type of Change ## Type of Change
- [ ] New application (ct/AppName.sh + install/appname-install.sh) - [ ] New application (ct/AppName.sh + install/appname-install.sh)
- [ ] Update existing application - [ ] Update existing application
- [ ] Bug fix - [ ] Bug fix
- [ ] Documentation update - [ ] Documentation update
- [ ] Other: **\_\_\_** - [ ] Other: _______
## Testing ## Testing
- [ ] Tested on Proxmox VE 8.x - [ ] Tested on Proxmox VE 8.x
- [ ] Container creation successful - [ ] Container creation successful
- [ ] Application installation successful - [ ] Application installation successful
@@ -783,7 +792,6 @@ Brief description of what this PR adds/fixes
- [ ] No temporary files left after installation - [ ] No temporary files left after installation
## Application Details (for new apps only) ## Application Details (for new apps only)
- **App Name**: MyApp - **App Name**: MyApp
- **Source**: https://github.com/app/repo - **Source**: https://github.com/app/repo
- **Default OS**: Debian 12 - **Default OS**: Debian 12
@@ -792,11 +800,9 @@ Brief description of what this PR adds/fixes
- **Access URL**: http://IP:PORT/path - **Access URL**: http://IP:PORT/path
## Checklist ## Checklist
- [ ] My code follows the style guidelines - [ ] My code follows the style guidelines
- [ ] I have performed a self-review - [ ] I have performed a self-review
- [ ] I have tested the script via curl from my fork (after git push) - [ ] I have tested the script locally
- [ ] GitHub had time to update (waited 10-30 seconds)
- [ ] ShellCheck shows no critical warnings - [ ] ShellCheck shows no critical warnings
- [ ] Documentation is accurate and complete - [ ] Documentation is accurate and complete
- [ ] I have added/updated relevant documentation - [ ] I have added/updated relevant documentation
@@ -805,7 +811,6 @@ Brief description of what this PR adds/fixes
### Step 5: Respond to Review Comments ### Step 5: Respond to Review Comments
**Maintainers may request changes**: **Maintainers may request changes**:
- Fix syntax/style issues - Fix syntax/style issues
- Add better error handling - Add better error handling
- Optimize resource usage - Optimize resource usage
@@ -917,7 +922,6 @@ pct exec CTID netstat -tlnp | grep LISTEN
### Q: Can I test without a Proxmox system? ### Q: Can I test without a Proxmox system?
**A**: Partially. You can verify syntax and ShellCheck compliance locally, but real container testing requires Proxmox. Consider using: **A**: Partially. You can verify syntax and ShellCheck compliance locally, but real container testing requires Proxmox. Consider using:
- Proxmox in a VM (VirtualBox/KVM) - Proxmox in a VM (VirtualBox/KVM)
- Test instances on Hetzner/DigitalOcean - Test instances on Hetzner/DigitalOcean
- Ask maintainers to test for you - Ask maintainers to test for you
@@ -925,7 +929,6 @@ pct exec CTID netstat -tlnp | grep LISTEN
### Q: My update function is very complex - is that OK? ### Q: My update function is very complex - is that OK?
**A**: Yes! Update functions can be complex if needed. Just ensure: **A**: Yes! Update functions can be complex if needed. Just ensure:
- Backup user data before updating - Backup user data before updating
- Restore user data after update - Restore user data after update
- Test thoroughly before submitting - Test thoroughly before submitting
@@ -934,7 +937,6 @@ pct exec CTID netstat -tlnp | grep LISTEN
### Q: Can I add new dependencies to build.func? ### Q: Can I add new dependencies to build.func?
**A**: Generally no. build.func is the orchestrator and should remain stable. New functions should go in: **A**: Generally no. build.func is the orchestrator and should remain stable. New functions should go in:
- `tools.func` - Tool installation - `tools.func` - Tool installation
- `core.func` - Utility functions - `core.func` - Utility functions
- `install.func` - Container setup - `install.func` - Container setup
@@ -946,13 +948,11 @@ Ask in an issue first if you're unsure.
**A**: You have options: **A**: You have options:
**Option 1**: Use Advanced mode (19-step wizard) **Option 1**: Use Advanced mode (19-step wizard)
```bash ```bash
# Extend advanced_settings() if app needs special vars # Extend advanced_settings() if app needs special vars
``` ```
**Option 2**: Create custom setup menu **Option 2**: Create custom setup menu
```bash ```bash
function custom_config() { function custom_config() {
OPTION=$(whiptail --inputbox "Enter database name:" 8 60) OPTION=$(whiptail --inputbox "Enter database name:" 8 60)
@@ -961,7 +961,6 @@ function custom_config() {
``` ```
**Option 3**: Leave as defaults + documentation **Option 3**: Leave as defaults + documentation
```bash ```bash
# In success message: # In success message:
echo "Edit /opt/myapp/config.json to customize settings" echo "Edit /opt/myapp/config.json to customize settings"
@@ -970,10 +969,9 @@ echo "Edit /opt/myapp/config.json to customize settings"
### Q: Can I contribute Windows/macOS/ARM support? ### Q: Can I contribute Windows/macOS/ARM support?
**A**: **A**:
- **Windows**: Not planned (ProxmoxVE is Linux/Proxmox focused) - **Windows**: Not planned (ProxmoxVE is Linux/Proxmox focused)
- **macOS**: Can contribute Docker-based alternatives - **macOS**: Can contribute Docker-based alternatives
- **ARM**: Yes! Many apps work on ARM. Add to vm/pimox-\*.sh scripts - **ARM**: Yes! Many apps work on ARM. Add to vm/pimox-*.sh scripts
--- ---
@@ -997,7 +995,6 @@ echo "Edit /opt/myapp/config.json to customize settings"
### Report Bugs ### Report Bugs
When reporting bugs, include: When reporting bugs, include:
- Which application - Which application
- What happened (error message) - What happened (error message)
- What you expected - What you expected
@@ -1005,7 +1002,6 @@ When reporting bugs, include:
- Container OS and version - Container OS and version
Example: Example:
``` ```
Title: pihole-install.sh fails on Alpine 3.20 Title: pihole-install.sh fails on Alpine 3.20
@@ -1029,7 +1025,6 @@ Error Output:
## Contribution Statistics ## Contribution Statistics
**ProxmoxVE by the Numbers**: **ProxmoxVE by the Numbers**:
- 🎯 40+ applications supported - 🎯 40+ applications supported
- 👥 100+ contributors - 👥 100+ contributors
- 📊 10,000+ GitHub stars - 📊 10,000+ GitHub stars
@@ -1043,7 +1038,6 @@ Error Output:
## Code of Conduct ## Code of Conduct
By contributing, you agree to: By contributing, you agree to:
- ✅ Be respectful and inclusive - ✅ Be respectful and inclusive
- ✅ Follow the style guidelines - ✅ Follow the style guidelines
- ✅ Test your changes thoroughly - ✅ Test your changes thoroughly

View File

@@ -30,8 +30,6 @@
> ⚠️ **Both files are ALWAYS required!** The CT script calls the install script automatically during container creation. > ⚠️ **Both files are ALWAYS required!** The CT script calls the install script automatically during container creation.
Install scripts are **not** run directly by users; they are invoked by the CT script inside the container.
### Node.js + PostgreSQL ### Node.js + PostgreSQL
**Koel** - Music streaming with PHP + Node.js + PostgreSQL **Koel** - Music streaming with PHP + Node.js + PostgreSQL
@@ -97,7 +95,7 @@ Install scripts are **not** run directly by users; they are invoked by the CT sc
Install Node.js from NodeSource repository. Install Node.js from NodeSource repository.
```bash ```bash
# Default (Node.js 24) # Default (Node.js 22)
setup_nodejs setup_nodejs
# Specific version # Specific version
@@ -137,12 +135,8 @@ $STD cargo build --release
Install Python uv package manager (fast pip/venv replacement). Install Python uv package manager (fast pip/venv replacement).
```bash ```bash
# Default
setup_uv setup_uv
# Install a specific Python version
PYTHON_VERSION="3.12" setup_uv
# Use in script # Use in script
setup_uv setup_uv
cd /opt/myapp cd /opt/myapp
@@ -166,7 +160,7 @@ Install PHP with configurable modules and FPM/Apache support.
setup_php setup_php
# Full configuration # Full configuration
PHP_VERSION="8.4" \ PHP_VERSION="8.3" \
PHP_MODULE="mysqli,gd,curl,mbstring,xml,zip,ldap" \ PHP_MODULE="mysqli,gd,curl,mbstring,xml,zip,ldap" \
PHP_FPM="YES" \ PHP_FPM="YES" \
PHP_APACHE="YES" \ PHP_APACHE="YES" \
@@ -176,7 +170,7 @@ setup_php
**Environment Variables:** **Environment Variables:**
| Variable | Default | Description | | Variable | Default | Description |
| ------------- | ------- | ------------------------------- | | ------------- | ------- | ------------------------------- |
| `PHP_VERSION` | `8.4` | PHP version to install | | `PHP_VERSION` | `8.3` | PHP version to install |
| `PHP_MODULE` | `""` | Comma-separated list of modules | | `PHP_MODULE` | `""` | Comma-separated list of modules |
| `PHP_FPM` | `NO` | Install PHP-FPM | | `PHP_FPM` | `NO` | Install PHP-FPM |
| `PHP_APACHE` | `NO` | Install Apache module | | `PHP_APACHE` | `NO` | Install Apache module |
@@ -245,12 +239,12 @@ setup_mysql
Install PostgreSQL server. Install PostgreSQL server.
```bash ```bash
# Default (PostgreSQL 16) # Default (PostgreSQL 17)
setup_postgresql setup_postgresql
# Specific version # Specific version
PG_VERSION="16" setup_postgresql PG_VERSION="16" setup_postgresql
PG_VERSION="16" setup_postgresql PG_VERSION="17" setup_postgresql
``` ```
### `setup_postgresql_db` ### `setup_postgresql_db`
@@ -440,12 +434,12 @@ create_self_signed_cert
## Utility Functions ## Utility Functions
### `import_local_ip` ### `get_lxc_ip`
Set the `$LOCAL_IP` variable with the container's IP address. Set the `$LOCAL_IP` variable with the container's IP address.
```bash ```bash
import_local_ip get_lxc_ip
echo "Container IP: $LOCAL_IP" echo "Container IP: $LOCAL_IP"
# Use in config files # Use in config files
@@ -532,9 +526,9 @@ msg_ok "Installed Dependencies"
# Setup runtimes and databases FIRST # Setup runtimes and databases FIRST
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
PG_VERSION="16" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db
import_local_ip get_lxc_ip
# Download app using fetch_and_deploy (handles version tracking) # Download app using fetch_and_deploy (handles version tracking)
fetch_and_deploy_gh_release "myapp" "example/myapp" "tarball" "latest" "/opt/myapp" fetch_and_deploy_gh_release "myapp" "example/myapp" "tarball" "latest" "/opt/myapp"
@@ -670,7 +664,7 @@ PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,x
setup_composer setup_composer
setup_mariadb setup_mariadb
MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db
import_local_ip get_lxc_ip
# Download pre-built release (with asset pattern) # Download pre-built release (with asset pattern)
fetch_and_deploy_gh_release "myapp" "example/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz" fetch_and_deploy_gh_release "myapp" "example/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz"

View File

@@ -17,9 +17,7 @@ Complete guide to contributing to the ProxmoxVE project - from your first fork t
## 🚀 Quick Start ## 🚀 Quick Start
### 60 Seconds to Contributing (Development) ### 60 Seconds to Contributing
When developing and testing **in your fork**:
```bash ```bash
# 1. Fork on GitHub # 1. Fork on GitHub
@@ -29,8 +27,8 @@ When developing and testing **in your fork**:
git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
cd ProxmoxVE cd ProxmoxVE
# 3. Auto-configure your fork (IMPORTANT - updates all links!) # 3. Auto-configure your fork
bash docs/contribution/setup-fork.sh --full bash docs/contribution/setup-fork.sh
# 4. Create a feature branch # 4. Create a feature branch
git checkout -b feature/my-awesome-app git checkout -b feature/my-awesome-app
@@ -41,73 +39,19 @@ cat docs/ct/DETAILED_GUIDE.md # For container scripts
cat docs/install/DETAILED_GUIDE.md # For install scripts cat docs/install/DETAILED_GUIDE.md # For install scripts
# 6. Create your contribution # 6. Create your contribution
cp docs/contribution/templates_ct/AppName.sh ct/myapp.sh cp ct/example.sh ct/myapp.sh
cp docs/contribution/templates_install/AppName-install.sh install/myapp-install.sh cp install/example-install.sh install/myapp-install.sh
# ... edit files ... # ... edit files ...
# 7. Push to your fork and test via GitHub # 7. Test and commit
git push origin feature/my-awesome-app bash ct/myapp.sh
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" git add ct/myapp.sh install/myapp-install.sh
# ⏱️ GitHub may take 10-30 seconds to update files - be patient! git commit -m "feat: add MyApp"
# 8. Create your JSON metadata file
cp docs/contribution/templates_json/AppName.json frontend/public/json/myapp.json
# Edit metadata: name, slug, categories, description, resources, etc.
# 9. No direct install-script test
# Install scripts are executed by the CT script inside the container
# 10. Commit ONLY your new files (see Cherry-Pick section below!)
git add ct/myapp.sh install/myapp-install.sh frontend/public/json/myapp.json
git commit -m "feat: add MyApp container and install scripts"
git push origin feature/my-awesome-app git push origin feature/my-awesome-app
# 11. Create Pull Request on GitHub # 8. Create Pull Request on GitHub
``` ```
⚠️ **IMPORTANT: After setup-fork.sh, many files are modified!**
See the **Cherry-Pick: Submitting Only Your Changes** section below to learn how to push ONLY your 3-4 files instead of 600+ modified files!
### How Users Run Scripts (After Merged)
Once your script is merged to the main repository, users download and run it from GitHub like this:
```bash
# ✅ Users run from GitHub (normal usage after PR merged)
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)"
# Install scripts are called by the CT script and are not run directly by users
```
### Development vs. Production Execution
**During Development (you, in your fork):**
```bash
# You MUST test via curl from your GitHub fork (not local files!)
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
# The script's curl commands are updated by setup-fork.sh to point to YOUR fork
# This ensures you're testing your actual changes
# ⏱️ Wait 10-30 seconds after pushing - GitHub updates slowly
```
**After Merge (users, from GitHub):**
```bash
# Users download the script from upstream via curl
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)"
# The script's curl commands now point back to upstream (community-scripts)
# This is the stable, tested version
```
**Summary:**
- **Development**: Push to fork, test via curl → setup-fork.sh changes curl URLs to your fork
- **Production**: curl | bash from upstream → curl URLs point to community-scripts repo
--- ---
## 🍴 Setting Up Your Fork ## 🍴 Setting Up Your Fork
@@ -117,35 +61,14 @@ bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/Proxmo
When you clone your fork, run the setup script to automatically configure everything: When you clone your fork, run the setup script to automatically configure everything:
```bash ```bash
bash docs/contribution/setup-fork.sh --full bash docs/contribution/setup-fork.sh
``` ```
**What it does:** This will:
- Auto-detects your GitHub username from git config - Auto-detect your GitHub username
- Auto-detects your fork repository name - Update all documentation links to point to your fork
- Updates **ALL** hardcoded links to point to your fork instead of the main repo (`--full`) - Create `.git-setup-info` with recommended git workflows
- Creates `.git-setup-info` with your configuration
- Allows you to develop and test independently in your fork
**Why this matters:**
Without running this script, all links in your fork will still point to the upstream repository (community-scripts). This is a problem when testing because:
- Installation links will pull from upstream, not your fork
- Updates will target the wrong repository
- Your contributions won't be properly tested
**After running setup-fork.sh:**
Your fork is fully configured and ready to develop. You can:
- Push changes to your fork
- Test via curl: `bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"`
- All links will reference your fork for development
- ⏱️ Wait 10-30 seconds after pushing - GitHub takes time to update
- Commit and push with confidence
- Create a PR to merge into upstream
**See**: [FORK_SETUP.md](FORK_SETUP.md) for detailed instructions **See**: [FORK_SETUP.md](FORK_SETUP.md) for detailed instructions
@@ -158,12 +81,11 @@ If the script doesn't work, manually configure:
git config user.name "Your Name" git config user.name "Your Name"
git config user.email "your.email@example.com" git config user.email "your.email@example.com"
# Add upstream remote for syncing with main repo # Add upstream remote for syncing
git remote add upstream https://github.com/community-scripts/ProxmoxVE.git git remote add upstream https://github.com/community-scripts/ProxmoxVE.git
# Verify remotes # Verify remotes
git remote -v git remote -v
# Should show: origin (your fork) and upstream (main repo)
``` ```
--- ---
@@ -180,7 +102,7 @@ All scripts and configurations must follow our coding standards to ensure consis
- **[HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md)** - Reference for all tools.func helper functions - **[HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md)** - Reference for all tools.func helper functions
- **Container Scripts** - `/ct/` templates and guidelines - **Container Scripts** - `/ct/` templates and guidelines
- **Install Scripts** - `/install/` templates and guidelines - **Install Scripts** - `/install/` templates and guidelines
- **JSON Configurations** - `frontend/public/json/` structure and format - **JSON Configurations** - `/json/` structure and format
### Quick Checklist ### Quick Checklist
@@ -190,7 +112,7 @@ All scripts and configurations must follow our coding standards to ensure consis
- ✅ Include proper shebang: `#!/usr/bin/env bash` - ✅ Include proper shebang: `#!/usr/bin/env bash`
- ✅ Add copyright header with author - ✅ Add copyright header with author
- ✅ Handle errors properly with `msg_error`, `msg_ok`, etc. - ✅ Handle errors properly with `msg_error`, `msg_ok`, etc.
- ✅ Test before submitting PR (via curl from your fork, not local bash) - ✅ Test before submitting PR
- ✅ Update documentation if needed - ✅ Update documentation if needed
--- ---
@@ -211,172 +133,7 @@ Key points:
--- ---
## 🍒 Cherry-Pick: Submitting Only Your Changes ## 📚 Guides & Resources
**Problem**: `setup-fork.sh` modifies 600+ files to update links. You don't want to submit all of those changes - only your new 3-4 files!
**Solution**: Use git cherry-pick to select only YOUR files.
### Step-by-Step Cherry-Pick Guide
#### 1. Check what changed
```bash
# See all modified files
git status
# Verify your files are there
git status | grep -E "ct/myapp|install/myapp|json/myapp"
```
#### 2. Create a clean feature branch for submission
```bash
# Go back to upstream main (clean slate)
git fetch upstream
git checkout -b submit/myapp upstream/main
# Don't use your modified main branch!
```
#### 3. Cherry-pick ONLY your files
Cherry-picking extracts specific changes from commits:
```bash
# Option A: Cherry-pick commits that added your files
# (if you committed your files separately)
git cherry-pick <commit-hash-of-your-files>
# Option B: Manually copy and commit only your files
# From your work branch, get the file contents
git show feature/my-awesome-app:ct/myapp.sh > /tmp/myapp.sh
git show feature/my-awesome-app:install/myapp-install.sh > /tmp/myapp-install.sh
git show feature/my-awesome-app:frontend/public/json/myapp.json > /tmp/myapp.json
# Add them to the clean branch
cp /tmp/myapp.sh ct/myapp.sh
cp /tmp/myapp-install.sh install/myapp-install.sh
cp /tmp/myapp.json frontend/public/json/myapp.json
# Commit
git add ct/myapp.sh install/myapp-install.sh frontend/public/json/myapp.json
git commit -m "feat: add MyApp"
```
#### 4. Verify only your files are in the PR
```bash
# Check git diff against upstream
git diff upstream/main --name-only
# Should show ONLY:
# ct/myapp.sh
# install/myapp-install.sh
# frontend/public/json/myapp.json
```
#### 5. Push and create PR
```bash
# Push your clean submission branch
git push origin submit/myapp
# Create PR on GitHub from: submit/myapp → main
```
### Why This Matters
- ✅ Clean PR with only your changes
- ✅ Easier for maintainers to review
- ✅ Faster merge without conflicts
- ❌ Without cherry-pick: PR has 600+ file changes (won't merge!)
### If You Made a Mistake
```bash
# Delete the messy branch
git branch -D submit/myapp
# Go back to clean branch
git checkout -b submit/myapp upstream/main
# Try cherry-picking again
```
---
If you're using **Visual Studio Code** with an AI assistant, you can leverage our detailed guidelines to generate high-quality contributions automatically.
### How to Use AI Assistance
1. **Open the AI Guidelines**
```
docs/contribution/AI.md
```
This file contains all requirements, patterns, and examples for writing proper scripts.
2. **Prepare Your Information**
Before asking the AI to generate code, gather:
- **Repository URL**: e.g., `https://github.com/owner/myapp`
- **Dockerfile/Script**: Paste the app's installation instructions (if available)
- **Dependencies**: What packages does it need? (Node, Python, Java, PostgreSQL, etc.)
- **Ports**: What port does it listen on? (e.g., 3000, 8080, 5000)
- **Configuration**: Any environment variables or config files?
3. **Tell the AI Assistant**
Share with the AI:
- The repository URL
- The Dockerfile or install instructions
- Link to [docs/contribution/AI.md](AI.md) with instructions to follow
**Example prompt:**
```
I want to contribute a container script for MyApp to ProxmoxVE.
Repository: https://github.com/owner/myapp
Here's the Dockerfile:
[paste Dockerfile content]
Please follow the guidelines in docs/contribution/AI.md to create:
1. ct/myapp.sh (container script)
2. install/myapp-install.sh (installation script)
3. frontend/public/json/myapp.json (metadata)
```
4. **AI Will Generate**
The AI will produce scripts that:
- Follow all ProxmoxVE patterns and conventions
- Use helper functions from `tools.func` correctly
- Include proper error handling and messages
- Have correct update mechanisms
- Are ready to submit as a PR
### Key Points for AI Assistants
- **Templates Location**: `docs/contribution/templates_ct/AppName.sh`, `templates_install/`, `templates_json/`
- **Guidelines**: Must follow `docs/contribution/AI.md` exactly
- **Helper Functions**: Use only functions from `misc/tools.func` - never write custom ones
- **Testing**: Always test before submission via curl from your fork
```bash
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
# Wait 10-30 seconds after pushing changes
```
- **No Docker**: Container scripts must be bare-metal, not Docker-based
### Benefits
- **Speed**: AI generates boilerplate in seconds
- **Consistency**: Follows same patterns as 200+ existing scripts
- **Quality**: Less bugs and more maintainable code
- **Learning**: See how your app should be structured
---
### Documentation ### Documentation
@@ -464,15 +221,15 @@ git push origin feature/my-feature
git rebase upstream/main git rebase upstream/main
``` ```
2. **Test your changes** (via curl from your fork) 2. **Test your changes**
```bash ```bash
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)" bash ct/my-app.sh
# Follow prompts and test the container # Follow prompts and test the container
# ⏱️ Wait 10-30 seconds after pushing - GitHub takes time to update
``` ```
3. **Check code standards** 3. **Check code standards**
- [ ] Follows template structure - [ ] Follows template structure
- [ ] Proper error handling - [ ] Proper error handling
- [ ] Documentation updated (if needed) - [ ] Documentation updated (if needed)
@@ -503,66 +260,23 @@ Before opening a PR:
## ❓ FAQ ## ❓ FAQ
### ❌ Why can't I test with `bash ct/myapp.sh` locally? ### How do I test my changes?
You might try:
```bash ```bash
# ❌ WRONG - This won't test your actual changes! # For container scripts
bash ct/myapp.sh bash ct/my-app.sh
./ct/myapp.sh
sh ct/myapp.sh # For install scripts (runs inside container)
# The ct script will call it automatically
# For advanced debugging
VERBOSE=yes bash ct/my-app.sh
``` ```
**Why this fails:**
- `bash ct/myapp.sh` uses the LOCAL clone file
- The LOCAL file doesn't execute the curl commands - it's already on disk
- The curl URLs INSIDE the script are modified by setup-fork.sh, but they're not executed
- So you can't verify if your curl URLs actually work
- Users will get the curl URL version (which may be broken)
**Solution:** Always test via curl from GitHub:
```bash
# ✅ CORRECT - Tests the actual GitHub URLs
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
```
### ❓ How do I test my changes?
You **cannot** test locally with `bash ct/myapp.sh` from your cloned directory!
You **must** push to GitHub and test via curl from your fork:
```bash
# 1. Push your changes to your fork
git push origin feature/my-awesome-app
# 2. Test via curl (this loads the script from GitHub, not local files)
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)"
# 3. For verbose/debug output, pass environment variables
VERBOSE=yes bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)"
DEV_MODE_LOGS=true bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)"
```
**Why?**
- Local `bash ct/myapp.sh` uses local files from your clone
- But the script's INTERNAL curl commands have been modified by setup-fork.sh to point to your fork
- This discrepancy means you're not actually testing the curl URLs
- Testing via curl ensures the script downloads from YOUR fork GitHub URLs
- ⏱️ **Important:** GitHub takes 10-30 seconds to recognize newly pushed files. Wait before testing!
**What if local bash worked?**
You'd be testing local files only, not the actual GitHub URLs that users will download. This means broken curl links wouldn't be caught during testing.
### What if my PR has conflicts? ### What if my PR has conflicts?
```bash ```bash
# Sync with upstream main repository # Sync with upstream
git fetch upstream git fetch upstream
git rebase upstream/main git rebase upstream/main
@@ -574,27 +288,17 @@ git push -f origin your-branch
### How do I keep my fork updated? ### How do I keep my fork updated?
Two ways: See "Keep Your Fork Updated" section above, or run:
**Option 1: Run setup script again**
```bash ```bash
bash docs/contribution/setup-fork.sh --full bash docs/contribution/setup-fork.sh
```
**Option 2: Manual sync**
```bash
git fetch upstream
git rebase upstream/main
git push -f origin main
``` ```
### Where do I ask questions? ### Where do I ask questions?
- **GitHub Issues**: For bugs and feature requests - **GitHub Issues**: For bugs and feature requests
- **GitHub Discussions**: For general questions and ideas - **GitHub Discussions**: For general questions
- **Discord**: Community-scripts server for real-time chat - **Discord**: Community-scripts server
--- ---
@@ -603,7 +307,7 @@ git push -f origin main
### For First-Time Contributors ### For First-Time Contributors
1. Read: [docs/README.md](../README.md) - Documentation overview 1. Read: [docs/README.md](../README.md) - Documentation overview
2. Read: [CONTRIBUTING.md](CONTRIBUTING.md) - Essential coding standards 2. Read: [docs/contribution/FORK_SETUP.md](FORK_SETUP.md) - Fork setup guide
3. Choose your path: 3. Choose your path:
- Containers → [docs/ct/DETAILED_GUIDE.md](../ct/DETAILED_GUIDE.md) - Containers → [docs/ct/DETAILED_GUIDE.md](../ct/DETAILED_GUIDE.md)
- Installation → [docs/install/DETAILED_GUIDE.md](../install/DETAILED_GUIDE.md) - Installation → [docs/install/DETAILED_GUIDE.md](../install/DETAILED_GUIDE.md)
@@ -614,24 +318,21 @@ git push -f origin main
1. Review [CONTRIBUTING.md](CONTRIBUTING.md) - Coding standards 1. Review [CONTRIBUTING.md](CONTRIBUTING.md) - Coding standards
2. Review [CODE_AUDIT.md](CODE_AUDIT.md) - Audit checklist 2. Review [CODE_AUDIT.md](CODE_AUDIT.md) - Audit checklist
3. Check templates in `/docs/contribution/templates_*/` 3. Check templates in `/ct/` and `/install/`
4. Use AI assistants with [AI.md](AI.md) for code generation 4. Submit PR with confidence
5. Submit PR with confidence
### For Using AI Assistants ### For Reviewers/Maintainers
See "Using AI Assistants" section above for: 1. Use [CODE_AUDIT.md](CODE_AUDIT.md) as review guide
2. Reference [docs/TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md) for architecture
- How to structure prompts 3. Check [docs/EXIT_CODES.md](../EXIT_CODES.md) for error handling
- What information to provide
- How to validate AI output
--- ---
## 🚀 Ready to Contribute? ## 🚀 Ready to Contribute?
1. **Fork** the repository 1. **Fork** the repository
2. **Clone** your fork and **setup** with `bash docs/contribution/setup-fork.sh --full` 2. **Clone** your fork and **setup** with `bash docs/contribution/setup-fork.sh`
3. **Choose** your contribution type (container, installation, tools, etc.) 3. **Choose** your contribution type (container, installation, tools, etc.)
4. **Read** the appropriate detailed guide 4. **Read** the appropriate detailed guide
5. **Create** your feature branch 5. **Create** your feature branch
@@ -644,9 +345,9 @@ See "Using AI Assistants" section above for:
## 📞 Contact & Support ## 📞 Contact & Support
- **GitHub**: [community-scripts/ProxmoxVE](https://github.com/community-scripts/ProxmoxVE) - **GitHub**: https://github.com/community-scripts/ProxmoxVE
- **Issues**: [GitHub Issues](https://github.com/community-scripts/ProxmoxVE/issues) - **Issues**: https://github.com/community-scripts/ProxmoxVE/issues
- **Discussions**: [GitHub Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) - **Discussions**: https://github.com/community-scripts/ProxmoxVE/discussions
- **Discord**: [Join Server](https://discord.gg/UHrpNWGwkH) - **Discord**: [Join Server](https://discord.gg/UHrpNWGwkH)
--- ---

View File

@@ -8,15 +8,13 @@
# Updates all hardcoded links to point to your fork # Updates all hardcoded links to point to your fork
# #
# Usage: # Usage:
# ./setup-fork.sh # Auto-detect from git config (updates misc/ only) # ./setup-fork.sh # Auto-detect from git config
# ./setup-fork.sh YOUR_USERNAME # Specify username (updates misc/ only) # ./setup-fork.sh YOUR_USERNAME # Specify username
# ./setup-fork.sh YOUR_USERNAME REPO_NAME # Specify both (updates misc/ only) # ./setup-fork.sh YOUR_USERNAME REPO_NAME # Specify both
# ./setup-fork.sh --full # Update all files including ct/, install/, vm/, etc.
# #
# Examples: # Examples:
# ./setup-fork.sh john # Uses john/ProxmoxVE, updates misc/ only # ./setup-fork.sh john # Uses john/ProxmoxVE
# ./setup-fork.sh john my-fork # Uses john/my-fork, updates misc/ only # ./setup-fork.sh john my-fork # Uses john/my-fork
# ./setup-fork.sh --full # Auto-detect + update all files
################################################################################ ################################################################################
set -e set -e
@@ -32,7 +30,6 @@ NC='\033[0m' # No Color
REPO_NAME="ProxmoxVE" REPO_NAME="ProxmoxVE"
USERNAME="" USERNAME=""
AUTO_DETECT=true AUTO_DETECT=true
UPDATE_ALL=false
################################################################################ ################################################################################
# FUNCTIONS # FUNCTIONS
@@ -102,8 +99,7 @@ confirm() {
local prompt="$1" local prompt="$1"
local response local response
echo -ne "${YELLOW}${prompt} (y/n)${NC} " read -p "$(echo -e ${YELLOW})$prompt (y/n)${NC} " -r response
read -r response
[[ $response =~ ^[Yy]$ ]] [[ $response =~ ^[Yy]$ ]]
} }
@@ -117,22 +113,24 @@ update_links() {
print_info "Scanning for hardcoded links..." print_info "Scanning for hardcoded links..."
# Change to repo root # Find all markdown and shell files
local repo_root=$(git rev-parse --show-toplevel 2>/dev/null || pwd) local -a files_to_update=(
"docs/DEFAULTS_SYSTEM_GUIDE.md"
# Determine search path "docs/alpine-install.func.md"
local search_path="$repo_root/misc" "docs/install.func.md"
if [[ "$UPDATE_ALL" == "true" ]]; then "docs/APP-install.md"
search_path="$repo_root" "docs/APP-ct.md"
print_info "Searching all files (--full mode)" "docs/CONTRIBUTION_GUIDE.md"
else "docs/INDEX.md"
print_info "Searching misc/ directory only (core functions)" "docs/README.md"
fi "docs/EXIT_CODES.md"
"docs/api/README.md"
)
echo "" echo ""
# Find all files containing the old repo reference for file in "${files_to_update[@]}"; do
while IFS= read -r file; do if [[ -f "$file" ]]; then
# Count occurrences # Count occurrences
local count=$(grep -c "github.com/$old_repo/$old_name" "$file" 2>/dev/null || echo 0) local count=$(grep -c "github.com/$old_repo/$old_name" "$file" 2>/dev/null || echo 0)
@@ -140,19 +138,14 @@ update_links() {
# Backup original # Backup original
cp "$file" "$file.backup" cp "$file" "$file.backup"
# Replace links - use different sed syntax for BSD/macOS vs GNU sed # Replace links
if sed --version &>/dev/null 2>&1; then
# GNU sed
sed -i "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file" sed -i "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file"
else
# BSD sed (macOS)
sed -i '' "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file"
fi
((files_updated++)) ((files_updated++))
print_success "Updated $file ($count links)" print_success "Updated $file ($count links)"
fi fi
done < <(find "$search_path" -type f \( -name "*.md" -o -name "*.sh" -o -name "*.func" -o -name "*.json" \) -not -path "*/.git/*" 2>/dev/null | xargs grep -l "github.com/$old_repo/$old_name" 2>/dev/null) fi
done
return $files_updated return $files_updated
} }
@@ -220,7 +213,7 @@ git merge upstream/main
--- ---
For more help, see: docs/contribution/README.md For more help, see: docs/CONTRIBUTION_GUIDE.md
EOF EOF
print_success "Created .git-setup-info file" print_success "Created .git-setup-info file"
@@ -233,15 +226,6 @@ EOF
print_header print_header
# Parse command line arguments # Parse command line arguments
if [[ $# -gt 0 ]]; then
# Check for --full flag
if [[ "$1" == "--full" ]]; then
UPDATE_ALL=true
AUTO_DETECT=true
shift # Remove --full from arguments
fi
# Process remaining arguments
if [[ $# -gt 0 ]]; then if [[ $# -gt 0 ]]; then
USERNAME="$1" USERNAME="$1"
AUTO_DETECT=false AUTO_DETECT=false
@@ -249,7 +233,6 @@ if [[ $# -gt 0 ]]; then
if [[ $# -gt 1 ]]; then if [[ $# -gt 1 ]]; then
REPO_NAME="$2" REPO_NAME="$2"
fi fi
fi
else else
# Try auto-detection # Try auto-detection
if username=$(detect_username); then if username=$(detect_username); then
@@ -286,11 +269,7 @@ fi
# Show what we'll do # Show what we'll do
echo -e "${BLUE}Configuration Summary:${NC}" echo -e "${BLUE}Configuration Summary:${NC}"
echo " Repository URL: https://github.com/$USERNAME/$REPO_NAME" echo " Repository URL: https://github.com/$USERNAME/$REPO_NAME"
if [[ "$UPDATE_ALL" == "true" ]]; then echo " Files to update: 10 files with documentation"
echo " Files to update: ALL files (ct/, install/, vm/, misc/, docs/, etc.)"
else
echo " Files to update: misc/ directory only (core functions)"
fi
echo "" echo ""
# Ask for confirmation # Ask for confirmation
@@ -328,7 +307,7 @@ echo -e "${BLUE}Next Steps:${NC}"
echo " 1. Review the changes: git diff" echo " 1. Review the changes: git diff"
echo " 2. Check .git-setup-info for recommended git workflow" echo " 2. Check .git-setup-info for recommended git workflow"
echo " 3. Start developing: git checkout -b feature/my-app" echo " 3. Start developing: git checkout -b feature/my-app"
echo " 4. Read: docs/contribution/README.md" echo " 4. Read: docs/CONTRIBUTION_GUIDE.md"
echo "" echo ""
print_success "Happy contributing! 🚀" print_success "Happy contributing! 🚀"

View File

@@ -1,180 +1,188 @@
# CT Container Scripts - Quick Reference # **AppName<span></span>.sh Scripts**
> [!WARNING] `AppName.sh` scripts found in the `/ct` directory. These scripts are responsible for the installation of the desired application. For this guide we take `/ct/snipeit.sh` as example.
> **This is legacy documentation.** Refer to the **modern template** at [templates_ct/AppName.sh](AppName.sh) for best practices.
>
> Current templates use:
>
> - `tools.func` helpers instead of manual patterns
> - `check_for_gh_release` and `fetch_and_deploy_gh_release` from build.func
> - Automatic setup-fork.sh configuration
--- ## Table of Contents
## Before Creating a Script - [**AppName.sh Scripts**](#appnamesh-scripts)
- [Table of Contents](#table-of-contents)
- [1. **File Header**](#1-file-header)
- [1.1 **Shebang**](#11-shebang)
- [1.2 **Import Functions**](#12-import-functions)
- [1.3 **Metadata**](#13-metadata)
- [2 **Variables and function import**](#2-variables-and-function-import)
- [2.1 **Default Values**](#21-default-values)
- [2.2 **📋 App output \& base settings**](#22--app-output--base-settings)
- [2.3 **🛠 Core functions**](#23--core-functions)
- [3 **Update function**](#3-update-function)
- [3.1 **Function Header**](#31-function-header)
- [3.2 **Check APP**](#32-check-app)
- [3.3 **Check version**](#33-check-version)
- [3.4 **Verbosity**](#34-verbosity)
- [3.5 **Backups**](#35-backups)
- [3.6 **Cleanup**](#36-cleanup)
- [3.7 **No update function**](#37-no-update-function)
- [4 **End of the script**](#4-end-of-the-script)
- [5. **Contribution checklist**](#5-contribution-checklist)
1. **Fork & Clone:** ## 1. **File Header**
```bash ### 1.1 **Shebang**
git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
cd ProxmoxVE
```
2. **Run setup-fork.sh** (updates all curl URLs to your fork): - Use `#!/usr/bin/env bash` as the shebang.
```bash
bash docs/contribution/setup-fork.sh
```
3. **Copy the Modern Template:**
```bash
cp templates_ct/AppName.sh ct/MyApp.sh
# Edit ct/MyApp.sh with your app details
```
4. **Test Your Script (via GitHub):**
⚠️ **Important:** You must push to GitHub and test via curl, not `bash ct/MyApp.sh`!
```bash
# Push your changes to your fork first
git push origin feature/my-awesome-app
# Then test via curl (this loads from YOUR fork, not local files)
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)"
```
> 💡 **Why?** The script's curl commands are modified by setup-fork.sh, but local execution uses local files, not the updated GitHub URLs. Testing via curl ensures your script actually works.
>
> ⏱️ **Note:** GitHub sometimes takes 10-30 seconds to update files. If you don't see your changes, wait and try again.
5. **Cherry-Pick for PR** (submit ONLY your 3-4 files):
- See [Cherry-Pick Guide](../README.md) for step-by-step git commands
---
## Template Structure
The modern template includes:
### Header
```bash ```bash
#!/usr/bin/env bash #!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# (Note: setup-fork.sh changes this URL to point to YOUR fork during development)
``` ```
### Metadata ### 1.2 **Import Functions**
- Import the build.func file.
- When developing your own script, change the URL to your own repository.
> [!IMPORTANT]
> You also need to change all apperances of this URL in `misc/build.func` and `misc/install.func`
Example for development:
```bash
source <(curl -fsSL https://raw.githubusercontent.com/[USER]/[REPO]/refs/heads/[BRANCH]/misc/build.func)
```
Final script:
```bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
```
> [!CAUTION]
> Before opening a Pull Request, change the URLs to point to the community-scripts repo.
### 1.3 **Metadata**
- Add clear comments for script metadata, including author, copyright, and license information.
Example:
```bash ```bash
# Copyright (c) 2021-2026 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: YourUsername # Author: [YourUserName]
# License: MIT # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
APP="MyApp" # Source: [SOURCE_URL]
var_tags="app-category;foss" ```
> [!NOTE]:
>
> - Add your username and source URL
> - For existing scripts, add "| Co-Author [YourUserName]" after the current author
---
## 2 **Variables and function import**
>
> [!NOTE]
> You need to have all this set in your script, otherwise it will not work!
### 2.1 **Default Values**
- This section sets the default values for the container.
- `APP` needs to be set to the application name and must be equal to the filenames of your scripts.
- `var_tags`: You can set Tags for the CT wich show up in the Proxmox UI. Don´t overdo it!
>[!NOTE]
>Description for all Default Values
>
>| Variable | Description | Notes |
>|----------|-------------|-------|
>| `APP` | Application name | Must match ct\AppName.sh |
>| `var_tags` | Proxmox display tags without Spaces, only ; | Limit the number |
>| `var_cpu` | CPU cores | Number of cores |
>| `var_ram` | RAM | In MB |
>| `var_disk` | Disk capacity | In GB |
>| `var_os` | Operating system | alpine, debian, ubuntu |
>| `var_version` | OS version | e.g., 3.20, 11, 12, 20.04 |
>| `var_unprivileged` | Container type | 1 = Unprivileged, 0 = Privileged |
Example:
```bash
APP="SnipeIT"
var_tags="asset-management;foss"
var_cpu="2" var_cpu="2"
var_ram="2048" var_ram="2048"
var_disk="4" var_disk="4"
var_os="alpine" var_os="debian"
var_version="3.20" var_version="12"
var_unprivileged="1" var_unprivileged="1"
``` ```
### Core Setup ## 2.2 **📋 App output & base settings**
```bash ```bash
header_info "$APP" header_info "$APP"
```
- `header_info`: Generates ASCII header for APP
## 2.3 **🛠 Core functions**
```bash
variables variables
color color
catch_errors catch_errors
``` ```
### Update Function - `variables`: Processes input and prepares variables
- `color`: Sets icons, colors, and formatting
- `catch_errors`: Enables error handling
The modern template provides a standard update pattern: ---
## 3 **Update function**
### 3.1 **Function Header**
- If applicable write a function that updates the application and the OS in the container.
- Each update function starts with the same code:
```bash ```bash
function update_script() { function update_script() {
header_info header_info
check_container_storage check_container_storage
check_container_resources check_container_resources
```
# Use tools.func helpers: ### 3.2 **Check APP**
check_for_gh_release "myapp" "owner/repo"
fetch_and_deploy_gh_release "myapp" "owner/repo" "tarball" "latest" "/opt/myapp" - Before doing anything update-wise, check if the app is installed in the container.
Example:
```bash
if [[ ! -d /opt/snipe-it ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
```
### 3.3 **Check version**
- Before updating, check if a new version exists.
- We use the `${APPLICATION}_version.txt` file created in `/opt` during the install to compare new versions against the currently installed version.
Example with a Github Release:
```bash
RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Updating ${APP} to v${RELEASE}"
#DO UPDATE
else
msg_ok "No update required. ${APP} is already at v${RELEASE}."
fi
exit
} }
``` ```
---
## Key Patterns
### Check for Updates (App Repository)
Use `check_for_gh_release` with the **app repo**:
```bash
check_for_gh_release "myapp" "owner/repo"
```
### Deploy External App
Use `fetch_and_deploy_gh_release` with the **app repo**:
```bash
fetch_and_deploy_gh_release "myapp" "owner/repo"
```
### Avoid Manual Version Checking
❌ OLD (manual):
```bash
RELEASE=$(curl -fsSL https://api.github.com/repos/myapp/myapp/releases/latest | grep tag_name)
```
✅ NEW (use tools.func):
```bash
fetch_and_deploy_gh_release "myapp" "owner/repo"
```
---
## Best Practices
1. **Use tools.func helpers** - Don't manually curl for versions
2. **Only add app-specific dependencies** - Don't add ca-certificates, curl, gnupg (handled by build.func)
3. **Test via curl from your fork** - Push first, then: `bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)"`
4. **Wait for GitHub to update** - Takes 10-30 seconds after git push
5. **Cherry-pick only YOUR files** - Submit only ct/MyApp.sh, install/MyApp-install.sh, frontend/public/json/myapp.json (3 files)
6. **Verify before PR** - Run `git diff upstream/main --name-only` to confirm only your files changed
---
## Common Update Patterns
See the [modern template](AppName.sh) and [AI.md](../AI.md) for complete working examples.
Recent reference scripts with good update functions:
- [Trip](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/trip.sh)
- [Thingsboard](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/thingsboard.sh)
- [UniFi](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/unifi.sh)
---
## Need Help?
- **[README.md](../README.md)** - Full contribution workflow
- **[AI.md](../AI.md)** - AI-generated script guidelines
- **[FORK_SETUP.md](../FORK_SETUP.md)** - Why setup-fork.sh is important
- **[Slack Community](https://discord.gg/your-link)** - Ask questions
````
### 3.4 **Verbosity** ### 3.4 **Verbosity**
- Use the appropriate flag (**-q** in the examples) for a command to suppress its output. - Use the appropriate flag (**-q** in the examples) for a command to suppress its output.
@@ -183,7 +191,7 @@ Recent reference scripts with good update functions:
```bash ```bash
curl -fsSL curl -fsSL
unzip -q unzip -q
```` ```
- If a command does not come with this functionality use `$STD` to suppress it's output. - If a command does not come with this functionality use `$STD` to suppress it's output.
@@ -269,7 +277,7 @@ echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
## 5. **Contribution checklist** ## 5. **Contribution checklist**
- [ ] Shebang is correctly set (`#!/usr/bin/env bash`). - [ ] Shebang is correctly set (`#!/usr/bin/env bash`).
- [ ] Correct link to _build.func_ - [ ] Correct link to *build.func*
- [ ] Metadata (author, license) is included at the top. - [ ] Metadata (author, license) is included at the top.
- [ ] Variables follow naming conventions. - [ ] Variables follow naming conventions.
- [ ] Update function exists. - [ ] Update function exists.

View File

@@ -5,133 +5,89 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: [SOURCE_URL e.g. https://github.com/example/app] # Source: [SOURCE_URL e.g. https://github.com/example/app]
# ============================================================================ # App Default Values
# APP CONFIGURATION
# ============================================================================
# These values are sent to build.func and define default container resources.
# Users can customize these during installation via the interactive prompts.
# ============================================================================
APP="[AppName]" APP="[AppName]"
var_tags="${var_tags:-[category1];[category2]}" # Max 2 tags, semicolon-separated var_tags="${var_tags:-[category]}"
var_cpu="${var_cpu:-2}" # CPU cores: 1-4 typical var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}" # RAM in MB: 512, 1024, 2048, etc. var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}" # Disk in GB: 6, 8, 10, 20 typical var_disk="${var_disk:-4}"
var_os="${var_os:-debian}" # OS: debian, ubuntu, alpine var_os="${var_os:-debian}"
var_version="${var_version:-13}" # OS Version: 13 (Debian), 24.04 (Ubuntu), 3.21 (Alpine) var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}" # 1=unprivileged (secure), 0=privileged (for Docker/Podman) var_unprivileged="${var_unprivileged:-1}"
# ============================================================================ # =============================================================================
# INITIALIZATION - These are required in all CT scripts # CONFIGURATION GUIDE
# ============================================================================ # =============================================================================
header_info "$APP" # Display app name and setup header # APP - Display name, title case (e.g. "Koel", "Wallabag", "Actual Budget")
variables # Initialize build.func variables # var_tags - Max 2 tags, semicolon separated (e.g. "music;streaming", "finance")
color # Load color variables for output # var_cpu - CPU cores: 1-4 typical
catch_errors # Enable error handling with automatic exit on failure # var_ram - RAM in MB: 512, 1024, 2048, 4096 typical
# var_disk - Disk in GB: 4, 6, 8, 10, 20 typical
# var_os - OS: debian, ubuntu, alpine
# var_version - OS version: 12/13 (debian), 22.04/24.04 (ubuntu), 3.20/3.21 (alpine)
# var_unprivileged - 1 = unprivileged (secure, default), 0 = privileged (for docker etc.)
# ============================================================================ header_info "$APP"
# UPDATE SCRIPT - Called when user selects "Update" from web interface variables
# ============================================================================ color
# This function is triggered by the web interface to update the application. catch_errors
# It should:
# 1. Check if installation exists
# 2. Check for new GitHub releases
# 3. Stop running services
# 4. Backup critical data
# 5. Deploy new version
# 6. Run post-update commands (migrations, config updates, etc.)
# 7. Restore data if needed
# 8. Start services
#
# Exit with `exit` at the end to prevent container restart.
# ============================================================================
function update_script() { function update_script() {
header_info header_info
check_container_storage check_container_storage
check_container_resources check_container_resources
# Step 1: Verify installation exists # Check if installation exists
if [[ ! -d /opt/[appname] ]]; then if [[ ! -d /opt/[appname] ]]; then
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
# Step 2: Check if update is available # check_for_gh_release returns 0 (true) if update available, 1 (false) if not
if check_for_gh_release "[appname]" "YourUsername/YourRepo"; then if check_for_gh_release "[appname]" "[owner/repo]"; then
msg_info "Stopping Services"
# Step 3: Stop services before update
msg_info "Stopping Service"
systemctl stop [appname] systemctl stop [appname]
msg_ok "Stopped Service" msg_ok "Stopped Services"
# Step 4: Backup critical data before overwriting # Optional: Backup important data before update
msg_info "Backing up Data" msg_info "Creating Backup"
cp -r /opt/[appname]/data /opt/[appname]_data_backup 2>/dev/null || true mkdir -p /tmp/[appname]_backup
msg_ok "Backed up Data" cp /opt/[appname]/.env /tmp/[appname]_backup/ 2>/dev/null || true
cp -r /opt/[appname]/data /tmp/[appname]_backup/ 2>/dev/null || true
msg_ok "Created Backup"
# Step 5: Download and deploy new version # CLEAN_INSTALL=1 removes old directory before extracting new version
# CLEAN_INSTALL=1 removes old directory before extracting CLEAN_INSTALL=1 fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/[appname]"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "[appname]" "owner/repo" "tarball" "latest" "/opt/[appname]"
# Step 6: Run post-update commands (uncomment as needed) # Restore configuration and data
# These examples show common patterns - use what applies to your app:
#
# For Node.js apps:
# msg_info "Installing Dependencies"
# cd /opt/[appname]
# $STD npm ci --production
# msg_ok "Installed Dependencies"
#
# For Python apps:
# msg_info "Installing Dependencies"
# cd /opt/[appname]
# $STD uv sync --frozen
# msg_ok "Installed Dependencies"
#
# For database migrations:
# msg_info "Running Database Migrations"
# cd /opt/[appname]
# $STD npm run migrate
# msg_ok "Ran Database Migrations"
#
# For PHP apps:
# msg_info "Installing Dependencies"
# cd /opt/[appname]
# $STD composer install --no-dev
# msg_ok "Installed Dependencies"
# Step 7: Restore data from backup
msg_info "Restoring Data" msg_info "Restoring Data"
cp -r /opt/[appname]_data_backup/. /opt/[appname]/data/ 2>/dev/null || true cp /tmp/[appname]_backup/.env /opt/[appname]/ 2>/dev/null || true
rm -rf /opt/[appname]_data_backup cp -r /tmp/[appname]_backup/data/* /opt/[appname]/data/ 2>/dev/null || true
rm -rf /tmp/[appname]_backup
msg_ok "Restored Data" msg_ok "Restored Data"
# Step 8: Restart service with new version # Optional: Run any post-update commands
msg_info "Starting Service" msg_info "Running Post-Update Tasks"
cd /opt/[appname]
# Examples:
# $STD npm ci --production
# $STD php artisan migrate --force
# $STD composer install --no-dev
msg_ok "Ran Post-Update Tasks"
msg_info "Starting Services"
systemctl start [appname] systemctl start [appname]
msg_ok "Started Service" msg_ok "Started Services"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi fi
exit exit
} }
# ============================================================================
# MAIN EXECUTION - Container creation flow
# ============================================================================
# These are called by build.func and handle the full installation process:
# 1. start - Initialize container creation
# 2. build_container - Execute the install script inside container
# 3. description - Display completion info and access details
# ============================================================================
start start
build_container build_container
description description
# ============================================================================
# COMPLETION MESSAGE
# ============================================================================
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}"

View File

@@ -1,195 +1,54 @@
# Install Scripts - Quick Reference
> [!WARNING] # **AppName<span></span>-install.sh Scripts**
> **This is legacy documentation.** Refer to the **modern template** at [templates_install/AppName-install.sh](AppName-install.sh) for best practices.
>
> Current templates use:
>
> - `tools.func` helpers (setup_nodejs, setup_uv, setup_postgresql_db, etc.)
> - Automatic dependency installation via build.func
> - Standardized environment variable patterns
--- `AppName-install.sh` scripts found in the `/install` directory. These scripts are responsible for the installation of the application. For this guide we take `/install/snipeit-install.sh` as example.
## Before Creating a Script ## Table of Contents
1. **Copy the Modern Template:** - [**AppName-install.sh Scripts**](#appname-installsh-scripts)
- [Table of Contents](#table-of-contents)
- [1. **File header**](#1-file-header)
- [1.1 **Shebang**](#11-shebang)
- [1.2 **Comments**](#12-comments)
- [1.3 **Variables and function import**](#13-variables-and-function-import)
- [2. **Variable naming and management**](#2-variable-naming-and-management)
- [2.1 **Naming conventions**](#21-naming-conventions)
- [3. **Dependencies**](#3-dependencies)
- [3.1 **Install all at once**](#31-install-all-at-once)
- [3.2 **Collapse dependencies**](#32-collapse-dependencies)
- [4. **Paths to application files**](#4-paths-to-application-files)
- [5. **Version management**](#5-version-management)
- [5.1 **Install the latest release**](#51-install-the-latest-release)
- [5.2 **Save the version for update checks**](#52-save-the-version-for-update-checks)
- [6. **Input and output management**](#6-input-and-output-management)
- [6.1 **User feedback**](#61-user-feedback)
- [6.2 **Verbosity**](#62-verbosity)
- [7. **String/File Manipulation**](#7-stringfile-manipulation)
- [7.1 **File Manipulation**](#71-file-manipulation)
- [8. **Security practices**](#8-security-practices)
- [8.1 **Password generation**](#81-password-generation)
- [8.2 **File permissions**](#82-file-permissions)
- [9. **Service Configuration**](#9-service-configuration)
- [9.1 **Configuration files**](#91-configuration-files)
- [9.2 **Credential management**](#92-credential-management)
- [9.3 **Enviroment files**](#93-enviroment-files)
- [9.4 **Services**](#94-services)
- [10. **Cleanup**](#10-cleanup)
- [10.1 **Remove temporary files**](#101-remove-temporary-files)
- [10.2 **Autoremove and autoclean**](#102-autoremove-and-autoclean)
- [11. **Best Practices Checklist**](#11-best-practices-checklist)
- [Example: High-Level Script Flow](#example-high-level-script-flow)
```bash ## 1. **File header**
cp templates_install/AppName-install.sh install/MyApp-install.sh
# Edit install/MyApp-install.sh
```
2. **Key Pattern:** ### 1.1 **Shebang**
- CT scripts source build.func and call the install script
- Install scripts use sourced FUNCTIONS_FILE_PATH (via build.func)
- Both scripts work together in the container
3. **Test via GitHub:** - Use `#!/usr/bin/env bash` as the shebang.
```bash
# Push your changes to your fork first
git push origin feature/my-awesome-app
# Test the CT script via curl (it will call the install script)
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)"
# ⏱️ Wait 10-30 seconds after pushing - GitHub takes time to update
```
---
## Template Structure
### Header
```bash ```bash
#!/usr/bin/env bash #!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/install.func)
# (setup-fork.sh modifies this URL to point to YOUR fork during development)
``` ```
### Dependencies (App-Specific Only)
```bash
# Don't add: ca-certificates, curl, gnupg, wget, git, jq
# These are handled by build.func
msg_info "Installing dependencies"
$STD apt-get install -y app-specific-deps
msg_ok "Installed dependencies"
```
### Runtime Setup
Use tools.func helpers instead of manual installation:
```bash
# ✅ NEW (use tools.func):
NODE_VERSION="20"
setup_nodejs
# OR
PYTHON_VERSION="3.12"
setup_uv
# OR
PG_DB_NAME="myapp_db"
PG_DB_USER="myapp"
setup_postgresql_db
```
### Service Configuration
```bash
# Create .env file
msg_info "Configuring MyApp"
cat << EOF > /opt/myapp/.env
DEBUG=false
PORT=8080
DATABASE_URL=postgresql://...
EOF
msg_ok "Configuration complete"
# Create systemd service
msg_info "Creating systemd service"
cat << EOF > /etc/systemd/system/myapp.service
[Unit]
Description=MyApp
[Service]
ExecStart=/usr/bin/node /opt/myapp/app.js
[Install]
WantedBy=multi-user.target
EOF
msg_ok "Service created"
```
### Finalization
```bash
msg_info "Finalizing MyApp installation"
systemctl enable --now myapp
motd_ssh
customize
msg_ok "MyApp installation complete"
cleanup_lxc
```
---
## Key Patterns
### Avoid Manual Version Checking
❌ OLD (manual):
```bash
RELEASE=$(curl -fsSL https://api.github.com/repos/app/repo/releases/latest | grep tag_name)
wget https://github.com/app/repo/releases/download/$RELEASE/app.tar.gz
```
✅ NEW (use tools.func via CT script's fetch_and_deploy_gh_release):
```bash
# In CT script, not install script:
fetch_and_deploy_gh_release "myapp" "app/repo" "app.tar.gz" "latest" "/opt/myapp"
```
### Database Setup
```bash
# Use setup_postgresql_db, setup_mysql_db, etc.
PG_DB_NAME="myapp"
PG_DB_USER="myapp"
setup_postgresql_db
```
### Node.js Setup
```bash
NODE_VERSION="20"
setup_nodejs
npm install --no-save
```
---
## Best Practices
1. **Only add app-specific dependencies**
- Don't add: ca-certificates, curl, gnupg, wget, git, jq
- These are handled by build.func
2. **Use tools.func helpers**
- setup_nodejs, setup_python, setup_uv, setup_postgresql_db, setup_mysql_db, etc.
3. **Don't do version checks in install script**
- Version checking happens in CT script's update_script()
- Install script just installs the latest
4. **Structure:**
- Dependencies
- Runtime setup (tools.func)
- Deployment (fetch from CT script)
- Configuration files
- Systemd service
- Finalization
---
## Reference Scripts
See working examples:
- [Trip](https://github.com/community-scripts/ProxmoxVE/blob/main/install/trip-install.sh)
- [Thingsboard](https://github.com/community-scripts/ProxmoxVE/blob/main/install/thingsboard-install.sh)
- [UniFi](https://github.com/community-scripts/ProxmoxVE/blob/main/install/unifi-install.sh)
---
## Need Help?
- **[Modern Template](AppName-install.sh)** - Start here
- **[CT Template](../templates_ct/AppName.sh)** - How CT scripts work
- **[README.md](../README.md)** - Full contribution workflow
- **[AI.md](../AI.md)** - AI-generated script guidelines
### 1.2 **Comments** ### 1.2 **Comments**
- Add clear comments for script metadata, including author, copyright, and license information. - Add clear comments for script metadata, including author, copyright, and license information.

View File

@@ -5,6 +5,7 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: [SOURCE_URL e.g. https://github.com/example/app] # Source: [SOURCE_URL e.g. https://github.com/example/app]
# Import Functions and Setup
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color color
verb_ip6 verb_ip6
@@ -14,73 +15,148 @@ network_check
update_os update_os
# ============================================================================= # =============================================================================
# DEPENDENCIES - Only add app-specific dependencies here! # DEPENDENCIES
# Don't add: ca-certificates, curl, gnupg, git, build-essential (handled by build.func)
# ============================================================================= # =============================================================================
# Only install what's actually needed - curl/sudo/mc are already in the base image
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y \ $STD apt install -y \
libharfbuzz0b \ nginx \
fontconfig build-essential
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
# ============================================================================= # =============================================================================
# SETUP RUNTIMES & DATABASES (if needed) # HELPER FUNCTIONS FROM tools.func
# ============================================================================= # =============================================================================
# Examples (uncomment as needed): # These functions are available via $FUNCTIONS_FILE_PATH (tools.func)
# Call them with optional environment variables for configuration
# #
# --- Runtime & Language Setup ---
# NODE_VERSION="22" setup_nodejs # Install Node.js (22, 24)
# NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs # With pnpm
# PYTHON_VERSION="3.13" setup_uv # Python with uv package manager
# setup_go # Install Go (latest)
# setup_rust # Install Rust via rustup
# setup_ruby # Install Ruby
# PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="mysqli,gd" setup_php
# PHP_VERSION="8.3" PHP_FPM="YES" PHP_APACHE="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,xml,zip" setup_php
# setup_composer # Install PHP Composer
# JAVA_VERSION="21" setup_java # Install Java (17, 21)
#
# --- Database Setup ---
# setup_mariadb # Install MariaDB server
# MARIADB_DB_NAME="mydb" MARIADB_DB_USER="myuser" setup_mariadb_db
# setup_mysql # Install MySQL server
# PG_VERSION="17" setup_postgresql # Install PostgreSQL (16, 17)
# PG_VERSION="17" PG_MODULES="postgis" setup_postgresql # With extensions
# PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db
# setup_mongodb # Install MongoDB
#
# --- GitHub Release (PREFERRED METHOD) ---
# fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" # Downloads, extracts, tracks version
# fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
# fetch_and_deploy_gh_release "appname" "owner/repo" "prebuild" "latest" "/opt/appname" "app-*.tar.gz"
#
# --- Tools & Utilities ---
# get_lxc_ip # Sets $LOCAL_IP variable (call early!)
# setup_ffmpeg # Install FFmpeg with codecs
# setup_hwaccel # Setup GPU hardware acceleration
# setup_imagemagick # Install ImageMagick 7
# setup_docker # Install Docker Engine
# setup_adminer # Install Adminer for DB management
# create_self_signed_cert # Creates cert in /etc/ssl/[appname]/
# =============================================================================
# EXAMPLE 1: Node.js Application with PostgreSQL
# =============================================================================
# NODE_VERSION="22" setup_nodejs # NODE_VERSION="22" setup_nodejs
# PYTHON_VERSION="3.13" setup_uv # PG_VERSION="17" setup_postgresql
# JAVA_VERSION="17" setup_java
# GO_VERSION="1.22" setup_go
# PHP_VERSION="8.4" PHP_FPM="YES" setup_php
# setup_postgresql # Server only
# setup_mariadb # Server only
#
# Then set up DB and user:
# PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db # PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db
# MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db # get_lxc_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
# =============================================================================
# DOWNLOAD & DEPLOY APPLICATION
# =============================================================================
# fetch_and_deploy_gh_release modes:
# "tarball" - Source tarball (default if omitted)
# "binary" - .deb package (auto-detects amd64/arm64)
# "prebuild" - Pre-built archive (.tar.gz)
# "singlefile" - Single binary file
# #
# Examples: # msg_info "Configuring MyApp"
# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "tarball" "latest" "/opt/myapp" # cd /opt/myapp
# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "binary" "latest" "/tmp" # $STD npm ci
# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz" # cat <<EOF >/opt/myapp/.env
# DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}
fetch_and_deploy_gh_release "[appname]" "owner/repo" "tarball" "latest" "/opt/[appname]" # HOST=${LOCAL_IP}
# PORT=3000
# EOF
# msg_ok "Configured MyApp"
# ============================================================================= # =============================================================================
# CONFIGURE APPLICATION # EXAMPLE 2: Python Application with uv
# =============================================================================
# PYTHON_VERSION="3.13" setup_uv
# get_lxc_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
#
# msg_info "Setting up MyApp"
# cd /opt/myapp
# $STD uv sync
# cat <<EOF >/opt/myapp/.env
# HOST=${LOCAL_IP}
# PORT=8000
# EOF
# msg_ok "Setup MyApp"
# =============================================================================
# EXAMPLE 3: PHP Application with MariaDB + Nginx
# =============================================================================
# PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,xml,zip" setup_php
# setup_composer
# setup_mariadb
# MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db
# get_lxc_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz"
#
# msg_info "Configuring MyApp"
# cd /opt/myapp
# cp .env.example .env
# sed -i "s|APP_URL=.*|APP_URL=http://${LOCAL_IP}|" .env
# sed -i "s|DB_DATABASE=.*|DB_DATABASE=${MARIADB_DB_NAME}|" .env
# sed -i "s|DB_USERNAME=.*|DB_USERNAME=${MARIADB_DB_USER}|" .env
# sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=${MARIADB_DB_PASS}|" .env
# $STD composer install --no-dev --no-interaction
# chown -R www-data:www-data /opt/myapp
# msg_ok "Configured MyApp"
# =============================================================================
# YOUR APPLICATION INSTALLATION
# =============================================================================
# 1. Setup runtimes and databases FIRST
# 2. Call get_lxc_ip if you need the container IP
# 3. Use fetch_and_deploy_gh_release to download the app (handles version tracking)
# 4. Configure the application
# 5. Create systemd service
# 6. Finalize with motd_ssh, customize, cleanup_lxc
# --- Setup runtimes/databases ---
NODE_VERSION="22" setup_nodejs
get_lxc_ip
# --- Download and install app ---
fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/[appname]"
msg_info "Setting up [AppName]"
cd /opt/[appname]
$STD npm ci
msg_ok "Setup [AppName]"
# =============================================================================
# CONFIGURATION
# ============================================================================= # =============================================================================
msg_info "Configuring [AppName]" msg_info "Configuring [AppName]"
cd /opt/[appname]
# Install application dependencies (uncomment as needed):
# $STD npm ci --production # Node.js apps
# $STD uv sync --frozen # Python apps
# $STD composer install --no-dev # PHP apps
# $STD cargo build --release # Rust apps
# Create .env file if needed:
cat <<EOF >/opt/[appname]/.env cat <<EOF >/opt/[appname]/.env
# Use import_local_ip to get container IP, or hardcode if building on Proxmox HOST=${LOCAL_IP}
APP_URL=http://localhost
PORT=8080 PORT=8080
EOF EOF
msg_ok "Configured [AppName]" msg_ok "Configured [AppName]"
# ============================================================================= # =============================================================================
# CREATE SYSTEMD SERVICE # SERVICE CREATION
# ============================================================================= # =============================================================================
msg_info "Creating Service" msg_info "Creating Service"
@@ -106,11 +182,9 @@ msg_ok "Created Service"
# ============================================================================= # =============================================================================
# CLEANUP & FINALIZATION # CLEANUP & FINALIZATION
# ============================================================================= # =============================================================================
# These are called automatically, but shown here for clarity:
# motd_ssh - Displays service info on SSH login
# customize - Enables optional customizations
# cleanup_lxc - Removes temp files, bash history, logs
motd_ssh motd_ssh
customize customize
# cleanup_lxc handles: apt autoremove, autoclean, temp files, bash history
cleanup_lxc cleanup_lxc

View File

@@ -4,26 +4,25 @@
"categories": [ "categories": [
0 0
], ],
"date_created": "2026-01-18", "date_created": "DATE CREATED",
"type": "ct", "type": "ct",
"updateable": true, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 3000, "interface_port": "DEFAULT-PORT",
"documentation": "https://docs.example.com/", "documentation": null,
"website": "https://example.com/", "website": "LINK TO WEBSITE",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/appname.webp", "logo": "LINK TO LOGO",
"config_path": "/opt/appname/.env", "description": "Description of the app",
"description": "Short description of what AppName does and its main features.",
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "ct/appname.sh", "script": "ct/AppName.sh",
"resources": { "resources": {
"cpu": 2, "cpu": 2,
"ram": 2048, "ram": 2048,
"hdd": 8, "hdd": 4,
"os": "Debian", "os": "debian",
"version": "13" "version": "12"
} }
} }
], ],
@@ -31,10 +30,5 @@
"username": null, "username": null,
"password": null "password": null
}, },
"notes": [ "notes": []
{
"text": "Change the default password after first login!",
"type": "warning"
}
]
} }

View File

@@ -1,165 +1,13 @@
# JSON Metadata Files - Quick Reference # **AppName<span></span>.json Files**
The metadata file (`frontend/public/json/myapp.json`) tells the web interface how to display your application. `AppName.json` files found in the `/json` directory. These files are used to provide informations for the website. For this guide we take `/json/snipeit.json` as example.
--- ## Table of Contents
## Quick Start - [**AppName.json Files**](#appnamejson-files)
- [Table of Contents](#table-of-contents)
- [1. JSON Generator](#1-json-generator)
**Use the JSON Generator Tool:** ## 1. JSON Generator
[https://community-scripts.github.io/ProxmoxVE/json-editor](https://community-scripts.github.io/ProxmoxVE/json-editor)
1. Enter application details Use the [JSON Generator](https://community-scripts.github.io/ProxmoxVE/json-editor) to create this file for your application.
2. Generator creates `frontend/public/json/myapp.json`
3. Copy the output to your contribution
---
## File Structure
```json
{
"name": "MyApp",
"slug": "myapp",
"categories": [1],
"date_created": "2026-01-18",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://docs.example.com/",
"website": "https://example.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/myapp.webp",
"config_path": "/opt/myapp/.env",
"description": "Brief description of what MyApp does",
"install_methods": [
{
"type": "default",
"script": "ct/myapp.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Change the default password after first login!",
"type": "warning"
}
]
}
```
---
## Field Reference
| Field | Required | Example | Notes |
| --------------------- | -------- | ----------------- | ---------------------------------------------- |
| `name` | Yes | "MyApp" | Display name |
| `slug` | Yes | "myapp" | URL-friendly identifier (lowercase, no spaces) |
| `categories` | Yes | [1] | One or more category IDs |
| `date_created` | Yes | "2026-01-18" | Format: YYYY-MM-DD |
| `type` | Yes | "ct" | Container type: "ct" or "vm" |
| `interface_port` | Yes | 3000 | Default web interface port |
| `logo` | No | "https://..." | Logo URL (64px x 64px PNG) |
| `config_path` | Yes | "/opt/myapp/.env" | Main config file location |
| `description` | Yes | "App description" | Brief description (100 chars) |
| `install_methods` | Yes | See below | Installation resources (array) |
| `default_credentials` | No | See below | Optional default login |
| `notes` | No | See below | Additional notes (array) |
---
## Install Methods
Each installation method specifies resource requirements:
```json
"install_methods": [
{
"type": "default",
"script": "ct/myapp.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
]
```
**Resource Defaults:**
- CPU: Cores (1-8)
- RAM: Megabytes (256-4096)
- Disk: Gigabytes (4-50)
---
## Common Categories
- `0` Miscellaneous
- `1` Proxmox & Virtualization
- `2` Operating Systems
- `3` Containers & Docker
- `4` Network & Firewall
- `5` Adblock & DNS
- `6` Authentication & Security
- `7` Backup & Recovery
- `8` Databases
- `9` Monitoring & Analytics
- `10` Dashboards & Frontends
- `11` Files & Downloads
- `12` Documents & Notes
- `13` Media & Streaming
- `14` \*Arr Suite
- `15` NVR & Cameras
- `16` IoT & Smart Home
- `17` ZigBee, Z-Wave & Matter
- `18` MQTT & Messaging
- `19` Automation & Scheduling
- `20` AI / Coding & Dev-Tools
- `21` Webservers & Proxies
- `22` Bots & ChatOps
- `23` Finance & Budgeting
- `24` Gaming & Leisure
- `25` Business & ERP
---
## Best Practices
1. **Use the JSON Generator** - It validates structure
2. **Keep descriptions short** - 100 characters max
3. **Use real resource requirements** - Based on your testing
4. **Include sensible defaults** - Pre-filled in install_methods
5. **Slug must be lowercase** - No spaces, use hyphens
---
## Reference Examples
See actual examples in the repo:
- [frontend/public/json/trip.json](https://github.com/community-scripts/ProxmoxVE/blob/main/frontend/public/json/trip.json)
- [frontend/public/json/thingsboard.json](https://github.com/community-scripts/ProxmoxVE/blob/main/frontend/public/json/thingsboard.json)
- [frontend/public/json/unifi.json](https://github.com/community-scripts/ProxmoxVE/blob/main/frontend/public/json/unifi.json)
---
## Need Help?
- **[JSON Generator](https://community-scripts.github.io/ProxmoxVE/json-editor)** - Interactive tool
- **[README.md](../README.md)** - Full contribution workflow
- **[Quick Start](../README.md)** - Step-by-step guide

View File

@@ -8,7 +8,7 @@
"type": "addon", "type": "addon",
"updateable": true, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": 3923,
"documentation": "https://github.com/9001/copyparty?tab=readme-ov-file#the-browser", "documentation": "https://github.com/9001/copyparty?tab=readme-ov-file#the-browser",
"website": "https://github.com/9001/copyparty", "website": "https://github.com/9001/copyparty",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/copyparty.webp", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/copyparty.webp",
@@ -35,6 +35,10 @@
{ {
"text": "Execute within the Proxmox shell or in LXC", "text": "Execute within the Proxmox shell or in LXC",
"type": "info" "type": "info"
},
{
"text": "Update with: update_copyparty",
"type": "info"
} }
] ]
} }

View File

@@ -23,7 +23,7 @@
"ram": 512, "ram": 512,
"hdd": 2, "hdd": 2,
"os": "debian", "os": "debian",
"version": "12" "version": "13"
} }
} }
], ],
@@ -35,10 +35,6 @@
{ {
"text": "Default credentials: `cat /root/hev.creds`", "text": "Default credentials: `cat /root/hev.creds`",
"type": "info" "type": "info"
},
{
"text": "Config stored at `/etc/hev-socks5-server/main.yml`",
"type": "info"
} }
] ]
} }

View File

@@ -23,7 +23,7 @@
"ram": 4096, "ram": 4096,
"hdd": 6, "hdd": 6,
"os": "debian", "os": "debian",
"version": "12" "version": "13"
} }
} }
], ],

View File

@@ -1,40 +0,0 @@
{
"name": "iVentoy",
"slug": "iventoy",
"categories": [
2
],
"date_created": "2024-05-16",
"type": "ct",
"updateable": false,
"privileged": false,
"interface_port": 26000,
"documentation": "https://www.iventoy.com/en/doc_news.html",
"website": "https://www.iventoy.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/iventoy.webp",
"config_path": "",
"description": "iVentoy is an upgraded PXE server that allows simultaneous OS booting and installation on multiple machines via network. It is user-friendly, requiring only the placement of ISO files in a designated folder and selecting PXE boot on the client machine. iVentoy supports x86 Legacy BIOS, IA32 UEFI, x86_64 UEFI, and ARM64 UEFI modes. It is compatible with over 110 OS types, including Windows, WinPE, Linux, and VMware.",
"install_methods": [
{
"type": "default",
"script": "ct/iventoy.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 2,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Container must be privileged.",
"type": "warning"
}
]
}

View File

@@ -8,7 +8,7 @@
"type": "ct", "type": "ct",
"updateable": true, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 3000, "interface_port": 8080,
"documentation": "https://github.com/Brandawg93/PeaNUT/blob/main/README.md", "documentation": "https://github.com/Brandawg93/PeaNUT/blob/main/README.md",
"website": "https://github.com/Brandawg93/PeaNUT/", "website": "https://github.com/Brandawg93/PeaNUT/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/peanut.webp", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/peanut.webp",

View File

@@ -1,35 +0,0 @@
{
"name": "phpIPAM",
"slug": "phpipam",
"categories": [
4
],
"date_created": "2025-01-15",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://phpipam.net/documents/all-documents/",
"website": "https://phpipam.net/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/phpipam.webp",
"config_path": "/opt/phpipam/config.php",
"description": "phpipam is an open-source web IP address management application (IPAM). Its goal is to provide light, modern and useful IP address management.",
"install_methods": [
{
"type": "default",
"script": "ct/phpipam.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "Admin",
"password": "ipamadmin"
},
"notes": []
}

View File

@@ -12,7 +12,7 @@
"documentation": "https://help.splunk.com", "documentation": "https://help.splunk.com",
"config_path": "", "config_path": "",
"website": "https://www.splunk.com/en_us/download/splunk-enterprise.html", "website": "https://www.splunk.com/en_us/download/splunk-enterprise.html",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/splunk.webp", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/splunk-light.webp",
"description": "Platform for searching, monitoring, and analyzing machine-generated data at scale for operational intelligence and security.", "description": "Platform for searching, monitoring, and analyzing machine-generated data at scale for operational intelligence and security.",
"install_methods": [ "install_methods": [
{ {
@@ -22,8 +22,8 @@
"cpu": 4, "cpu": 4,
"ram": 8192, "ram": 8192,
"hdd": 40, "hdd": 40,
"os": "Ubuntu", "os": "Debian",
"version": "24.04" "version": "13"
} }
} }
], ],

View File

@@ -0,0 +1,35 @@
{
"name": "Termix",
"slug": "termix",
"categories": [
6
],
"date_created": "2026-01-18",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://docs.termix.site/",
"website": "https://termix.site/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/termix.webp",
"config_path": "",
"description": "Termix is an open-source, self-hosted server management platform with SSH terminal access, SSH tunneling, remote file management, Docker management, and multi-platform support.",
"install_methods": [
{
"type": "default",
"script": "ct/termix.sh",
"resources": {
"cpu": 4,
"ram": 4096,
"hdd": 10,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,13 +1,103 @@
[ [
{
"name": "binwiederhier/ntfy",
"version": "v2.16.0",
"date": "2026-01-19T23:40:31Z"
},
{
"name": "inventree/InvenTree",
"version": "1.1.9",
"date": "2026-01-19T20:51:19Z"
},
{
"name": "ollama/ollama",
"version": "v0.14.3-rc2",
"date": "2026-01-19T20:48:34Z"
},
{
"name": "firefly-iii/firefly-iii",
"version": "v6.4.16",
"date": "2026-01-17T07:54:15Z"
},
{
"name": "metabase/metabase",
"version": "v0.58.x",
"date": "2026-01-19T18:21:04Z"
},
{
"name": "apache/tomcat",
"version": "11.0.16",
"date": "2026-01-19T18:15:05Z"
},
{
"name": "paperless-ngx/paperless-ngx",
"version": "v2.20.5",
"date": "2026-01-19T17:55:57Z"
},
{
"name": "ghostfolio/ghostfolio",
"version": "2.232.0",
"date": "2026-01-19T16:58:37Z"
},
{ {
"name": "laurent22/joplin", "name": "laurent22/joplin",
"version": "server-v3.5.2", "version": "server-v3.5.2",
"date": "2025-12-19T21:28:55Z" "date": "2025-12-19T21:28:55Z"
}, },
{ {
"name": "firefly-iii/firefly-iii", "name": "meilisearch/meilisearch",
"version": "v6.4.16", "version": "prototype-v1.33.0-hannoy-better-linear-scanning.4",
"date": "2026-01-17T07:54:15Z" "date": "2026-01-19T16:37:18Z"
},
{
"name": "Infisical/infisical",
"version": "v0.155.6",
"date": "2026-01-19T16:35:03Z"
},
{
"name": "bunkerity/bunkerweb",
"version": "v1.6.7",
"date": "2026-01-12T09:54:36Z"
},
{
"name": "msgbyte/tianji",
"version": "v1.31.8",
"date": "2026-01-19T16:13:13Z"
},
{
"name": "VictoriaMetrics/VictoriaMetrics",
"version": "pmm-6401-v1.134.0",
"date": "2026-01-19T13:31:08Z"
},
{
"name": "keycloak/keycloak",
"version": "26.4.8",
"date": "2026-01-15T13:52:29Z"
},
{
"name": "crowdsecurity/crowdsec",
"version": "v1.7.4",
"date": "2025-12-04T13:56:39Z"
},
{
"name": "home-assistant/operating-system",
"version": "17.0",
"date": "2026-01-19T11:11:37Z"
},
{
"name": "TuroYT/snowshare",
"version": "v1.2.10",
"date": "2026-01-19T10:13:52Z"
},
{
"name": "AlexxIT/go2rtc",
"version": "v1.9.14",
"date": "2026-01-19T09:16:56Z"
},
{
"name": "dgtlmoon/changedetection.io",
"version": "0.52.7",
"date": "2026-01-19T08:38:05Z"
}, },
{ {
"name": "morpheus65535/bazarr", "name": "morpheus65535/bazarr",
@@ -16,8 +106,93 @@
}, },
{ {
"name": "Jackett/Jackett", "name": "Jackett/Jackett",
"version": "v0.24.879", "version": "v0.24.887",
"date": "2026-01-18T05:55:29Z" "date": "2026-01-19T05:55:24Z"
},
{
"name": "gethomepage/homepage",
"version": "v1.9.0",
"date": "2026-01-19T05:46:09Z"
},
{
"name": "nickheyer/discopanel",
"version": "v1.0.23",
"date": "2026-01-19T05:14:43Z"
},
{
"name": "9001/copyparty",
"version": "v1.20.2",
"date": "2026-01-19T02:20:10Z"
},
{
"name": "jellyfin/jellyfin",
"version": "v10.11.6",
"date": "2026-01-19T01:03:03Z"
},
{
"name": "eclipse-mosquitto/mosquitto",
"version": "2.1.0rc1",
"date": "2026-01-19T00:48:21Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.1.0",
"date": "2025-11-23T12:13:34Z"
},
{
"name": "jeedom/core",
"version": "4.5.2",
"date": "2026-01-19T00:27:05Z"
},
{
"name": "Kareadita/Kavita",
"version": "v0.8.9.1",
"date": "2026-01-18T23:04:08Z"
},
{
"name": "pelican-dev/panel",
"version": "v1.0.0-beta31",
"date": "2026-01-18T22:43:24Z"
},
{
"name": "pelican-dev/wings",
"version": "v1.0.0-beta22",
"date": "2026-01-18T22:38:36Z"
},
{
"name": "Part-DB/Part-DB-server",
"version": "v2.5.0",
"date": "2026-01-18T22:16:38Z"
},
{
"name": "seerr-team/seerr",
"version": "preview-remonitor-sonarr-episodes",
"date": "2026-01-18T20:33:38Z"
},
{
"name": "fccview/jotty",
"version": "1.18.0",
"date": "2026-01-18T19:00:48Z"
},
{
"name": "Brandawg93/PeaNUT",
"version": "v5.21.2",
"date": "2026-01-18T17:32:08Z"
},
{
"name": "pocketbase/pocketbase",
"version": "v0.36.1",
"date": "2026-01-18T17:09:58Z"
},
{
"name": "pommee/goaway",
"version": "v0.63.5",
"date": "2026-01-18T13:34:16Z"
},
{
"name": "wger-project/wger",
"version": "2.4",
"date": "2026-01-18T12:12:02Z"
}, },
{ {
"name": "BerriAI/litellm", "name": "BerriAI/litellm",
@@ -29,16 +204,6 @@
"version": "2.1.1", "version": "2.1.1",
"date": "2025-06-14T17:45:06Z" "date": "2025-06-14T17:45:06Z"
}, },
{
"name": "steveiliop56/tinyauth",
"version": "v4.1.0",
"date": "2025-11-23T12:13:34Z"
},
{
"name": "jeedom/core",
"version": "4.5.2",
"date": "2026-01-18T00:27:03Z"
},
{ {
"name": "oauth2-proxy/oauth2-proxy", "name": "oauth2-proxy/oauth2-proxy",
"version": "v7.14.2", "version": "v7.14.2",
@@ -69,21 +234,6 @@
"version": "v0.4.1", "version": "v0.4.1",
"date": "2026-01-17T12:24:31Z" "date": "2026-01-17T12:24:31Z"
}, },
{
"name": "inventree/InvenTree",
"version": "1.1.8",
"date": "2026-01-17T11:21:36Z"
},
{
"name": "nickheyer/discopanel",
"version": "v1.0.22",
"date": "2026-01-17T11:09:45Z"
},
{
"name": "ghostfolio/ghostfolio",
"version": "2.231.0",
"date": "2026-01-17T11:01:23Z"
},
{ {
"name": "forgejo/forgejo", "name": "forgejo/forgejo",
"version": "v14.0.1", "version": "v14.0.1",
@@ -104,21 +254,6 @@
"version": "v4.108.1", "version": "v4.108.1",
"date": "2026-01-17T04:09:09Z" "date": "2026-01-17T04:09:09Z"
}, },
{
"name": "seerr-team/seerr",
"version": "preview-axios-config",
"date": "2026-01-17T02:07:56Z"
},
{
"name": "ollama/ollama",
"version": "v0.14.2",
"date": "2026-01-16T00:50:51Z"
},
{
"name": "metabase/metabase",
"version": "v0.58.2",
"date": "2026-01-16T22:54:44Z"
},
{ {
"name": "home-assistant/core", "name": "home-assistant/core",
"version": "2026.1.2", "version": "2026.1.2",
@@ -129,11 +264,6 @@
"version": "v1.13.0", "version": "v1.13.0",
"date": "2026-01-16T20:26:34Z" "date": "2026-01-16T20:26:34Z"
}, },
{
"name": "keycloak/keycloak",
"version": "26.4.8",
"date": "2026-01-15T13:52:29Z"
},
{ {
"name": "homarr-labs/homarr", "name": "homarr-labs/homarr",
"version": "v1.50.1", "version": "v1.50.1",
@@ -141,29 +271,19 @@
}, },
{ {
"name": "livebook-dev/livebook", "name": "livebook-dev/livebook",
"version": "nightly", "version": "v0.18.3",
"date": "2026-01-16T19:17:16Z" "date": "2026-01-14T21:50:55Z"
},
{
"name": "cloudflare/cloudflared",
"version": "2026.1.0",
"date": "2026-01-16T17:48:15Z"
}, },
{ {
"name": "n8n-io/n8n", "name": "n8n-io/n8n",
"version": "n8n@2.3.6", "version": "n8n@2.3.6",
"date": "2026-01-16T15:00:42Z" "date": "2026-01-16T15:00:42Z"
}, },
{
"name": "bunkerity/bunkerweb",
"version": "v1.6.7",
"date": "2026-01-12T09:54:36Z"
},
{
"name": "Brandawg93/PeaNUT",
"version": "v5.21.1",
"date": "2026-01-16T16:20:21Z"
},
{
"name": "TuroYT/snowshare",
"version": "v1.2.10",
"date": "2026-01-16T15:18:09Z"
},
{ {
"name": "emqx/emqx", "name": "emqx/emqx",
"version": "6.0.2", "version": "6.0.2",
@@ -189,11 +309,6 @@
"version": "v1.11.1", "version": "v1.11.1",
"date": "2026-01-16T08:27:09Z" "date": "2026-01-16T08:27:09Z"
}, },
{
"name": "pocketbase/pocketbase",
"version": "v0.36.0",
"date": "2026-01-16T04:51:49Z"
},
{ {
"name": "goauthentik/authentik", "name": "goauthentik/authentik",
"version": "version/2025.12.1", "version": "version/2025.12.1",
@@ -209,11 +324,6 @@
"version": "v2.17.0-rc3", "version": "v2.17.0-rc3",
"date": "2026-01-15T21:30:26Z" "date": "2026-01-15T21:30:26Z"
}, },
{
"name": "dgtlmoon/changedetection.io",
"version": "0.52.6",
"date": "2026-01-15T21:29:48Z"
},
{ {
"name": "azukaar/Cosmos-Server", "name": "azukaar/Cosmos-Server",
"version": "v0.20.0", "version": "v0.20.0",
@@ -221,8 +331,8 @@
}, },
{ {
"name": "runtipi/runtipi", "name": "runtipi/runtipi",
"version": "v4.7.0-beta.1", "version": "nightly",
"date": "2026-01-15T20:00:44Z" "date": "2026-01-15T20:03:50Z"
}, },
{ {
"name": "Stirling-Tools/Stirling-PDF", "name": "Stirling-Tools/Stirling-PDF",
@@ -264,11 +374,6 @@
"version": "v10.11.10", "version": "v10.11.10",
"date": "2026-01-15T10:36:07Z" "date": "2026-01-15T10:36:07Z"
}, },
{
"name": "meilisearch/meilisearch",
"version": "latest",
"date": "2026-01-15T09:49:28Z"
},
{ {
"name": "SigNoz/signoz", "name": "SigNoz/signoz",
"version": "v0.107.0", "version": "v0.107.0",
@@ -284,11 +389,6 @@
"version": "1.14.1-s.3", "version": "1.14.1-s.3",
"date": "2026-01-15T06:09:56Z" "date": "2026-01-15T06:09:56Z"
}, },
{
"name": "Infisical/infisical",
"version": "v0.155.5",
"date": "2026-01-15T05:25:10Z"
},
{ {
"name": "tailscale/tailscale", "name": "tailscale/tailscale",
"version": "v1.95.0-pre", "version": "v1.95.0-pre",
@@ -299,16 +399,6 @@
"version": "v0.24.0", "version": "v0.24.0",
"date": "2026-01-14T21:28:09Z" "date": "2026-01-14T21:28:09Z"
}, },
{
"name": "Kareadita/Kavita",
"version": "v0.8.9",
"date": "2026-01-14T21:26:43Z"
},
{
"name": "fccview/jotty",
"version": "1.17.2",
"date": "2026-01-14T19:06:52Z"
},
{ {
"name": "NodeBB/NodeBB", "name": "NodeBB/NodeBB",
"version": "v4.8.0", "version": "v4.8.0",
@@ -379,11 +469,6 @@
"version": "v1.12.1", "version": "v1.12.1",
"date": "2026-01-13T20:39:22Z" "date": "2026-01-13T20:39:22Z"
}, },
{
"name": "paperless-ngx/paperless-ngx",
"version": "v2.20.4",
"date": "2026-01-13T18:52:08Z"
},
{ {
"name": "community-scripts/ProxmoxVE-Local", "name": "community-scripts/ProxmoxVE-Local",
"version": "v0.5.5", "version": "v0.5.5",
@@ -394,11 +479,6 @@
"version": "v1.145.0", "version": "v1.145.0",
"date": "2026-01-13T16:49:51Z" "date": "2026-01-13T16:49:51Z"
}, },
{
"name": "msgbyte/tianji",
"version": "v1.31.7",
"date": "2026-01-13T16:12:12Z"
},
{ {
"name": "LimeSurvey/LimeSurvey", "name": "LimeSurvey/LimeSurvey",
"version": "6.16.3+251215", "version": "6.16.3+251215",
@@ -547,7 +627,7 @@
{ {
"name": "theonedev/onedev", "name": "theonedev/onedev",
"version": "v14.0.7", "version": "v14.0.7",
"date": "2026-01-10T15:10:54Z" "date": "2026-01-10T10:31:47Z"
}, },
{ {
"name": "Kozea/Radicale", "name": "Kozea/Radicale",
@@ -584,11 +664,6 @@
"version": "@fumadocs/base-ui@16.4.6", "version": "@fumadocs/base-ui@16.4.6",
"date": "2026-01-09T10:54:11Z" "date": "2026-01-09T10:54:11Z"
}, },
{
"name": "9001/copyparty",
"version": "v1.20.1",
"date": "2026-01-09T01:30:37Z"
},
{ {
"name": "webmin/webmin", "name": "webmin/webmin",
"version": "2.620", "version": "2.620",
@@ -619,11 +694,6 @@
"version": "v2.2.0.103-2.2.0.103_canary_2026-01-08", "version": "v2.2.0.103-2.2.0.103_canary_2026-01-08",
"date": "2026-01-08T12:41:37Z" "date": "2026-01-08T12:41:37Z"
}, },
{
"name": "home-assistant/operating-system",
"version": "16.3",
"date": "2025-11-04T12:28:47Z"
},
{ {
"name": "Graylog2/graylog2-server", "name": "Graylog2/graylog2-server",
"version": "6.2.11", "version": "6.2.11",
@@ -724,11 +794,6 @@
"version": "v1.12.0", "version": "v1.12.0",
"date": "2026-01-06T00:10:39Z" "date": "2026-01-06T00:10:39Z"
}, },
{
"name": "VictoriaMetrics/VictoriaMetrics",
"version": "pmm-6401-v1.133.0",
"date": "2026-01-05T18:31:47Z"
},
{ {
"name": "maxdorninger/MediaManager", "name": "maxdorninger/MediaManager",
"version": "v1.12.1", "version": "v1.12.1",
@@ -739,11 +804,6 @@
"version": "v5.2.0", "version": "v5.2.0",
"date": "2026-01-05T05:56:57Z" "date": "2026-01-05T05:56:57Z"
}, },
{
"name": "Part-DB/Part-DB-server",
"version": "v2.4.0",
"date": "2026-01-04T21:10:51Z"
},
{ {
"name": "actualbudget/actual", "name": "actualbudget/actual",
"version": "v26.1.0", "version": "v26.1.0",
@@ -784,11 +844,6 @@
"version": "2.2.2", "version": "2.2.2",
"date": "2025-12-31T16:53:34Z" "date": "2025-12-31T16:53:34Z"
}, },
{
"name": "pommee/goaway",
"version": "v0.63.4",
"date": "2025-12-31T12:40:07Z"
},
{ {
"name": "BookStackApp/BookStack", "name": "BookStackApp/BookStack",
"version": "v25.12.1", "version": "v25.12.1",
@@ -929,16 +984,6 @@
"version": "v14.3.0", "version": "v14.3.0",
"date": "2025-12-20T13:16:37Z" "date": "2025-12-20T13:16:37Z"
}, },
{
"name": "pelican-dev/panel",
"version": "v1.0.0-beta30",
"date": "2025-12-19T23:37:07Z"
},
{
"name": "pelican-dev/wings",
"version": "v1.0.0-beta21",
"date": "2025-12-19T23:04:27Z"
},
{ {
"name": "qdrant/qdrant", "name": "qdrant/qdrant",
"version": "v1.16.3", "version": "v1.16.3",
@@ -994,16 +1039,6 @@
"version": "v4.2.2", "version": "v4.2.2",
"date": "2025-12-15T18:25:36Z" "date": "2025-12-15T18:25:36Z"
}, },
{
"name": "jellyfin/jellyfin",
"version": "v10.11.5",
"date": "2025-12-15T02:44:19Z"
},
{
"name": "AlexxIT/go2rtc",
"version": "v1.9.13",
"date": "2025-12-14T20:18:28Z"
},
{ {
"name": "docmost/docmost", "name": "docmost/docmost",
"version": "v0.24.1", "version": "v0.24.1",
@@ -1054,11 +1089,6 @@
"version": "0.43.1", "version": "0.43.1",
"date": "2025-12-11T22:45:52Z" "date": "2025-12-11T22:45:52Z"
}, },
{
"name": "gethomepage/homepage",
"version": "v1.8.0",
"date": "2025-12-10T16:44:33Z"
},
{ {
"name": "rclone/rclone", "name": "rclone/rclone",
"version": "v1.72.1", "version": "v1.72.1",
@@ -1129,21 +1159,11 @@
"version": "v1.8.3", "version": "v1.8.3",
"date": "2025-12-04T21:07:00Z" "date": "2025-12-04T21:07:00Z"
}, },
{
"name": "crowdsecurity/crowdsec",
"version": "v1.7.4",
"date": "2025-12-04T13:56:39Z"
},
{ {
"name": "glpi-project/glpi", "name": "glpi-project/glpi",
"version": "11.0.4", "version": "11.0.4",
"date": "2025-12-04T09:26:37Z" "date": "2025-12-04T09:26:37Z"
}, },
{
"name": "apache/tomcat",
"version": "10.1.50",
"date": "2025-12-02T22:59:59Z"
},
{ {
"name": "WordPress/WordPress", "name": "WordPress/WordPress",
"version": "6.9", "version": "6.9",
@@ -1274,11 +1294,6 @@
"version": "v0.28.2", "version": "v0.28.2",
"date": "2025-11-18T05:51:46Z" "date": "2025-11-18T05:51:46Z"
}, },
{
"name": "binwiederhier/ntfy",
"version": "v2.15.0",
"date": "2025-11-16T18:53:49Z"
},
{ {
"name": "bastienwirtz/homer", "name": "bastienwirtz/homer",
"version": "v25.11.1", "version": "v25.11.1",
@@ -1319,11 +1334,6 @@
"version": "2.11.1", "version": "2.11.1",
"date": "2025-11-08T14:27:27Z" "date": "2025-11-08T14:27:27Z"
}, },
{
"name": "cloudflare/cloudflared",
"version": "2025.11.1",
"date": "2025-11-07T17:05:45Z"
},
{ {
"name": "deuxfleurs-org/garage", "name": "deuxfleurs-org/garage",
"version": "v1.99.3-internal", "version": "v1.99.3-internal",
@@ -1459,11 +1469,6 @@
"version": "v0.18.3", "version": "v0.18.3",
"date": "2025-09-19T16:16:11Z" "date": "2025-09-19T16:16:11Z"
}, },
{
"name": "eclipse-mosquitto/mosquitto",
"version": "2.1.0-test1",
"date": "2025-09-17T18:21:45Z"
},
{ {
"name": "Checkmk/checkmk", "name": "Checkmk/checkmk",
"version": "v2.4.0p12", "version": "v2.4.0p12",
@@ -1629,11 +1634,6 @@
"version": "v0.2.11", "version": "v0.2.11",
"date": "2025-04-12T21:13:08Z" "date": "2025-04-12T21:13:08Z"
}, },
{
"name": "wger-project/wger",
"version": "2.3",
"date": "2025-04-05T18:05:36Z"
},
{ {
"name": "louislam/dockge", "name": "louislam/dockge",
"version": "1.5.0", "version": "1.5.0",

View File

@@ -0,0 +1,35 @@
{
"name": "Yubal",
"slug": "yubal",
"categories": [
13
],
"date_created": "2026-01-19",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8000,
"documentation": "https://github.com/guillevc/yubal/blob/master/README.md",
"website": "https://github.com/guillevc/yubal",
"config_path": "/opt/yubal.env",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/yubal.webp",
"description": "YouTube Music album downloader with Spotify metadata auto-tagging.",
"install_methods": [
{
"type": "default",
"script": "ct/yubal.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 15,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -17,12 +17,11 @@ msg_info "Installing Dependencies"
$STD apt install -y nginx $STD apt install -y nginx
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
PHP_VERSION="8.4" PHP_VERSION="8.4" PHP_MODULE="common,ctype,fileinfo,mysql,tokenizer,dom,redis" PHP_FPM="YES" setup_php
PHP_MODULE="common,ctype,fileinfo,mysql,tokenizer,dom,redis" PHP_FPM="YES" setup_php
setup_composer setup_composer
setup_mariadb setup_mariadb
MARIADB_DB_NAME="2fauth_db" MARIADB_DB_USER="2fauth" setup_mariadb_db MARIADB_DB_NAME="2fauth_db" MARIADB_DB_USER="2fauth" setup_mariadb_db
import_local_ip
fetch_and_deploy_gh_release "2fauth" "Bubka/2FAuth" "tarball" fetch_and_deploy_gh_release "2fauth" "Bubka/2FAuth" "tarball"
msg_info "Setup 2FAuth" msg_info "Setup 2FAuth"

View File

@@ -26,8 +26,8 @@ PYTHON_VERSION="3.13" setup_uv
NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs
PG_VERSION="17" PG_MODULES="postgis" setup_postgresql PG_VERSION="17" PG_MODULES="postgis" setup_postgresql
PG_DB_NAME="adventurelog_db" PG_DB_USER="adventurelog_user" PG_DB_EXTENSIONS="postgis" setup_postgresql_db PG_DB_NAME="adventurelog_db" PG_DB_USER="adventurelog_user" PG_DB_EXTENSIONS="postgis" setup_postgresql_db
fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog" "tarball" fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog" "tarball"
import_local_ip
msg_info "Installing AdventureLog (Patience)" msg_info "Installing AdventureLog (Patience)"
SECRET_KEY="$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)" SECRET_KEY="$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)"

View File

@@ -75,7 +75,6 @@ mkdir -p /opt/bar-assistant/resources/data
curl -fsSL https://github.com/bar-assistant/data/archive/refs/heads/v5.tar.gz | tar -xz --strip-components=1 -C /opt/bar-assistant/resources/data curl -fsSL https://github.com/bar-assistant/data/archive/refs/heads/v5.tar.gz | tar -xz --strip-components=1 -C /opt/bar-assistant/resources/data
MeiliSearch_API_KEY=$(curl -s -X GET 'http://127.0.0.1:7700/keys' -H "Authorization: Bearer $MASTER_KEY" | grep -o '"key":"[^"]*"' | head -n 1 | sed 's/"key":"//;s/"//') MeiliSearch_API_KEY=$(curl -s -X GET 'http://127.0.0.1:7700/keys' -H "Authorization: Bearer $MASTER_KEY" | grep -o '"key":"[^"]*"' | head -n 1 | sed 's/"key":"//;s/"//')
MeiliSearch_API_KEY_UID=$(curl -s -X GET 'http://127.0.0.1:7700/keys' -H "Authorization: Bearer $MASTER_KEY" | grep -o '"uid":"[^"]*"' | head -n 1 | sed 's/"uid":"//;s/"//') MeiliSearch_API_KEY_UID=$(curl -s -X GET 'http://127.0.0.1:7700/keys' -H "Authorization: Bearer $MASTER_KEY" | grep -o '"uid":"[^"]*"' | head -n 1 | sed 's/"uid":"//;s/"//')
LOCAL_IP=$(hostname -I | awk '{print $1}')
sed -i -e "s|^APP_URL=|APP_URL=http://${LOCAL_IP}/bar/|" \ sed -i -e "s|^APP_URL=|APP_URL=http://${LOCAL_IP}/bar/|" \
-e "s|^MEILISEARCH_HOST=|MEILISEARCH_HOST=http://127.0.0.1:7700|" \ -e "s|^MEILISEARCH_HOST=|MEILISEARCH_HOST=http://127.0.0.1:7700|" \
-e "s|^MEILISEARCH_KEY=|MEILISEARCH_KEY=${MASTER_KEY}|" \ -e "s|^MEILISEARCH_KEY=|MEILISEARCH_KEY=${MASTER_KEY}|" \

View File

@@ -21,8 +21,8 @@ PHP_MODULE="ldap,tidy,bz2,mysqli" PHP_FPM="YES" PHP_APACHE="YES" PHP_VERSION="8.
setup_composer setup_composer
setup_mariadb setup_mariadb
MARIADB_DB_NAME="bookstack_db" MARIADB_DB_USER="bookstack_user" setup_mariadb_db MARIADB_DB_NAME="bookstack_db" MARIADB_DB_USER="bookstack_user" setup_mariadb_db
fetch_and_deploy_gh_release "bookstack" "BookStackApp/BookStack" "tarball" fetch_and_deploy_gh_release "bookstack" "BookStackApp/BookStack" "tarball"
import_local_ip
msg_info "Configuring Bookstack (Patience)" msg_info "Configuring Bookstack (Patience)"
cd /opt/bookstack cd /opt/bookstack

View File

@@ -17,11 +17,10 @@ NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "cronicle" "jhuckaby/Cronicle" "tarball" fetch_and_deploy_gh_release "cronicle" "jhuckaby/Cronicle" "tarball"
msg_info "Configuring Cronicle Primary Server" msg_info "Configuring Cronicle Primary Server"
IP=$(hostname -I | awk '{print $1}')
cd /opt/cronicle cd /opt/cronicle
$STD npm install $STD npm install
$STD node bin/build.js dist $STD node bin/build.js dist
sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json sed -i "s/localhost:3012/${LOCAL_IP}:3012/g" /opt/cronicle/conf/config.json
$STD /opt/cronicle/bin/control.sh setup $STD /opt/cronicle/bin/control.sh setup
$STD /opt/cronicle/bin/control.sh start $STD /opt/cronicle/bin/control.sh start
msg_ok "Configured Cronicle Primary Server" msg_ok "Configured Cronicle Primary Server"

View File

@@ -28,8 +28,7 @@ $STD npm ci
$STD npm run install:components $STD npm run install:components
$STD npm run build $STD npm run build
cp config/config.example.js config/config.js cp config/config.example.js config/config.js
IP=$(hostname -I | awk '{print $1}') sed -i "51s/localhost/${LOCAL_IP}/g" /opt/cryptpad/config/config.js
sed -i "51s/localhost/${IP}/g" /opt/cryptpad/config/config.js
sed -i "80s#//httpAddress: 'localhost'#httpAddress: '0.0.0.0'#g" /opt/cryptpad/config/config.js sed -i "80s#//httpAddress: 'localhost'#httpAddress: '0.0.0.0'#g" /opt/cryptpad/config/config.js
if [[ "$onlyoffice" =~ ^[Yy]$ ]]; then if [[ "$onlyoffice" =~ ^[Yy]$ ]]; then
$STD bash -c "./install-onlyoffice.sh --accept-license" $STD bash -c "./install-onlyoffice.sh --accept-license"

View File

@@ -22,7 +22,6 @@ msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/docmost/docmost/main/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs NODE_VERSION="22" NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/docmost/docmost/main/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs
PG_VERSION="16" setup_postgresql PG_VERSION="16" setup_postgresql
PG_DB_NAME="docmost_db" PG_DB_USER="docmost_user" setup_postgresql_db PG_DB_NAME="docmost_db" PG_DB_USER="docmost_user" setup_postgresql_db
import_local_ip
fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball" fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball"
msg_info "Configuring Docmost (Patience)" msg_info "Configuring Docmost (Patience)"

View File

@@ -21,7 +21,6 @@ PYTHON_VERSION="3.13" setup_uv
NODE_VERSION="24" setup_nodejs NODE_VERSION="24" setup_nodejs
PG_VERSION="17" PG_MODULES="postgis" setup_postgresql PG_VERSION="17" PG_MODULES="postgis" setup_postgresql
PG_DB_NAME="enduraindb" PG_DB_USER="endurain" setup_postgresql_db PG_DB_NAME="enduraindb" PG_DB_USER="endurain" setup_postgresql_db
import_local_ip
fetch_and_deploy_gh_release "endurain" "endurain-project/endurain" "tarball" "latest" "/opt/endurain" fetch_and_deploy_gh_release "endurain" "endurain-project/endurain" "tarball" "latest" "/opt/endurain"
msg_info "Setting up Endurain" msg_info "Setting up Endurain"

View File

@@ -17,7 +17,7 @@ PHP_VERSION="8.4" PHP_APACHE="YES" PHP_MODULE="mysql" setup_php
setup_composer setup_composer
setup_mariadb setup_mariadb
MARIADB_DB_NAME="firefly" MARIADB_DB_USER="firefly" setup_mariadb_db MARIADB_DB_NAME="firefly" MARIADB_DB_USER="firefly" setup_mariadb_db
import_local_ip
fetch_and_deploy_gh_release "firefly" "firefly-iii/firefly-iii" "prebuild" "latest" "/opt/firefly" "FireflyIII-*.zip" fetch_and_deploy_gh_release "firefly" "firefly-iii/firefly-iii" "prebuild" "latest" "/opt/firefly" "FireflyIII-*.zip"
fetch_and_deploy_gh_release "dataimporter" "firefly-iii/data-importer" "prebuild" "latest" "/opt/firefly/dataimporter" "DataImporter-v*.tar.gz" fetch_and_deploy_gh_release "dataimporter" "firefly-iii/data-importer" "prebuild" "latest" "/opt/firefly/dataimporter" "DataImporter-v*.tar.gz"

View File

@@ -18,31 +18,15 @@ $STD apt-get install -y zip
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="fluiddb" PG_DB_USER="fluiduser" setup_postgresql_db
NODE_VERSION="20" setup_nodejs NODE_VERSION="20" setup_nodejs
msg_info "Setting up Postgresql Database"
DB_NAME="fluiddb"
DB_USER="fluiduser"
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)"
NEXTAUTH_SECRET="$(openssl rand -base64 44 | tr -dc 'a-zA-Z0-9' | cut -c1-32)"
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME to $DB_USER;"
$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;"
{
echo "${APPLICATION} Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
echo "NextAuth Secret: $NEXTAUTH_SECRET"
} >>~/$APPLICATION.creds
msg_ok "Set up Postgresql Database"
fetch_and_deploy_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar" "tarball" fetch_and_deploy_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar" "tarball"
msg_info "Configuring ${APPLICATION}" msg_info "Configuring fluid-calendar"
NEXTAUTH_SECRET="$(openssl rand -base64 44 | tr -dc 'a-zA-Z0-9' | cut -c1-32)"
echo "NextAuth Secret: $NEXTAUTH_SECRET" >>~/$APPLICATION.creds
cat <<EOF >/opt/fluid-calendar/.env cat <<EOF >/opt/fluid-calendar/.env
DATABASE_URL="postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}" DATABASE_URL="postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}"
# Change the URL below to your external URL # Change the URL below to your external URL
NEXTAUTH_URL="http://localhost:3000" NEXTAUTH_URL="http://localhost:3000"
@@ -61,7 +45,7 @@ $STD npm install --legacy-peer-deps
$STD npm run prisma:generate $STD npm run prisma:generate
$STD npx prisma migrate deploy $STD npx prisma migrate deploy
$STD npm run build:os $STD npm run build:os
msg_ok "Configuring ${APPLICATION}" msg_ok "Configured fluid-calendar"
msg_info "Creating Service" msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/fluid-calendar.service cat <<EOF >/etc/systemd/system/fluid-calendar.service
@@ -72,6 +56,7 @@ After=network.target postgresql.service
[Service] [Service]
Restart=always Restart=always
WorkingDirectory=/opt/fluid-calendar WorkingDirectory=/opt/fluid-calendar
EnvironmentFile=/opt/fluid-calendar/.env
ExecStart=/usr/bin/npm run start ExecStart=/usr/bin/npm run start
[Install] [Install]

View File

@@ -39,14 +39,13 @@ msg_ok "Installed gitea-mirror"
msg_info "Creating Services" msg_info "Creating Services"
APP_SECRET=$(openssl rand -base64 32) APP_SECRET=$(openssl rand -base64 32)
APP_VERSION=$(grep -o '"version": *"[^"]*"' package.json | cut -d'"' -f4) APP_VERSION=$(grep -o '"version": *"[^"]*"' package.json | cut -d'"' -f4)
HOST_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/opt/gitea-mirror.env cat <<EOF >/opt/gitea-mirror.env
# See here for config options: https://github.com/RayLabsHQ/gitea-mirror/blob/main/docs/ENVIRONMENT_VARIABLES.md # See here for config options: https://github.com/RayLabsHQ/gitea-mirror/blob/main/docs/ENVIRONMENT_VARIABLES.md
NODE_ENV=production NODE_ENV=production
HOST=0.0.0.0 HOST=0.0.0.0
PORT=4321 PORT=4321
DATABASE_URL=sqlite://data/gitea-mirror.db DATABASE_URL=sqlite://data/gitea-mirror.db
BETTER_AUTH_URL=http://${HOST_IP}:4321 BETTER_AUTH_URL=http://${LOCAL_IP}:4321
BETTER_AUTH_SECRET=${APP_SECRET} BETTER_AUTH_SECRET=${APP_SECRET}
npm_package_version=${APP_VERSION} npm_package_version=${APP_VERSION}
EOF EOF

View File

@@ -54,7 +54,6 @@ $STD pip install --upgrade pip wheel
$STD pip install gunicorn -r requirements.txt $STD pip install gunicorn -r requirements.txt
msg_ok "Installed Python packages" msg_ok "Installed Python packages"
LOCAL_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/opt/healthchecks/hc/local_settings.py cat <<EOF >/opt/healthchecks/hc/local_settings.py
DEBUG = False DEBUG = False

View File

@@ -13,36 +13,30 @@ setting_up_container
network_check network_check
update_os update_os
msg_info "Setup ${APPLICATION}" fetch_and_deploy_gh_release "hev-socks5-server" "heiher/hev-socks5-server" "singlefile" "latest" "/opt" "hev-socks5-server-linux-x86_64"
RELEASE=$(curl -fsSL https://api.github.com/repos/heiher/${APPLICATION}/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
curl -L -o "${APPLICATION}" "https://github.com/heiher/${APPLICATION}/releases/download/${RELEASE}/hev-socks5-server-linux-x86_64" msg_info "Setup hev-socks5-server"
mv ${APPLICATION} /opt/${APPLICATION} mkdir -p /etc/hev-socks5-server
chmod +x /opt/${APPLICATION} download_file "https://raw.githubusercontent.com/heiher/hev-socks5-server/refs/heads/main/conf/main.yml" "/etc/hev-socks5-server/main.yml"
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt sed -i 's/^#auth:/auth:/; s/^# file: conf\/auth.txt/ file: \/root\/hev.creds/' /etc/hev-socks5-server/main.yml
curl -L -o "main.yml" "https://raw.githubusercontent.com/heiher/${APPLICATION}/refs/heads/main/conf/main.yml"
sed -i 's/^#auth:/auth:/; s/^# file: conf\/auth.txt/ file: \/root\/hev.creds/' main.yml
mkdir -p /etc/${APPLICATION}
USERNAME="admin"
PASSWORD=$(openssl rand -base64 16) PASSWORD=$(openssl rand -base64 16)
MARK="0" echo "admin $PASSWORD 0" >/root/hev.creds
echo "$USERNAME $PASSWORD $MARK" >/root/hev.creds msg_ok "Setup hev-socks5-server"
mv main.yml /etc/${APPLICATION}/main.yml
msg_ok "Setup ${APPLICATION}"
msg_info "Creating Service" msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/${APPLICATION}.service cat <<EOF >/etc/systemd/system/hev-socks5-server.service
[Unit] [Unit]
Description=${APPLICATION} Service Description=hev-socks5-server Service
After=network.target After=network.target
[Service] [Service]
ExecStart=/opt/${APPLICATION} /etc/${APPLICATION}/main.yml ExecStart=/opt/hev-socks5-server /etc/hev-socks5-server/main.yml
Restart=always Restart=always
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
systemctl enable -q --now ${APPLICATION} systemctl enable -q --now hev-socks5-server
msg_ok "Created Service" msg_ok "Created Service"
motd_ssh motd_ssh

View File

@@ -18,16 +18,11 @@ $STD apt-get install -y jq
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs
fetch_and_deploy_gh_release "homepage" "gethomepage/homepage" "tarball"
RELEASE=$(get_latest_github_release "gethomepage/homepage")
LOCAL_IP=$(hostname -I | awk '{print $1}') msg_info "Installing Homepage (Patience)"
RELEASE=$(curl -fsSL https://api.github.com/repos/gethomepage/homepage/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
msg_info "Installing Homepage v${RELEASE} (Patience)"
curl -fsSL "https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz" -o "v${RELEASE}.tar.gz"
$STD tar -xzf v${RELEASE}.tar.gz
rm -rf v${RELEASE}.tar.gz
mkdir -p /opt/homepage/config mkdir -p /opt/homepage/config
mv homepage-${RELEASE}/* /opt/homepage
rm -rf homepage-${RELEASE}
cd /opt/homepage cd /opt/homepage
cp /opt/homepage/src/skeleton/* /opt/homepage/config cp /opt/homepage/src/skeleton/* /opt/homepage/config
$STD pnpm install $STD pnpm install
@@ -37,8 +32,7 @@ export NEXT_PUBLIC_BUILDTIME=$(curl -fsSL https://api.github.com/repos/gethomepa
export NEXT_TELEMETRY_DISABLED=1 export NEXT_TELEMETRY_DISABLED=1
$STD pnpm build $STD pnpm build
echo "HOMEPAGE_ALLOWED_HOSTS=localhost:3000,${LOCAL_IP}:3000" >/opt/homepage/.env echo "HOMEPAGE_ALLOWED_HOSTS=localhost:3000,${LOCAL_IP}:3000" >/opt/homepage/.env
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt msg_ok "Installed Homepage"
msg_ok "Installed Homepage v${RELEASE}"
msg_info "Creating Service" msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/homepage.service cat <<EOF >/etc/systemd/system/homepage.service
@@ -46,6 +40,7 @@ cat <<EOF >/etc/systemd/system/homepage.service
Description=Homepage Description=Homepage
After=network.target After=network.target
StartLimitIntervalSec=0 StartLimitIntervalSec=0
[Service] [Service]
Type=simple Type=simple
Restart=always Restart=always
@@ -53,6 +48,7 @@ RestartSec=1
User=root User=root
WorkingDirectory=/opt/homepage/ WorkingDirectory=/opt/homepage/
ExecStart=pnpm start ExecStart=pnpm start
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF

View File

@@ -21,7 +21,6 @@ msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="infisical_db" PG_DB_USER="infisical" setup_postgresql_db PG_DB_NAME="infisical_db" PG_DB_USER="infisical" setup_postgresql_db
import_local_ip
msg_info "Setting up Infisical Repository" msg_info "Setting up Infisical Repository"
setup_deb822_repo \ setup_deb822_repo \

View File

@@ -28,7 +28,6 @@ $STD apt install -y inventree
msg_ok "Installed InvenTree" msg_ok "Installed InvenTree"
msg_info "Configuring InvenTree" msg_info "Configuring InvenTree"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
if [[ -f /etc/inventree/config.yaml ]]; then if [[ -f /etc/inventree/config.yaml ]]; then
sed -i "s|site_url:.*|site_url: http://${LOCAL_IP}|" /etc/inventree/config.yaml sed -i "s|site_url:.*|site_url: http://${LOCAL_IP}|" /etc/inventree/config.yaml
fi fi

View File

@@ -33,7 +33,6 @@ setup_composer
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
PG_VERSION="17" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="investbrain" PG_DB_USER="investbrain" setup_postgresql_db PG_DB_NAME="investbrain" PG_DB_USER="investbrain" setup_postgresql_db
import_local_ip
fetch_and_deploy_gh_release "Investbrain" "investbrainapp/investbrain" "tarball" "latest" "/opt/investbrain" fetch_and_deploy_gh_release "Investbrain" "investbrainapp/investbrain" "tarball" "latest" "/opt/investbrain"

View File

@@ -36,7 +36,7 @@ msg_ok "Installed Dependencies"
setup_mariadb setup_mariadb
MARIADB_DB_NAME="invoiceninja" MARIADB_DB_USER="invoiceninja" setup_mariadb_db MARIADB_DB_NAME="invoiceninja" MARIADB_DB_USER="invoiceninja" setup_mariadb_db
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,gmp,imagick,intl,mbstring,mysql,soap,xml,zip" setup_php PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,gmp,imagick,intl,mbstring,mysql,soap,xml,zip" setup_php
import_local_ip
fetch_and_deploy_gh_release "invoiceninja" "invoiceninja/invoiceninja" "prebuild" "latest" "/opt/invoiceninja" "invoiceninja.tar.gz" fetch_and_deploy_gh_release "invoiceninja" "invoiceninja/invoiceninja" "prebuild" "latest" "/opt/invoiceninja" "invoiceninja.tar.gz"
msg_info "Configuring InvoiceNinja" msg_info "Configuring InvoiceNinja"

View File

@@ -1,48 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.iventoy.com/en/index.html
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
RELEASE=$(curl -fsSL https://api.github.com/repos/ventoy/pxe/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
msg_info "Installing iVentoy v${RELEASE}"
mkdir -p /opt/iventoy/{data,iso}
curl -fsSL "https://github.com/ventoy/PXE/releases/download/v${RELEASE}/iventoy-${RELEASE}-linux-free.tar.gz" -o "iventoy-${RELEASE}-linux-free.tar.gz"
tar -C /tmp -xzf iventoy*.tar.gz
mv /tmp/iventoy*/* /opt/iventoy/
rm -rf iventoy*.tar.gz
msg_ok "Installed iVentoy"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/iventoy.service
[Unit]
Description=iVentoy PXE Booter
Documentation=https://www.iventoy.com
Wants=network-online.target
[Service]
Type=forking
Environment=IVENTOY_API_ALL=1
Environment=IVENTOY_AUTO_RUN=1
Environment=LIBRARY_PATH=/opt/iventoy/lib/lin64
Environment=LD_LIBRARY_PATH=/opt/iventoy/lib/lin64
ExecStart=sh ./iventoy.sh -R start
WorkingDirectory=/opt/iventoy
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now iventoy
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -28,8 +28,8 @@ $STD pm2 install pm2-logrotate
$STD pm2 set pm2-logrotate:max_size 100MB $STD pm2 set pm2-logrotate:max_size 100MB
$STD pm2 set pm2-logrotate:retain 5 $STD pm2 set pm2-logrotate:retain 5
$STD pm2 set pm2-logrotate:compress tr $STD pm2 set pm2-logrotate:compress tr
fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball" fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball"
import_local_ip
msg_info "Setting up Joplin Server (Patience)" msg_info "Setting up Joplin Server (Patience)"
cd /opt/joplin-server cd /opt/joplin-server

View File

@@ -21,7 +21,6 @@ $STD apt install -y \
locales locales
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
import_local_ip
PG_VERSION="16" setup_postgresql PG_VERSION="16" setup_postgresql
PG_DB_NAME="koel" PG_DB_USER="koel" setup_postgresql_db PG_DB_NAME="koel" PG_DB_USER="koel" setup_postgresql_db
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bz2,exif,imagick,pgsql,sqlite3" setup_php PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bz2,exif,imagick,pgsql,sqlite3" setup_php

View File

@@ -21,8 +21,7 @@ $STD ln -s /usr/local/kubo/ipfs /usr/local/bin/ipfs
$STD ipfs init $STD ipfs init
ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001 ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001
ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080 ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080
LXCIP=$(hostname -I | awk '{print $1}') ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "[\"http://${LOCAL_IP}:5001\", \"http://localhost:3000\", \"http://127.0.0.1:5001\", \"https://webui.ipfs.io\", \"http://0.0.0.0:5001\"]"
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "[\"http://${LXCIP}:5001\", \"http://localhost:3000\", \"http://127.0.0.1:5001\", \"https://webui.ipfs.io\", \"http://0.0.0.0:5001\"]"
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST"]' ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST"]'
msg_ok "Configured IPFS" msg_ok "Configured IPFS"

View File

@@ -19,7 +19,6 @@ read -rp "${TAB3}Enter your choice <i/e> (default: i): " ssl_choice
ssl_choice=${ssl_choice:-i} ssl_choice=${ssl_choice:-i}
case "${ssl_choice,,}" in case "${ssl_choice,,}" in
i) i)
import_local_ip
DEFAULT_HOST="$LOCAL_IP" DEFAULT_HOST="$LOCAL_IP"
msg_info "Configuring Caddy" msg_info "Configuring Caddy"

View File

@@ -78,11 +78,10 @@ sed -i "s/listen = \/run\/php\/php8.4-fpm.sock/listen = \/run\/php-fpm-librenms.
msg_ok "Configured PHP-FPM" msg_ok "Configured PHP-FPM"
msg_info "Configure Nginx" msg_info "Configure Nginx"
IP_ADDR=$(hostname -I | awk '{print $1}')
cat >/etc/nginx/sites-enabled/librenms <<'EOF' cat >/etc/nginx/sites-enabled/librenms <<'EOF'
server { server {
listen 80; listen 80;
server_name ${IP_ADDR}; server_name ${LOCAL_IP};
root /opt/librenms/html; root /opt/librenms/html;
index index.php; index index.php;

View File

@@ -50,10 +50,9 @@ fi
$STD yarn $STD yarn
$STD npx playwright install-deps $STD npx playwright install-deps
$STD npx playwright install $STD npx playwright install
IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/opt/linkwarden/.env cat <<EOF >/opt/linkwarden/.env
NEXTAUTH_SECRET=${SECRET_KEY} NEXTAUTH_SECRET=${SECRET_KEY}
NEXTAUTH_URL=http://${IP}:3000 NEXTAUTH_URL=http://${LOCAL_IP}:3000
DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME} DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}
EOF EOF
$STD yarn prisma:generate $STD yarn prisma:generate

View File

@@ -44,14 +44,13 @@ $STD sudo -u postgres psql -c "GRANT USAGE, CREATE ON SCHEMA PUBLIC TO $DB_USER;
msg_ok "Set up PostgreSQL" msg_ok "Set up PostgreSQL"
msg_info "Installing Mattermost" msg_info "Installing Mattermost"
IPADDRESS=$(hostname -I | awk '{print $1}')
curl -fsSL -o /usr/share/keyrings/mattermost-archive-keyring.gpg https://deb.packages.mattermost.com/pubkey.gpg curl -fsSL -o /usr/share/keyrings/mattermost-archive-keyring.gpg https://deb.packages.mattermost.com/pubkey.gpg
sh -c 'curl -fsSL https://deb.packages.mattermost.com/repo-setup.sh | sudo bash -s mattermost' >/dev/null sh -c 'curl -fsSL https://deb.packages.mattermost.com/repo-setup.sh | sudo bash -s mattermost' >/dev/null
$STD apt update $STD apt update
$STD apt install -y mattermost $STD apt install -y mattermost
$STD install -C -m 600 -o mattermost -g mattermost /opt/mattermost/config/config.defaults.json /opt/mattermost/config/config.json $STD install -C -m 600 -o mattermost -g mattermost /opt/mattermost/config/config.defaults.json /opt/mattermost/config/config.json
sed -i -e "/DataSource/c\ \"DataSource\": \"postgres://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME?sslmode=disable&connect_timeout=10\"," \ sed -i -e "/DataSource/c\ \"DataSource\": \"postgres://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME?sslmode=disable&connect_timeout=10\"," \
-e "/SiteURL/c\ \"SiteURL\": \"http://$IPADDRESS:8065\"," /opt/mattermost/config/config.json -e "/SiteURL/c\ \"SiteURL\": \"http://$LOCAL_IP:8065\"," /opt/mattermost/config/config.json
systemctl enable -q --now mattermost systemctl enable -q --now mattermost
msg_ok "Installed Mattermost" msg_ok "Installed Mattermost"

View File

@@ -40,7 +40,6 @@ msg_ok "Installed Python Dependencies"
msg_info "Building Frontend" msg_info "Building Frontend"
MEALIE_VERSION=$(<$HOME/.mealie) MEALIE_VERSION=$(<$HOME/.mealie)
CONTAINER_IP=$(hostname -I | awk '{print $1}')
export NUXT_TELEMETRY_DISABLED=1 export NUXT_TELEMETRY_DISABLED=1
cd /opt/mealie/frontend cd /opt/mealie/frontend
$STD sed -i "s|https://github.com/mealie-recipes/mealie/commit/|https://github.com/mealie-recipes/mealie/releases/tag/|g" /opt/mealie/frontend/pages/admin/site-settings.vue $STD sed -i "s|https://github.com/mealie-recipes/mealie/commit/|https://github.com/mealie-recipes/mealie/releases/tag/|g" /opt/mealie/frontend/pages/admin/site-settings.vue
@@ -79,7 +78,7 @@ POSTGRES_DB=${PG_DB_NAME}
PRODUCTION=true PRODUCTION=true
HOST=0.0.0.0 HOST=0.0.0.0
PORT=9000 PORT=9000
BASE_URL=http://${CONTAINER_IP}:9000 BASE_URL=http://${LOCAL_IP}:9000
EOF EOF
msg_ok "Wrote Environment File" msg_ok "Wrote Environment File"

View File

@@ -61,7 +61,6 @@ $STD /usr/local/bin/uv sync --locked --active -n -p cpython3.13 --managed-python
msg_ok "Configured MediaManager" msg_ok "Configured MediaManager"
msg_info "Creating config and start script" msg_info "Creating config and start script"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
SECRET="$(openssl rand -hex 32)" SECRET="$(openssl rand -hex 32)"
sed -e "s/localhost:8/$LOCAL_IP:8/g" \ sed -e "s/localhost:8/$LOCAL_IP:8/g" \
-e "s|/data/|$MEDIA_DIR/|g" \ -e "s|/data/|$MEDIA_DIR/|g" \

View File

@@ -18,7 +18,6 @@ fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary"
msg_info "Configuring ${APPLICATION}" msg_info "Configuring ${APPLICATION}"
curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml
MASTER_KEY=$(openssl rand -base64 12) MASTER_KEY=$(openssl rand -base64 12)
LOCAL_IP="$(hostname -I | awk '{print $1}')"
sed -i \ sed -i \
-e 's|^env =.*|env = "production"|' \ -e 's|^env =.*|env = "production"|' \
-e "s|^# master_key =.*|master_key = \"$MASTER_KEY\"|" \ -e "s|^# master_key =.*|master_key = \"$MASTER_KEY\"|" \

View File

@@ -29,13 +29,12 @@ $STD npm install --global n8n
msg_ok "Installed n8n" msg_ok "Installed n8n"
msg_info "Creating Service" msg_info "Creating Service"
HOST_IP=$(hostname -I | awk '{print $1}')
mkdir -p /opt mkdir -p /opt
cat <<EOF >/opt/n8n.env cat <<EOF >/opt/n8n.env
N8N_SECURE_COOKIE=false N8N_SECURE_COOKIE=false
N8N_PORT=5678 N8N_PORT=5678
N8N_PROTOCOL=http N8N_PROTOCOL=http
N8N_HOST=$HOST_IP N8N_HOST=${LOCAL_IP}
EOF EOF
cat <<EOF >/etc/systemd/system/n8n.service cat <<EOF >/etc/systemd/system/n8n.service

View File

@@ -20,11 +20,11 @@ msg_ok "Installed dependendencies"
NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs
PG_VERSION="17" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="openarchiver_db" PG_DB_USER="openarchiver" setup_postgresql_db PG_DB_NAME="openarchiver_db" PG_DB_USER="openarchiver" setup_postgresql_db
fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary"
fetch_and_deploy_gh_release "openarchiver" "LogicLabs-OU/OpenArchiver" "tarball" fetch_and_deploy_gh_release "openarchiver" "LogicLabs-OU/OpenArchiver" "tarball"
JWT_KEY="$(openssl rand -hex 32)" JWT_KEY="$(openssl rand -hex 32)"
SECRET_KEY="$(openssl rand -hex 32)" SECRET_KEY="$(openssl rand -hex 32)"
import_local_ip
msg_info "Configuring MeiliSearch" msg_info "Configuring MeiliSearch"
curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml

View File

@@ -21,7 +21,6 @@ PG_VERSION="17" setup_postgresql
PG_DB_NAME="openproject" PG_DB_USER="openproject" setup_postgresql_db PG_DB_NAME="openproject" PG_DB_USER="openproject" setup_postgresql_db
API_KEY=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) API_KEY=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
echo "OpenProject API Key: $API_KEY" >>~/openproject.creds echo "OpenProject API Key: $API_KEY" >>~/openproject.creds
import_local_ip
msg_info "Setting up OpenProject Repository" msg_info "Setting up OpenProject Repository"
curl -fsSL "https://dl.packager.io/srv/opf/openproject/key" | gpg --dearmor >/etc/apt/trusted.gpg.d/packager-io.gpg curl -fsSL "https://dl.packager.io/srv/opf/openproject/key" | gpg --dearmor >/etc/apt/trusted.gpg.d/packager-io.gpg

View File

@@ -29,8 +29,7 @@ msg_ok "Installed openziti"
read -r -p "${TAB3}Would you like to go through the auto configuration now? <y/N>" prompt read -r -p "${TAB3}Would you like to go through the auto configuration now? <y/N>" prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
IPADDRESS=$(hostname -I | awk '{print $1}') GEN_FQDN="controller.${LOCAL_IP}.sslip.io"
GEN_FQDN="controller.${IPADDRESS}.sslip.io"
read -r -p "${TAB3}Please enter the controller FQDN [${GEN_FQDN}]: " ZITI_CTRL_ADVERTISED_ADDRESS read -r -p "${TAB3}Please enter the controller FQDN [${GEN_FQDN}]: " ZITI_CTRL_ADVERTISED_ADDRESS
ZITI_CTRL_ADVERTISED_ADDRESS=${ZITI_CTRL_ADVERTISED_ADDRESS:-$GEN_FQDN} ZITI_CTRL_ADVERTISED_ADDRESS=${ZITI_CTRL_ADVERTISED_ADDRESS:-$GEN_FQDN}
read -r -p "${TAB3}Please enter the controller port [1280]: " ZITI_CTRL_ADVERTISED_PORT read -r -p "${TAB3}Please enter the controller port [1280]: " ZITI_CTRL_ADVERTISED_PORT

View File

@@ -23,8 +23,8 @@ msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
PG_VERSION="16" setup_postgresql PG_VERSION="16" setup_postgresql
PG_DB_NAME="outline" PG_DB_USER="outline" setup_postgresql_db PG_DB_NAME="outline" PG_DB_USER="outline" setup_postgresql_db
fetch_and_deploy_gh_release "outline" "outline/outline" "tarball" fetch_and_deploy_gh_release "outline" "outline/outline" "tarball"
import_local_ip
msg_info "Configuring Outline (Patience)" msg_info "Configuring Outline (Patience)"
SECRET_KEY="$(openssl rand -hex 32)" SECRET_KEY="$(openssl rand -hex 32)"
@@ -38,6 +38,7 @@ sed -i 's/redis:6379/localhost:6379/g' /opt/outline/.env
sed -i "5s#URL=#URL=http://${LOCAL_IP}#g" /opt/outline/.env sed -i "5s#URL=#URL=http://${LOCAL_IP}#g" /opt/outline/.env
sed -i 's/FORCE_HTTPS=true/FORCE_HTTPS=false/g' /opt/outline/.env sed -i 's/FORCE_HTTPS=true/FORCE_HTTPS=false/g' /opt/outline/.env
export NODE_OPTIONS="--max-old-space-size=3584" export NODE_OPTIONS="--max-old-space-size=3584"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
$STD corepack enable $STD corepack enable
$STD yarn install --immutable $STD yarn install --immutable
export NODE_ENV=production export NODE_ENV=production

View File

@@ -28,8 +28,8 @@ read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " p
read -rp "${TAB3}Enter your email address: " pango_email read -rp "${TAB3}Enter your email address: " pango_email
msg_info "Setup Pangolin" msg_info "Setup Pangolin"
IP_ADDR=$(hostname -I | awk '{print $1}')
SECRET_KEY=$(openssl rand -base64 48 | tr -dc 'A-Za-z0-9' | head -c 32) SECRET_KEY=$(openssl rand -base64 48 | tr -dc 'A-Za-z0-9' | head -c 32)
BADGER_VERSION=$(get_latest_github_release "fosrl/badger" "false")
cd /opt/pangolin cd /opt/pangolin
mkdir -p /opt/pangolin/config/{traefik,db,letsencrypt,logs} mkdir -p /opt/pangolin/config/{traefik,db,letsencrypt,logs}
$STD npm ci $STD npm ci
@@ -77,7 +77,7 @@ api:
providers: providers:
http: http:
endpoint: "http://$IP_ADDR:3001/api/v1/traefik-config" endpoint: "http://$LOCAL_IP:3001/api/v1/traefik-config"
pollInterval: "5s" pollInterval: "5s"
file: file:
filename: "/opt/pangolin/config/traefik/dynamic_config.yml" filename: "/opt/pangolin/config/traefik/dynamic_config.yml"
@@ -86,7 +86,7 @@ experimental:
plugins: plugins:
badger: badger:
moduleName: "github.com/fosrl/badger" moduleName: "github.com/fosrl/badger"
version: "v1.2.0" version: "$BADGER_VERSION"
log: log:
level: "INFO" level: "INFO"
@@ -168,12 +168,12 @@ http:
next-service: next-service:
loadBalancer: loadBalancer:
servers: servers:
- url: "http://$IP_ADDR:3002" - url: "http://$LOCAL_IP:3002"
api-service: api-service:
loadBalancer: loadBalancer:
servers: servers:
- url: "http://$IP_ADDR:3000" - url: "http://$LOCAL_IP:3000"
EOF EOF
$STD npm run db:sqlite:generate $STD npm run db:sqlite:generate
$STD npm run db:sqlite:push $STD npm run db:sqlite:push
@@ -218,7 +218,7 @@ Requires=pangolin.service
[Service] [Service]
Type=simple Type=simple
User=root User=root
ExecStart=/usr/bin/gerbil --reachableAt=http://$IP_ADDR:3004 --generateAndSaveKeyTo=/var/config/key --remoteConfig=http://$IP_ADDR:3001/api/v1/ ExecStart=/usr/bin/gerbil --reachableAt=http://$LOCAL_IP:3004 --generateAndSaveKeyTo=/var/config/key --remoteConfig=http://$LOCAL_IP:3001/api/v1/
Restart=always Restart=always
RestartSec=10 RestartSec=10

View File

@@ -23,7 +23,7 @@ msg_ok "Installed dependencies"
setup_mariadb setup_mariadb
MARIADB_DB_NAME="passboltdb" MARIADB_DB_USER="passbolt" setup_mariadb_db MARIADB_DB_NAME="passboltdb" MARIADB_DB_USER="passbolt" setup_mariadb_db
create_self_signed_cert create_self_signed_cert
import_local_ip
setup_deb822_repo \ setup_deb822_repo \
"passbolt" \ "passbolt" \
"https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x3D1A0346C8E1802F774AEF21DE8B853FC155581D" \ "https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x3D1A0346C8E1802F774AEF21DE8B853FC155581D" \

View File

@@ -23,8 +23,8 @@ msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs NODE_VERSION="24" setup_nodejs
PG_VERSION="17" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="patchmon_db" PG_DB_USER="patchmon_usr" setup_postgresql_db PG_DB_NAME="patchmon_db" PG_DB_USER="patchmon_usr" setup_postgresql_db
fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon" fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon"
import_local_ip
msg_info "Configuring PatchMon" msg_info "Configuring PatchMon"
cd /opt/patchmon cd /opt/patchmon
@@ -98,8 +98,8 @@ msg_ok "Configured PatchMon"
msg_info "Configuring Nginx" msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/patchmon.conf cat <<EOF >/etc/nginx/sites-available/patchmon.conf
map $http_x_forwarded_proto $proxy_corrected_scheme { map \$http_x_forwarded_proto \$proxy_corrected_scheme {
default $scheme; # Fallback to Nginx's actual connection scheme if no X-Forwarded-Proto header was set default \$scheme; # Fallback to Nginx's actual connection scheme if no X-Forwarded-Proto header was set
https https; # If X-Forwarded-Proto is 'https', use 'https' https https; # If X-Forwarded-Proto is 'https', use 'https'
http http; # If X-Forwarded-Proto is 'http', use 'http' http http; # If X-Forwarded-Proto is 'http', use 'http'
} }

View File

@@ -31,7 +31,7 @@ mkdir -p /etc/peanut/
ln -sf .next/standalone/server.js server.js ln -sf .next/standalone/server.js server.js
cat <<EOF >/etc/peanut/settings.yml cat <<EOF >/etc/peanut/settings.yml
WEB_HOST: 0.0.0.0 WEB_HOST: 0.0.0.0
WEB_PORT: 3000 WEB_PORT: 8080
NUT_HOST: 0.0.0.0 NUT_HOST: 0.0.0.0
NUT_PORT: 3493 NUT_PORT: 3493
EOF EOF
@@ -52,7 +52,7 @@ Environment="NODE_ENV=production"
#Environment="NUT_HOST=localhost" #Environment="NUT_HOST=localhost"
#Environment="NUT_PORT=3493" #Environment="NUT_PORT=3493"
#Environment="WEB_HOST=0.0.0.0" #Environment="WEB_HOST=0.0.0.0"
#Environment="WEB_PORT=3000" #Environment="WEB_PORT=8080"
WorkingDirectory=/opt/peanut WorkingDirectory=/opt/peanut
ExecStart=node /opt/peanut/entrypoint.mjs ExecStart=node /opt/peanut/entrypoint.mjs
TimeoutStopSec=30 TimeoutStopSec=30

View File

@@ -1,68 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: bvdberg01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://phpipam.net/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y fping
msg_ok "Installed Dependencies"
PHP_VERSION="8.4" PHP_APACHE="YES" PHP_FPM="YES" PHP_MODULE="mysql,gmp,snmp,ldap,apcu" setup_php
msg_info "Installing PHP-PEAR"
$STD apt install -y \
php-pear \
php-dev
msg_ok "Installed PHP-PEAR"
setup_mariadb
MARIADB_DB_NAME="phpipam" MARIADB_DB_USER="phpipam" setup_mariadb_db
fetch_and_deploy_gh_release "phpipam" "phpipam/phpipam" "prebuild" "latest" "/opt/phpipam" "phpipam-v*.zip"
msg_info "Installing phpIPAM"
# patch SCHEMA, during varchar l_name is to short in upstream (2025-11-15)
sed -i -E 's/`l_name`\s+varchar\([0-9]+\)/`l_name` varchar(128)/' /opt/phpipam/db/SCHEMA.sql
$STD mariadb -u root "${MARIADB_DB_NAME}" </opt/phpipam/db/SCHEMA.sql
cp /opt/phpipam/config.dist.php /opt/phpipam/config.php
sed -i -e "s/\(\$disable_installer = \).*/\1true;/" \
-e "s/\(\$db\['user'\] = \).*/\1'$MARIADB_DB_USER';/" \
-e "s/\(\$db\['pass'\] = \).*/\1'$MARIADB_DB_PASS';/" \
-e "s/\(\$db\['name'\] = \).*/\1'$MARIADB_DB_NAME';/" \
/opt/phpipam/config.php
sed -i '/max_execution_time/s/= .*/= 600/' /etc/php/8.4/apache2/php.ini
msg_ok "Installed phpIPAM"
msg_info "Creating Service"
cat <<EOF >/etc/apache2/sites-available/phpipam.conf
<VirtualHost *:80>
ServerName phpipam
DocumentRoot /opt/phpipam
<Directory /opt/phpipam>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/apache2/phpipam_error.log
CustomLog /var/log/apache2/phpipam_access.log combined
</VirtualHost>
EOF
$STD a2ensite phpipam
$STD a2enmod rewrite
$STD a2dissite 000-default.conf
$STD systemctl reload apache2
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -43,7 +43,6 @@ msg_ok "Set up PostgreSQL Database"
fetch_and_deploy_gh_release "planka" "plankanban/planka" "prebuild" "latest" "/opt/planka" "planka-prebuild.zip" fetch_and_deploy_gh_release "planka" "plankanban/planka" "prebuild" "latest" "/opt/planka" "planka-prebuild.zip"
msg_info "Configuring PLANKA" msg_info "Configuring PLANKA"
LOCAL_IP=$(hostname -I | awk '{print $1}')
SECRET_KEY=$(openssl rand -hex 64) SECRET_KEY=$(openssl rand -hex 64)
cd /opt/planka cd /opt/planka
$STD npm install $STD npm install

View File

@@ -70,11 +70,10 @@ cd /opt/pterodactyl-panel
curl -fsSL "https://github.com/pterodactyl/panel/releases/download/v${RELEASE}/panel.tar.gz" -o "panel.tar.gz" curl -fsSL "https://github.com/pterodactyl/panel/releases/download/v${RELEASE}/panel.tar.gz" -o "panel.tar.gz"
tar -xzf "panel.tar.gz" tar -xzf "panel.tar.gz"
cp .env.example .env cp .env.example .env
IP=$(hostname -I | awk '{print $1}')
ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD composer install --no-dev --optimize-autoloader --no-interaction $STD composer install --no-dev --optimize-autoloader --no-interaction
$STD php artisan key:generate --force $STD php artisan key:generate --force
$STD php artisan p:environment:setup --no-interaction --author "$ADMIN_EMAIL" --url "http://$IP" $STD php artisan p:environment:setup --no-interaction --author "$ADMIN_EMAIL" --url "http://$LOCAL_IP"
$STD php artisan p:environment:database --no-interaction --database $DB_NAME --username $DB_USER --password "$DB_PASS" $STD php artisan p:environment:database --no-interaction --database $DB_NAME --username $DB_USER --password "$DB_PASS"
$STD php artisan migrate --seed --force --no-interaction $STD php artisan migrate --seed --force --no-interaction
$STD php artisan p:user:make --no-interaction --admin=1 --email "$ADMIN_EMAIL" --password "$ADMIN_PASS" --name-first "$NAME_FIRST" --name-last "$NAME_LAST" --username "admin" $STD php artisan p:user:make --no-interaction --admin=1 --email "$ADMIN_EMAIL" --password "$ADMIN_PASS" --name-first "$NAME_FIRST" --name-last "$NAME_LAST" --username "admin"

View File

@@ -19,7 +19,6 @@ curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio
$STD dpkg -i minio.deb $STD dpkg -i minio.deb
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
import_local_ip
PG_VERSION="16" setup_postgresql PG_VERSION="16" setup_postgresql
PG_DB_NAME="rxresume" PG_DB_USER="rxresume" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db PG_DB_NAME="rxresume" PG_DB_USER="rxresume" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
NODE_VERSION="24" NODE_MODULE="pnpm@latest" setup_nodejs NODE_VERSION="24" NODE_MODULE="pnpm@latest" setup_nodejs

View File

@@ -47,7 +47,6 @@ cp ./target/release/daemon /usr/bin/scanopy-daemon
msg_ok "Built scanopy-daemon" msg_ok "Built scanopy-daemon"
msg_info "Configuring server for first-run" msg_info "Configuring server for first-run"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
cat <<EOF >/opt/scanopy/.env cat <<EOF >/opt/scanopy/.env
### - SERVER ### - SERVER
scanopy_DATABASE_URL=postgresql://$PG_DB_USER:$PG_DB_PASS@localhost:5432/$PG_DB_NAME scanopy_DATABASE_URL=postgresql://$PG_DB_USER:$PG_DB_PASS@localhost:5432/$PG_DB_NAME

View File

@@ -24,7 +24,6 @@ setup_composer
fetch_and_deploy_gh_release "snipe-it" "grokability/snipe-it" "tarball" fetch_and_deploy_gh_release "snipe-it" "grokability/snipe-it" "tarball"
setup_mariadb setup_mariadb
MARIADB_DB_NAME="snipeit_db" MARIADB_DB_USER="snipeit" setup_mariadb_db MARIADB_DB_NAME="snipeit_db" MARIADB_DB_USER="snipeit" setup_mariadb_db
import_local_ip
msg_info "Configuring Snipe-IT" msg_info "Configuring Snipe-IT"
cd /opt/snipe-it cd /opt/snipe-it

View File

@@ -23,8 +23,7 @@ msg_ok "Installed Dependencies"
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="common,sqlite3,redis" setup_php PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="common,sqlite3,redis" setup_php
setup_composer setup_composer
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
import_local_ip fetch_and_deploy_gh_release "speedtest-tracker" "alexjustesen/speedtest-tracker" "tarball"
fetch_and_deploy_gh_release "speedtest-tracker" "alexjustesen/speedtest-tracker" "tarball" "latest" "/opt/speedtest-tracker"
msg_info "Installing Speedtest CLI" msg_info "Installing Speedtest CLI"
setup_deb822_repo \ setup_deb822_repo \

View File

@@ -43,14 +43,17 @@ while true; do
done done
msg_info "Setup Splunk Enterprise" msg_info "Setup Splunk Enterprise"
DOWNLOAD_URL=$(curl -s "https://www.splunk.com/en_us/download/splunk-enterprise.html" | grep -o 'data-link="[^"]*' | sed 's/data-link="//' | grep "https.*products/splunk/releases" | grep "\.deb$") DOWNLOAD_URL=$(curl -s "https://www.splunk.com/en_us/download/splunk-enterprise.html" | grep -o 'data-link="[^"]*' | sed 's/data-link="//' | grep "https.*products/splunk/releases" | grep "linux-amd64\.tgz$")
RELEASE=$(echo "$DOWNLOAD_URL" | sed 's|.*/releases/\([^/]*\)/.*|\1|') RELEASE=$(echo "$DOWNLOAD_URL" | sed 's|.*/releases/\([^/]*\)/.*|\1|')
$STD curl -fsSL -o "splunk-enterprise.deb" "$DOWNLOAD_URL" || { $STD curl -fsSL -o "splunk-enterprise.tgz" "$DOWNLOAD_URL" || {
msg_error "Failed to download Splunk Enterprise from the provided link." msg_error "Failed to download Splunk Enterprise from the provided link."
exit 1 exit 1
} }
$STD dpkg -i "splunk-enterprise.deb" $STD tar -xzf "splunk-enterprise.tgz" -C /opt
rm -f "splunk-enterprise.deb" rm -f "splunk-enterprise.tgz"
addgroup --system splunk
adduser --system --home /opt/splunk --shell /bin/bash --ingroup splunk --no-create-home splunk
chown -R splunk:splunk /opt/splunk
msg_ok "Setup Splunk Enterprise v${RELEASE}" msg_ok "Setup Splunk Enterprise v${RELEASE}"
msg_info "Creating Splunk admin user" msg_info "Creating Splunk admin user"
@@ -62,7 +65,7 @@ ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
echo "Password: $ADMIN_PASS" echo "Password: $ADMIN_PASS"
} >> ~/splunk.creds } >> ~/splunk.creds
cat > "/opt/splunk/etc/system/local/user-seed.conf" << EOF cat << EOF > "/opt/splunk/etc/system/local/user-seed.conf"
[user_info] [user_info]
USERNAME = $ADMIN_USER USERNAME = $ADMIN_USER
PASSWORD = $ADMIN_PASS PASSWORD = $ADMIN_PASS
@@ -70,8 +73,8 @@ EOF
msg_ok "Created Splunk admin user" msg_ok "Created Splunk admin user"
msg_info "Starting Service" msg_info "Starting Service"
$STD /opt/splunk/bin/splunk start --accept-license --answer-yes --no-prompt $STD sudo -u splunk /opt/splunk/bin/splunk start --accept-license --answer-yes --no-prompt
$STD /opt/splunk/bin/splunk enable boot-start $STD /opt/splunk/bin/splunk enable boot-start -user splunk
msg_ok "Started Service" msg_ok "Started Service"
motd_ssh motd_ssh

View File

@@ -22,6 +22,9 @@ fetch_and_deploy_gh_release "Tautulli" "Tautulli/Tautulli" "tarball"
msg_info "Installing Tautulli" msg_info "Installing Tautulli"
cd /opt/Tautulli cd /opt/Tautulli
TAUTULLI_VERSION=$(get_latest_github_release "Tautulli/Tautulli" "false")
echo "${TAUTULLI_VERSION}" >/opt/Tautulli/version.txt
echo "master" >/opt/Tautulli/branch.txt
uv venv -q uv venv -q
uv pip install -q -r requirements.txt uv pip install -q -r requirements.txt
uv pip install -q pyopenssl uv pip install -q pyopenssl

258
install/termix-install.sh Normal file
View File

@@ -0,0 +1,258 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Termix-SSH/Termix
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
python3 \
nginx \
openssl \
gettext-base
msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "termix" "Termix-SSH/Termix"
msg_info "Building Frontend"
cd /opt/termix
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
find public/fonts -name "*.ttf" ! -name "*Regular.ttf" ! -name "*Bold.ttf" ! -name "*Italic.ttf" -delete 2>/dev/null || true
$STD npm install --ignore-scripts --force
$STD npm cache clean --force
$STD npm run build
msg_ok "Built Frontend"
msg_info "Building Backend"
$STD npm rebuild better-sqlite3 --force
$STD npm run build:backend
msg_ok "Built Backend"
msg_info "Setting up Node Dependencies"
cd /opt/termix
$STD npm ci --only=production --ignore-scripts --force
$STD npm rebuild better-sqlite3 bcryptjs --force
$STD npm cache clean --force
msg_ok "Set up Node Dependencies"
msg_info "Setting up Directories"
mkdir -p /opt/termix/data \
/opt/termix/uploads \
/opt/termix/html \
/opt/termix/nginx \
/opt/termix/nginx/logs \
/opt/termix/nginx/cache \
/opt/termix/nginx/client_body
cp -r /opt/termix/dist/* /opt/termix/html/ 2>/dev/null || true
cp -r /opt/termix/src/locales /opt/termix/html/locales 2>/dev/null || true
cp -r /opt/termix/public/fonts /opt/termix/html/fonts 2>/dev/null || true
msg_ok "Set up Directories"
msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/termix.conf
error_log /opt/termix/nginx/logs/error.log warn;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /opt/termix/nginx/logs/access.log;
client_body_temp_path /opt/termix/nginx/client_body;
proxy_temp_path /opt/termix/nginx/proxy_temp;
sendfile on;
keepalive_timeout 65;
client_header_timeout 300s;
server {
listen 80;
server_name _;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
root /opt/termix/html;
expires 1y;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
location / {
root /opt/termix/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location ~ ^/users(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ ^/(version|releases|alerts|rbac|credentials|snippets|terminal|encryption)(/.*)?$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ ^/(database|db)(/.*)?$ {
client_max_body_size 5G;
client_body_timeout 300s;
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
proxy_request_buffering off;
proxy_buffering off;
}
location /ssh/ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /ssh/websocket/ {
proxy_pass http://127.0.0.1:30002/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_buffering off;
proxy_request_buffering off;
}
location /ssh/tunnel/ {
proxy_pass http://127.0.0.1:30003;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /ssh/file_manager/ssh/ {
client_max_body_size 5G;
client_body_timeout 300s;
proxy_pass http://127.0.0.1:30004;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
proxy_request_buffering off;
proxy_buffering off;
}
location ~ ^/ssh/file_manager/(recent|pinned|shortcuts)$ {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /health {
proxy_pass http://127.0.0.1:30001;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location ~ ^/(status|metrics)(/.*)?$ {
proxy_pass http://127.0.0.1:30005;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location ~ ^/(uptime|activity)(/.*)?$ {
proxy_pass http://127.0.0.1:30006;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location ^~ /docker/console/ {
proxy_pass http://127.0.0.1:30008/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_buffering off;
proxy_request_buffering off;
}
location ~ ^/docker(/.*)?$ {
proxy_pass http://127.0.0.1:30007;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
}
}
EOF
rm -f /etc/nginx/sites-enabled/default
rm -f /etc/nginx/nginx.conf
ln -sf /etc/nginx/sites-available/termix.conf /etc/nginx/nginx.conf
systemctl reload nginx
msg_ok "Configured Nginx"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/termix.service
[Unit]
Description=Termix Backend
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/termix
Environment=NODE_ENV=production
Environment=DATA_DIR=/opt/termix/data
ExecStart=/usr/bin/node /opt/termix/dist/backend/backend/starter.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now termix
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -20,7 +20,6 @@ $STD apt install -y \
imagemagick imagemagick
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
import_local_ip
setup_mariadb setup_mariadb
MARIADB_DB_NAME="wallabag" MARIADB_DB_USER="wallabag" setup_mariadb_db MARIADB_DB_NAME="wallabag" MARIADB_DB_USER="wallabag" setup_mariadb_db
PHP_VERSION="8.3" PHP_FPM="YES" PHP_MODULE="bcmath,bz2,curl,gd,imagick,intl,mbstring,mysql,redis,tidy,xml,zip" setup_php PHP_VERSION="8.3" PHP_FPM="YES" PHP_MODULE="bcmath,bz2,curl,gd,imagick,intl,mbstring,mysql,redis,tidy,xml,zip" setup_php

Some files were not shown because too many files have changed in this diff Show More