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
102 changed files with 1459 additions and 938 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-18 ## 2026-01-20
## 2026-01-19
### 🆕 New Scripts ### 🆕 New Scripts
- ThingsBoard ([#10904](https://github.com/community-scripts/ProxmoxVE/pull/10904)) - yubal ([#10955](https://github.com/community-scripts/ProxmoxVE/pull/10955))
### 🚀 Updated Scripts ### 🚀 Updated Scripts
- #### 🐞 Bug Fixes - #### 🐞 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
### 🆕 New Scripts
- Termix ([#10887](https://github.com/community-scripts/ProxmoxVE/pull/10887))
- ThingsBoard ([#10904](https://github.com/community-scripts/ProxmoxVE/pull/10904))
### 🚀 Updated Scripts
- #### 🐞 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

@@ -434,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
@@ -528,7 +528,7 @@ msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
PG_VERSION="17" 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"
@@ -664,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

@@ -58,7 +58,7 @@ msg_ok "Installed Dependencies"
# fetch_and_deploy_gh_release "appname" "owner/repo" "prebuild" "latest" "/opt/appname" "app-*.tar.gz" # fetch_and_deploy_gh_release "appname" "owner/repo" "prebuild" "latest" "/opt/appname" "app-*.tar.gz"
# #
# --- Tools & Utilities --- # --- Tools & Utilities ---
# import_local_ip # Sets $LOCAL_IP variable (call early!) # get_lxc_ip # Sets $LOCAL_IP variable (call early!)
# setup_ffmpeg # Install FFmpeg with codecs # setup_ffmpeg # Install FFmpeg with codecs
# setup_hwaccel # Setup GPU hardware acceleration # setup_hwaccel # Setup GPU hardware acceleration
# setup_imagemagick # Install ImageMagick 7 # setup_imagemagick # Install ImageMagick 7
@@ -72,7 +72,7 @@ msg_ok "Installed Dependencies"
# NODE_VERSION="22" setup_nodejs # NODE_VERSION="22" setup_nodejs
# PG_VERSION="17" 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
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp" # fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
# #
# msg_info "Configuring MyApp" # msg_info "Configuring MyApp"
@@ -89,7 +89,7 @@ msg_ok "Installed Dependencies"
# EXAMPLE 2: Python Application with uv # EXAMPLE 2: Python Application with uv
# ============================================================================= # =============================================================================
# PYTHON_VERSION="3.13" setup_uv # PYTHON_VERSION="3.13" setup_uv
# import_local_ip # get_lxc_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp" # fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
# #
# msg_info "Setting up MyApp" # msg_info "Setting up MyApp"
@@ -108,7 +108,7 @@ msg_ok "Installed Dependencies"
# 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
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz" # fetch_and_deploy_gh_release "myapp" "owner/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz"
# #
# msg_info "Configuring MyApp" # msg_info "Configuring MyApp"
@@ -126,7 +126,7 @@ msg_ok "Installed Dependencies"
# YOUR APPLICATION INSTALLATION # YOUR APPLICATION INSTALLATION
# ============================================================================= # =============================================================================
# 1. Setup runtimes and databases FIRST # 1. Setup runtimes and databases FIRST
# 2. Call import_local_ip if you need the container IP # 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) # 3. Use fetch_and_deploy_gh_release to download the app (handles version tracking)
# 4. Configure the application # 4. Configure the application
# 5. Create systemd service # 5. Create systemd service
@@ -134,7 +134,7 @@ msg_ok "Installed Dependencies"
# --- Setup runtimes/databases --- # --- Setup runtimes/databases ---
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
import_local_ip get_lxc_ip
# --- Download and install app --- # --- Download and install app ---
fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/[appname]" fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/[appname]"

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

View File

@@ -32,7 +32,6 @@ msg_ok "Installed wanderer"
msg_info "Creating Service" msg_info "Creating Service"
MEILI_KEY=$(openssl rand -hex 32) MEILI_KEY=$(openssl rand -hex 32)
POCKETBASE_KEY=$(openssl rand -hex 16) POCKETBASE_KEY=$(openssl rand -hex 16)
LOCAL_IP="$(hostname -I | awk '{print $1}')"
cat <<EOF >/opt/wanderer/.env cat <<EOF >/opt/wanderer/.env
ORIGIN=http://${LOCAL_IP}:3000 ORIGIN=http://${LOCAL_IP}:3000

View File

@@ -19,8 +19,8 @@ msg_ok "Installed Dependencies"
setup_uv setup_uv
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "wizarr" "wizarrrr/wizarr" "tarball" fetch_and_deploy_gh_release "wizarr" "wizarrrr/wizarr" "tarball"
import_local_ip
msg_info "Configure Wizarr" msg_info "Configure Wizarr"
cd /opt/wizarr cd /opt/wizarr

91
install/yubal-install.sh Normal file
View File

@@ -0,0 +1,91 @@
#!/usr/bin/env bash
# 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
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 \
libssl-dev \
libffi-dev \
python3-dev \
ffmpeg
msg_ok "Installed Dependencies"
msg_info "Installing Bun"
export BUN_INSTALL=/opt/bun
curl -fsSL https://bun.sh/install | $STD bash
ln -sf /opt/bun/bin/bun /usr/local/bin/bun
ln -sf /opt/bun/bin/bunx /usr/local/bin/bunx
msg_ok "Installed Bun"
UV_VERSION="0.7.19" PYTHON_VERSION="3.12" setup_uv
msg_info "Installing Deno"
$STD sh -c "curl -fsSL https://deno.land/install.sh | DENO_INSTALL=/usr/local sh -s -- -y"
msg_ok "Installed Deno"
msg_info "Creating directories"
mkdir -p /opt/yubal \
/opt/yubal_data \
/opt/yubal_config
msg_ok "Created directories"
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
export UV_CONCURRENT_DOWNLOADS=1
$STD uv sync --package yubal-api --no-dev --frozen
msg_ok "Installed Python Dependencies"
msg_info "Creating Service"
cat <<EOF >/opt/yubal.env
YUBAL_HOST=0.0.0.0
YUBAL_PORT=8001
YUBAL_DATA=/opt/yubal_data
YUBAL_CONFIG=/opt/yubal_config
YUBAL_ROOT=/opt/yubal
PYTHONUNBUFFERED=1
EOF
cat <<EOF >/etc/systemd/system/yubal.service
[Unit]
Description=Yubal
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/yubal
EnvironmentFile=/opt/yubal.env
Environment="PATH=/opt/yubal/.venv/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/opt/yubal/.venv/bin/python -m yubal
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now yubal
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -20,8 +20,6 @@ $STD apt install -y \
apt-transport-https apt-transport-https
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
import_local_ip
msg_info "Setting up Elasticsearch" msg_info "Setting up Elasticsearch"
setup_deb822_repo \ setup_deb822_repo \
"elasticsearch" \ "elasticsearch" \

View File

@@ -11,6 +11,9 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
load_functions load_functions
catch_errors catch_errors
# Get LXC IP address (must be called INSIDE container, after network is up)
get_lxc_ip
# This function enables IPv6 if it's not disabled and sets verbose mode # This function enables IPv6 if it's not disabled and sets verbose mode
verb_ip6() { verb_ip6() {
set_std_mode # Set STD mode based on VERBOSE set_std_mode # Set STD mode based on VERBOSE

View File

@@ -325,6 +325,38 @@ get_valid_container_id() {
echo "$suggested_id" echo "$suggested_id"
} }
# ------------------------------------------------------------------------------
# validate_hostname()
#
# - Validates hostname/FQDN according to RFC 1123/952
# - Checks total length (max 253 characters for FQDN)
# - Validates each label (max 63 chars, alphanumeric + hyphens)
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_hostname() {
local hostname="$1"
# Check total length (max 253 for FQDN)
if [[ ${#hostname} -gt 253 ]] || [[ -z "$hostname" ]]; then
return 1
fi
# Split by dots and validate each label
local IFS='.'
read -ra labels <<< "$hostname"
for label in "${labels[@]}"; do
# Each label: 1-63 chars, alphanumeric, hyphens allowed (not at start/end)
if [[ -z "$label" ]] || [[ ${#label} -gt 63 ]]; then
return 1
fi
if [[ ! "$label" =~ ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ ]] && [[ ! "$label" =~ ^[a-z0-9]$ ]]; then
return 1
fi
done
return 0
}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# find_host_ssh_keys() # find_host_ssh_keys()
# #
@@ -582,7 +614,22 @@ base_settings() {
CORE_COUNT="${final_cpu}" CORE_COUNT="${final_cpu}"
RAM_SIZE="${final_ram}" RAM_SIZE="${final_ram}"
VERBOSE=${var_verbose:-"${1:-no}"} VERBOSE=${var_verbose:-"${1:-no}"}
PW=${var_pw:-""} PW=""
if [[ -n "${var_pw:-}" ]]; then
local _pw_raw="${var_pw}"
case "$_pw_raw" in
--password\ *) _pw_raw="${_pw_raw#--password }" ;;
-password\ *) _pw_raw="${_pw_raw#-password }" ;;
esac
while [[ "$_pw_raw" == -* ]]; do
_pw_raw="${_pw_raw#-}"
done
if [[ -z "$_pw_raw" ]]; then
msg_warn "Password was only dashes after cleanup; leaving empty."
else
PW="--password $_pw_raw"
fi
fi
# Validate and set Container ID # Validate and set Container ID
local requested_id="${var_ctid:-$NEXTID}" local requested_id="${var_ctid:-$NEXTID}"
@@ -595,7 +642,17 @@ base_settings() {
fi fi
CT_ID="$requested_id" CT_ID="$requested_id"
HN=${var_hostname:-$NSAPP} # Validate and set Hostname/FQDN
local requested_hostname="${var_hostname:-$NSAPP}"
requested_hostname=$(echo "${requested_hostname,,}" | tr -d ' ')
if ! validate_hostname "$requested_hostname"; then
if [[ -n "${var_hostname:-}" ]]; then
msg_warn "Invalid hostname '$requested_hostname'. Using default: $NSAPP"
fi
requested_hostname="$NSAPP"
fi
HN="$requested_hostname"
BRG=${var_brg:-"vmbr0"} BRG=${var_brg:-"vmbr0"}
NET=${var_net:-"dhcp"} NET=${var_net:-"dhcp"}
@@ -1392,17 +1449,30 @@ advanced_settings() {
((STEP++)) ((STEP++))
elif [[ "$PW1" == *" "* ]]; then elif [[ "$PW1" == *" "* ]]; then
whiptail --msgbox "Password cannot contain spaces." 8 58 whiptail --msgbox "Password cannot contain spaces." 8 58
elif ((${#PW1} < 5)); then
whiptail --msgbox "Password must be at least 5 characters." 8 58
else else
local _pw1_clean="$PW1"
while [[ "$_pw1_clean" == -* ]]; do
_pw1_clean="${_pw1_clean#-}"
done
if [[ -z "$_pw1_clean" ]]; then
whiptail --msgbox "Password cannot be only '-' characters." 8 58
continue
elif ((${#_pw1_clean} < 5)); then
whiptail --msgbox "Password must be at least 5 characters (after removing leading '-')." 8 70
continue
fi
# Verify password # Verify password
if PW2=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if PW2=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "PASSWORD VERIFICATION" \ --title "PASSWORD VERIFICATION" \
--ok-button "Confirm" --cancel-button "Back" \ --ok-button "Confirm" --cancel-button "Back" \
--passwordbox "\nVerify Root Password" 10 58 \ --passwordbox "\nVerify Root Password" 10 58 \
3>&1 1>&2 2>&3); then 3>&1 1>&2 2>&3); then
if [[ "$PW1" == "$PW2" ]]; then local _pw2_clean="$PW2"
_pw="-password $PW1" while [[ "$_pw2_clean" == -* ]]; do
_pw2_clean="${_pw2_clean#-}"
done
if [[ "$_pw1_clean" == "$_pw2_clean" ]]; then
_pw="--password $_pw1_clean"
_pw_display="********" _pw_display="********"
((STEP++)) ((STEP++))
else else
@@ -1458,15 +1528,16 @@ advanced_settings() {
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "HOSTNAME" \ --title "HOSTNAME" \
--ok-button "Next" --cancel-button "Back" \ --ok-button "Next" --cancel-button "Back" \
--inputbox "\nSet Hostname (lowercase, alphanumeric, hyphens only)" 10 58 "$_hostname" \ --inputbox "\nSet Hostname (or FQDN, e.g. host.example.com)" 10 58 "$_hostname" \
3>&1 1>&2 2>&3); then 3>&1 1>&2 2>&3); then
local hn_test="${result:-$NSAPP}" local hn_test="${result:-$NSAPP}"
hn_test=$(echo "${hn_test,,}" | tr -d ' ') hn_test=$(echo "${hn_test,,}" | tr -d ' ')
if [[ "$hn_test" =~ ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ ]]; then
if validate_hostname "$hn_test"; then
_hostname="$hn_test" _hostname="$hn_test"
((STEP++)) ((STEP++))
else else
whiptail --msgbox "Invalid hostname: '$hn_test'\n\nOnly lowercase letters, digits and hyphens are allowed." 10 58 whiptail --msgbox "Invalid hostname: '$hn_test'\n\nRules:\n- Only lowercase letters, digits, dots and hyphens\n- Labels separated by dots (max 63 chars each)\n- No leading/trailing hyphens or dots\n- No consecutive dots\n- Total max 253 characters" 14 60
fi fi
else else
((STEP--)) ((STEP--))

View File

@@ -38,6 +38,8 @@ load_functions() {
icons icons
default_vars default_vars
set_std_mode set_std_mode
# Note: get_lxc_ip() is NOT called here automatically
# Call it explicitly when you need LOCAL_IP variable
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -878,6 +880,67 @@ check_or_create_swap() {
fi fi
} }
# ------------------------------------------------------------------------------
# Loads LOCAL_IP from persistent store or detects if missing.
#
# Description:
# - Loads from /run/local-ip.env or performs runtime lookup
# ------------------------------------------------------------------------------
function get_lxc_ip() {
local IP_FILE="/run/local-ip.env"
if [[ -f "$IP_FILE" ]]; then
# shellcheck disable=SC1090
source "$IP_FILE"
fi
if [[ -z "${LOCAL_IP:-}" ]]; then
get_current_ip() {
local ip
# Try direct interface lookup for eth0 FIRST (most reliable for LXC)
ip=$(ip -4 addr show eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1)
if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "$ip"
return 0
fi
# Fallback: Try hostname -I
if command -v hostname >/dev/null 2>&1; then
ip=$(hostname -I 2>/dev/null | awk '{print $1}')
if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "$ip"
return 0
fi
fi
# Last resort: Use routing table
local targets=("8.8.8.8" "1.1.1.1" "default")
for target in "${targets[@]}"; do
if [[ "$target" == "default" ]]; then
ip=$(ip route get 1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')
else
ip=$(ip route get "$target" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')
fi
if [[ -n "$ip" ]]; then
echo "$ip"
return 0
fi
done
return 1
}
LOCAL_IP="$(get_current_ip || true)"
if [[ -z "$LOCAL_IP" ]]; then
msg_error "Could not determine LOCAL_IP"
return 1
fi
fi
export LOCAL_IP
}
# ============================================================================== # ==============================================================================
# SIGNAL TRAPS # SIGNAL TRAPS
# ============================================================================== # ==============================================================================

View File

@@ -37,6 +37,9 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
load_functions load_functions
catch_errors catch_errors
# Get LXC IP address (must be called INSIDE container, after network is up)
get_lxc_ip
# ============================================================================== # ==============================================================================
# SECTION 2: NETWORK & CONNECTIVITY # SECTION 2: NETWORK & CONNECTIVITY
# ============================================================================== # ==============================================================================

View File

@@ -2004,50 +2004,6 @@ function fetch_and_deploy_gh_release() {
rm -rf "$tmpdir" rm -rf "$tmpdir"
} }
# ------------------------------------------------------------------------------
# Loads LOCAL_IP from persistent store or detects if missing.
#
# Description:
# - Loads from /run/local-ip.env or performs runtime lookup
# ------------------------------------------------------------------------------
function import_local_ip() {
local IP_FILE="/run/local-ip.env"
if [[ -f "$IP_FILE" ]]; then
# shellcheck disable=SC1090
source "$IP_FILE"
fi
if [[ -z "${LOCAL_IP:-}" ]]; then
get_current_ip() {
local targets=("8.8.8.8" "1.1.1.1" "192.168.1.1" "10.0.0.1" "172.16.0.1" "default")
local ip
for target in "${targets[@]}"; do
if [[ "$target" == "default" ]]; then
ip=$(ip route get 1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')
else
ip=$(ip route get "$target" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')
fi
if [[ -n "$ip" ]]; then
echo "$ip"
return 0
fi
done
return 1
}
LOCAL_IP="$(get_current_ip || true)"
if [[ -z "$LOCAL_IP" ]]; then
msg_error "Could not determine LOCAL_IP"
return 1
fi
fi
export LOCAL_IP
}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Installs Adminer (Debian/Ubuntu via APT, Alpine via direct download). # Installs Adminer (Debian/Ubuntu via APT, Alpine via direct download).
# #

View File

@@ -5,6 +5,49 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/9001/copyparty # Source: https://github.com/9001/copyparty
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
load_functions
# ==============================================================================
# CONFIGURATION
# ==============================================================================
VERBOSE=${var_verbose:-no}
APP="CopyParty"
APP_TYPE="addon"
BIN_PATH="/usr/local/bin/copyparty-sfx.py"
CONF_PATH="/etc/copyparty.conf"
LOG_PATH="/var/log/copyparty"
DATA_PATH="/var/lib/copyparty"
SVC_USER="copyparty"
SVC_GROUP="copyparty"
SRC_URL="https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py"
DEFAULT_PORT=3923
# ==============================================================================
# OS DETECTION
# ==============================================================================
if [[ -f "/etc/alpine-release" ]]; then
OS="Alpine"
PKG_MANAGER="apk add --no-cache"
SERVICE_PATH="/etc/init.d/copyparty"
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
OS="Debian"
PKG_MANAGER="apt-get install -y"
SERVICE_PATH="/etc/systemd/system/copyparty.service"
else
msg_error "Unsupported OS detected. Exiting."
exit 1
fi
# ==============================================================================
# HEADER
# ==============================================================================
function header_info() { function header_info() {
clear clear
cat <<"EOF" cat <<"EOF"
@@ -17,46 +60,13 @@ function header_info() {
EOF EOF
} }
YW=$(echo "\033[33m") # ==============================================================================
GN=$(echo "\033[1;92m") # HELPER FUNCTIONS
RD=$(echo "\033[01;31m") # ==============================================================================
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
APP="CopyParty"
BIN_PATH="/usr/local/bin/copyparty-sfx.py"
CONF_PATH="/etc/copyparty.conf"
LOG_PATH="/var/log/copyparty"
DATA_PATH="/var/lib/copyparty"
SERVICE_PATH_DEB="/etc/systemd/system/copyparty.service"
SERVICE_PATH_ALP="/etc/init.d/copyparty"
SVC_USER="copyparty"
SVC_GROUP="copyparty"
SRC_URL="https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py"
DEFAULT_PORT=3923
if [[ -f "/etc/alpine-release" ]]; then
OS="Alpine"
PKG_MANAGER="apk add --no-cache"
SERVICE_PATH="$SERVICE_PATH_ALP"
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
PKG_MANAGER="apt-get install -y"
SERVICE_PATH="$SERVICE_PATH_DEB"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 1
fi
header_info
function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
# ==============================================================================
# HELPER FUNCTIONS
# ==============================================================================
function setup_user_and_dirs() { function setup_user_and_dirs() {
msg_info "Creating $SVC_USER user and directories" msg_info "Creating $SVC_USER user and directories"
if ! id "$SVC_USER" &>/dev/null; then if ! id "$SVC_USER" &>/dev/null; then
@@ -73,150 +83,161 @@ function setup_user_and_dirs() {
msg_ok "User/Group/Dirs ready" msg_ok "User/Group/Dirs ready"
} }
function uninstall_copyparty() { # ==============================================================================
msg_info "Uninstalling $APP" # UNINSTALL
if [[ "$OS" == "Debian" ]]; then # ==============================================================================
systemctl disable --now copyparty &>/dev/null function uninstall() {
rm -f "$SERVICE_PATH_DEB" msg_info "Uninstalling ${APP}"
if [[ "$OS" == "Alpine" ]]; then
rc-service copyparty stop &>/dev/null || true
rc-update del copyparty &>/dev/null || true
rm -f "$SERVICE_PATH"
else else
rc-service copyparty stop &>/dev/null systemctl disable --now copyparty.service &>/dev/null || true
rc-update del copyparty &>/dev/null rm -f "$SERVICE_PATH"
rm -f "$SERVICE_PATH_ALP"
fi fi
rm -f "$BIN_PATH" "$CONF_PATH" rm -f "$BIN_PATH" "$CONF_PATH"
msg_ok "$APP has been uninstalled." rm -rf "$DATA_PATH" "$LOG_PATH"
exit 0 userdel "$SVC_USER" 2>/dev/null || true
groupdel "$SVC_GROUP" 2>/dev/null || true
rm -f "/usr/local/bin/update_copyparty"
rm -f "$HOME/.copyparty"
msg_ok "${APP} has been uninstalled"
} }
function update_copyparty() { # ==============================================================================
msg_info "Updating $APP" # UPDATE
# ==============================================================================
function update() {
if check_for_gh_release "copyparty-sfx.py" "9001/copyparty"; then
msg_info "Stopping service"
if [[ "$OS" == "Alpine" ]]; then
rc-service copyparty stop &>/dev/null || true
else
systemctl stop copyparty.service &>/dev/null || true
fi
msg_ok "Stopped service"
msg_info "Updating ${APP}"
curl -fsSL "$SRC_URL" -o "$BIN_PATH" curl -fsSL "$SRC_URL" -o "$BIN_PATH"
chmod +x "$BIN_PATH" chmod +x "$BIN_PATH"
chown "$SVC_USER:$SVC_GROUP" "$BIN_PATH"
msg_ok "Updated ${APP}"
msg_info "Starting service"
if [[ "$OS" == "Alpine" ]]; then
rc-service copyparty start
else
systemctl start copyparty.service
fi
msg_ok "Started service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
exit 0 exit
fi
} }
if [[ -f "$BIN_PATH" ]]; then # ==============================================================================
echo -e "${YW}⚠️ $APP is already installed.${CL}" # INSTALL
echo -n "Uninstall $APP? (y/N): " # ==============================================================================
read -r uninstall_prompt function install() {
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then local port data_path enable_auth admin_user admin_pass
uninstall_copyparty
fi
echo -n "Update $APP? (y/N): " echo ""
read -r update_prompt read -rp "${TAB}Enter port for ${APP} [${DEFAULT_PORT}]: " port
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then port=${port:-$DEFAULT_PORT}
update_copyparty
else
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
exit 0
fi
fi
msg_info "Installing dependencies" read -rp "${TAB}Set data directory [${DATA_PATH}]: " data_path
if [[ "$OS" == "Debian" ]]; then data_path=${data_path:-$DATA_PATH}
$PKG_MANAGER python3 curl &>/dev/null
else
$PKG_MANAGER python3 curl &>/dev/null
fi
msg_ok "Dependencies installed"
setup_user_and_dirs echo -n "${TAB}Enable authentication? (Y/n): "
read -r enable_auth
msg_info "Downloading $APP" if [[ "${enable_auth,,}" =~ ^(n|no)$ ]]; then
curl -fsSL "$SRC_URL" -o "$BIN_PATH" admin_user=""
chmod +x "$BIN_PATH" admin_pass=""
chown "$SVC_USER:$SVC_GROUP" "$BIN_PATH"
msg_ok "Downloaded to $BIN_PATH"
echo -n "Enter port for $APP (default: $DEFAULT_PORT): "
read -r PORT
PORT=${PORT:-$DEFAULT_PORT}
echo -n "Set data directory (default: $DATA_PATH): "
read -r USER_DATA_PATH
USER_DATA_PATH=${USER_DATA_PATH:-$DATA_PATH}
mkdir -p "$USER_DATA_PATH"
chown "$SVC_USER:$SVC_GROUP" "$USER_DATA_PATH"
echo -n "Enable authentication? (Y/n): "
read -r auth_enable
if [[ "${auth_enable,,}" =~ ^(n|no)$ ]]; then
AUTH_LINE=""
msg_ok "Configured without authentication" msg_ok "Configured without authentication"
else
echo -n "Set admin username [default: admin]: "
read -r ADMIN_USER
ADMIN_USER=${ADMIN_USER:-admin}
echo -n "Set admin password [default: helper-scripts.com]: "
read -rs ADMIN_PASS
ADMIN_PASS=${ADMIN_PASS:-helper-scripts.com}
echo
AUTH_LINE="auth vhost=/:$ADMIN_USER:$ADMIN_PASS:admin,,"
msg_ok "Configured with admin user: $ADMIN_USER"
fi
msg_info "Writing config to $CONF_PATH"
msg_info "Writing config to $CONF_PATH"
{
echo "[global]"
echo " p: $PORT"
echo " ansi"
echo " e2dsa"
echo " e2ts"
echo " theme: 2"
echo " grid"
echo
if [[ -n "$ADMIN_USER" && -n "$ADMIN_PASS" ]]; then
echo "[accounts]"
echo " $ADMIN_USER: $ADMIN_PASS"
echo
fi
echo "[/]"
echo " $USER_DATA_PATH"
echo " accs:"
if [[ -n "$ADMIN_USER" ]]; then
echo " rw: *"
echo " rwmda: $ADMIN_USER"
else else
echo " rw: *" read -rp "${TAB}Set admin username [admin]: " admin_user
admin_user=${admin_user:-admin}
read -rsp "${TAB}Set admin password [helper-scripts.com]: " admin_pass
echo ""
admin_pass=${admin_pass:-helper-scripts.com}
msg_ok "Configured with admin user: ${admin_user}"
fi fi
} >"$CONF_PATH"
chmod 640 "$CONF_PATH" msg_info "Installing dependencies"
chown "$SVC_USER:$SVC_GROUP" "$CONF_PATH" if [[ "$OS" == "Debian" ]]; then
msg_ok "Config written" $STD $PKG_MANAGER python3 python3-pil ffmpeg curl
else
$STD $PKG_MANAGER python3 py3-pillow ffmpeg curl
fi
msg_ok "Dependencies installed (with thumbnail support)"
msg_info "Creating service" setup_user_and_dirs
if [[ "$OS" == "Debian" ]]; then
cat <<EOF >"$SERVICE_PATH_DEB"
[Unit]
Description=Copyparty file server
After=network.target
[Service] # Use data_path if provided
User=$SVC_USER if [[ "$data_path" != "$DATA_PATH" ]]; then
Group=$SVC_GROUP DATA_PATH="$data_path"
WorkingDirectory=$DATA_PATH mkdir -p "$DATA_PATH"
ExecStart=/usr/bin/python3 /usr/local/bin/copyparty-sfx.py -c /etc/copyparty.conf chown "$SVC_USER:$SVC_GROUP" "$DATA_PATH"
Restart=always fi
StandardOutput=append:/var/log/copyparty/copyparty.log
StandardError=append:/var/log/copyparty/copyparty.err msg_info "Downloading ${APP}"
curl -fsSL "$SRC_URL" -o "$BIN_PATH"
chmod +x "$BIN_PATH"
chown "$SVC_USER:$SVC_GROUP" "$BIN_PATH"
msg_ok "Downloaded to ${BIN_PATH}"
msg_info "Creating configuration"
cat <<EOF >"$CONF_PATH"
[global]
p: ${port}
ansi
e2dsa
e2ts
theme: 2
grid
no-robots
force-js
lo: ${LOG_PATH}/cpp-%Y-%m%d.txt.xz
[Install]
WantedBy=multi-user.target
EOF EOF
systemctl enable -q --now copyparty if [[ -n "$admin_user" && -n "$admin_pass" ]]; then
cat <<EOF >>"$CONF_PATH"
[accounts]
${admin_user}: ${admin_pass}
elif [[ "$OS" == "Alpine" ]]; then EOF
cat <<'EOF' >"$SERVICE_PATH_ALP" fi
cat <<EOF >>"$CONF_PATH"
[/]
${DATA_PATH}
accs:
EOF
if [[ -n "$admin_user" ]]; then
cat <<EOF >>"$CONF_PATH"
rw: *
rwmda: ${admin_user}
EOF
else
cat <<EOF >>"$CONF_PATH"
rw: *
EOF
fi
chmod 640 "$CONF_PATH"
chown "$SVC_USER:$SVC_GROUP" "$CONF_PATH"
msg_ok "Created configuration"
msg_info "Creating service"
if [[ "$OS" == "Alpine" ]]; then
cat <<'SERVICEEOF' >"$SERVICE_PATH"
#!/sbin/openrc-run #!/sbin/openrc-run
name="copyparty" name="copyparty"
description="Copyparty file server" description="CopyParty file server"
command="$(command -v python3)" command="$(command -v python3)"
command_args="/usr/local/bin/copyparty-sfx.py -c /etc/copyparty.conf" command_args="/usr/local/bin/copyparty-sfx.py -c /etc/copyparty.conf"
command_background=true command_background=true
@@ -228,21 +249,110 @@ error_log="/var/log/copyparty/copyparty.err"
depend() { depend() {
need net need net
} }
EOF SERVICEEOF
chmod +x "$SERVICE_PATH"
$STD rc-update add copyparty default
$STD rc-service copyparty start
else
cat <<SERVICEEOF >"$SERVICE_PATH"
[Unit]
Description=CopyParty file server
After=network.target
chmod +x "$SERVICE_PATH_ALP" [Service]
rc-update add copyparty default >/dev/null 2>&1 User=${SVC_USER}
rc-service copyparty restart >/dev/null 2>&1 Group=${SVC_GROUP}
WorkingDirectory=${DATA_PATH}
ExecStart=/usr/bin/python3 ${BIN_PATH} -c ${CONF_PATH}
Restart=always
StandardOutput=append:${LOG_PATH}/copyparty.log
StandardError=append:${LOG_PATH}/copyparty.err
[Install]
WantedBy=multi-user.target
SERVICEEOF
systemctl daemon-reload
systemctl enable --now copyparty.service &>/dev/null
fi
msg_ok "Created and started service"
# Create update script
msg_info "Creating update script"
ensure_usr_local_bin_persist
cat <<'UPDATEEOF' >/usr/local/bin/update_copyparty
#!/usr/bin/env bash
# CopyParty Update Script
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/copyparty.sh)"
UPDATEEOF
chmod +x /usr/local/bin/update_copyparty
msg_ok "Created update script (/usr/local/bin/update_copyparty)"
echo ""
msg_ok "${APP} installed successfully"
msg_ok "Web UI: ${BL}http://${LOCAL_IP}:${port}${CL}"
msg_ok "Storage: ${BL}${DATA_PATH}${CL}"
msg_ok "Config: ${BL}${CONF_PATH}${CL}"
if [[ -n "$admin_user" ]]; then
echo ""
msg_ok "Login: ${GN}${admin_user}${CL} / ${GN}${admin_pass}${CL}"
fi
}
# ==============================================================================
# MAIN
# ==============================================================================
header_info
ensure_usr_local_bin_persist
get_lxc_ip
# Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then
if [[ -f "$BIN_PATH" ]]; then
update
else
msg_error "${APP} is not installed. Nothing to update."
exit 1
fi
exit 0
fi fi
msg_ok "Service created and started"
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}') # Check if already installed
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) if [[ -f "$BIN_PATH" ]]; then
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}') msg_warn "${APP} is already installed."
[[ -z "$IP" ]] && IP="127.0.0.1" echo ""
echo -e "${CM} ${GN}$APP is running at: ${BL}http://$IP:$PORT${CL}" echo -n "${TAB}Uninstall ${APP}? (y/N): "
echo -e "${INFO} Storage directory: ${YW}$USER_DATA_PATH${CL}" read -r uninstall_prompt
if [[ -n "$AUTH_LINE" ]]; then if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
echo -e "${INFO} Login: ${GN}${ADMIN_USER}${CL} / ${GN}${ADMIN_PASS}${CL}" uninstall
exit 0
fi
echo -n "${TAB}Update ${APP}? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
update
exit 0
fi
msg_warn "No action selected. Exiting."
exit 0
fi
# Fresh installation
msg_warn "${APP} is not installed."
echo ""
echo -e "${TAB}${INFO} This will install:"
echo -e "${TAB} - CopyParty (Python file server)"
echo -e "${TAB} - Thumbnail support (Pillow, FFmpeg)"
echo -e "${TAB} - Systemd/OpenRC service"
echo ""
echo -n "${TAB}Install ${APP}? (y/N): "
read -r install_prompt
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
install
else
msg_warn "Installation cancelled. Exiting."
exit 0
fi fi

View File

@@ -30,7 +30,7 @@ function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; } function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; } function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
get_local_ip() { get_lxc_ip() {
if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then
hostname -I | awk '{print $1}' hostname -I | awk '{print $1}'
elif command -v ip >/dev/null 2>&1; then elif command -v ip >/dev/null 2>&1; then
@@ -39,7 +39,7 @@ get_local_ip() {
echo "127.0.0.1" echo "127.0.0.1"
fi fi
} }
IP=$(get_local_ip) IP=$(get_lxc_ip)
install_glances_debian() { install_glances_debian() {
msg_info "Installing dependencies" msg_info "Installing dependencies"

View File

@@ -325,7 +325,7 @@ if [[ "${type:-}" == "update" ]]; then
fi fi
header_info header_info
import_local_ip get_lxc_ip
# Check if already installed # Check if already installed
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/package.json" ]]; then if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/package.json" ]]; then

View File

@@ -155,7 +155,7 @@ UPDATEEOF
# ============================================================================== # ==============================================================================
header_info header_info
ensure_usr_local_bin_persist ensure_usr_local_bin_persist
import_local_ip get_lxc_ip
# Handle type=update (called from update script) # Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then if [[ "${type:-}" == "update" ]]; then

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