Merge branch 'community-scripts:main' into byparr

This commit is contained in:
Luís Oliveira 2025-11-24 16:02:33 +00:00 committed by GitHub
commit 64b2d3eca3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
63 changed files with 8809 additions and 5276 deletions

View File

@ -1,6 +1,6 @@
module proxmox-api
go 1.23.2
go 1.24.0
require (
github.com/gorilla/mux v1.8.1
@ -17,7 +17,7 @@ require (
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
golang.org/x/crypto v0.35.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/text v0.31.0 // indirect
)

View File

@ -27,16 +27,16 @@ go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793Sqyh
go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -48,8 +48,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

View File

@ -1,35 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: michelroegl-brunner
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://asterisk.org/
APP="Asterisk"
var_tags="${var_tags:-telephone;pbx}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
msg_error "No Update function provided for ${APP} LXC"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"

View File

@ -1,68 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Lissy93/domain-locker
APP="Domain-Locker"
var_tags="${var_tags:-Monitoring}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-10240}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/domain-locker ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "domain-locker" "Lissy93/domain-locker"; then
msg_info "Stopping Service"
systemctl stop domain-locker
msg_info "Service stopped"
PG_VERSION="17" setup_postgresql
setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "domain-locker" "Lissy93/domain-locker"
msg_info "Installing Modules (patience)"
cd /opt/domain-locker
$STD npm install
msg_ok "Installed Modules"
msg_info "Building Domain-Locker (a lot of patience)"
npm install
set -a
source /opt/domain-locker.env
set +a
$STD npm run build
msg_info "Built Domain-Locker"
msg_info "Restarting Services"
systemctl start domain-locker
msg_ok "Restarted 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}:3000${CL}"

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
source <(curl -s https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/build.func)
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/refs/heads/freepbx/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Arian Nasr (arian-nasr)
# Updated by: Javier Pastor (vsc55)

View File

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

View File

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

View File

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

6
ct/headers/passbolt Normal file
View File

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

View File

@ -1,6 +0,0 @@
_____ __ __ ______ __ _
/ ___/____ / /_ ______ / /__ / ____/___ / /____ _________ _____(_)_______
\__ \/ __ \/ / / / / __ \/ //_/_____/ __/ / __ \/ __/ _ \/ ___/ __ \/ ___/ / ___/ _ \
___/ / /_/ / / /_/ / / / / ,< /_____/ /___/ / / / /_/ __/ / / /_/ / / / (__ ) __/
/____/ .___/_/\__,_/_/ /_/_/|_| /_____/_/ /_/\__/\___/_/ / .___/_/ /_/____/\___/
/_/ /_/

6
ct/headers/upgopher Normal file
View File

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

61
ct/joplin-server.sh Normal file
View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://joplinapp.org/
APP="Joplin-Server"
var_tags="${var_tags:-notes}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-20}"
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/joplin-server ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "joplin-server" "laurent22/joplin"; then
msg_info "Stopping Services"
systemctl stop joplin-server
msg_ok "Stopped Services"
fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball" "latest"
msg_info "Updating Joplin-Server"
cd /opt/joplin-server
sed -i "/onenote-converter/d" packages/lib/package.json
$STD yarn config set --home enableTelemetry 0
export BUILD_SEQUENCIAL=1
$STD yarn install --inline-builds
msg_ok "Updated Joplin-Server"
msg_info "Starting Services"
systemctl start joplin-server
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}:22300${CL}"

View File

@ -1,46 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: michelroegl-brunner
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://librenms.org
APP="Librenms"
var_tags="${var_tags:-monitoring}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
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/librenms ]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating ${APP} Installation"
su librenms
cd /opt/librenms
./daily.sh
msg_ok "Updated ${APP} Installation"
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}"

87
ct/mealie.sh Normal file
View File

@ -0,0 +1,87 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://mealie.io
APP="Mealie"
var_tags="${var_tags:-recipes}"
var_cpu="${var_cpu:-5}"
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/mealie ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "mealie" "mealie-recipes/mealie"; then
PYTHON_VERSION="3.12" setup_uv
NODE_MODULE="yarn" NODE_VERSION="24" setup_nodejs
msg_info "Stopping Service"
systemctl stop mealie
msg_ok "Stopped Service"
msg_info "Backing up configuration"
mkdir -p /opt/mealie_bak
cp -f /opt/mealie/mealie.env /opt/mealie_bak/mealie.env.bak
cp -f /opt/mealie/start.sh /opt/mealie_bak/start.sh.bak
msg_ok "Backup completed"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie"
msg_info "Rebuilding Frontend"
export NUXT_TELEMETRY_DISABLED=1
cd /opt/mealie/frontend
$STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000
$STD yarn generate
cp -r /opt/mealie/frontend/dist/* /opt/mealie/mealie/frontend/
msg_ok "Frontend rebuilt"
msg_info "Updating Python Dependencies"
cd /opt/mealie
$STD uv sync --frozen --extra pgsql
msg_ok "Dependencies updated"
msg_info "Restoring configuration"
grep -q "^SECRET=" /opt/mealie_bak/mealie.env.bak || echo "SECRET=$(openssl rand -hex 32)" >>/opt/mealie_bak/mealie.env.bak
grep -q "^MEALIE_HOME=" /opt/mealie_bak/mealie.env.bak || echo "MEALIE_HOME=/opt/mealie" >>/opt/mealie_bak/mealie.env.bak
grep -q "^NLTK_DATA=" /opt/mealie_bak/mealie.env.bak || echo "NLTK_DATA=/nltk_data" >>/opt/mealie_bak/mealie.env.bak
mv -f /opt/mealie_bak/mealie.env.bak /opt/mealie/mealie.env
mv -f /opt/mealie_bak/start.sh.bak /opt/mealie/start.sh
chmod +x /opt/mealie/start.sh
sed -i 's|exec .*|source /opt/mealie/.venv/bin/activate\nexec uv run mealie|' /opt/mealie/start.sh
msg_ok "Configuration restored"
msg_info "Starting Service"
systemctl start mealie
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}:9000${CL}"

View File

@ -1,73 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.tp-link.com/us/support/download/omada-software-controller/
APP="Omada"
var_tags="${var_tags:-tp-link;controller}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-3072}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/tplink ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating MongoDB"
if lscpu | grep -q 'avx'; then
MONGO_VERSION="8.0" setup_mongodb
else
msg_warn "No AVX detected: Using older MongoDB 4.4"
MONGO_VERSION="4.4" setup_mongodb
fi
msg_info "Checking if right Azul Zulu Java is installed"
java_version=$(java -version 2>&1 | awk -F[\"_] '/version/ {print $2}')
if [[ "$java_version" =~ ^1\.8\.* ]]; then
$STD apt remove --purge -y zulu8-jdk
$STD apt -y install zulu21-jre-headless
msg_ok "Updated Azul Zulu Java to 21"
else
msg_ok "Azul Zulu Java 21 already installed"
fi
msg_info "Updating Omada Controller"
OMADA_URL=$(curl -fsSL "https://support.omadanetworks.com/en/download/software/omada-controller/" |
grep -o 'https://static\.tp-link\.com/upload/software/[^"]*linux_x64[^"]*\.deb' |
head -n1)
OMADA_PKG=$(basename "$OMADA_URL")
if [ -z "$OMADA_PKG" ]; then
msg_error "Could not retrieve Omada package server may be down."
exit
fi
curl -fsSL "$OMADA_URL" -o "$OMADA_PKG"
export DEBIAN_FRONTEND=noninteractive
$STD dpkg -i "$OMADA_PKG"
rm -f "$OMADA_PKG"
msg_ok "Updated successfully!"
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}https://${IP}:8043${CL}"

View File

@ -1,45 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://www.passbolt.com/
APP="Passbolt"
var_tags="${var_tags:-auth}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-2}"
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 /var ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating $APP LXC"
$STD apt update
$STD apt upgrade -y
msg_ok "Updated $APP LXC"
cleanup_lxc
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}https://${IP}${CL}"

View File

@ -1,54 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Eduard González (wanetty)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/wanetty/upgopher
APP="Upgopher"
var_tags="${var_tags:-file-sharing}"
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/upgopher ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "upgopher" "wanetty/upgopher"; then
msg_info "Stopping Service"
systemctl stop upgopher
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "upgopher" "wanetty/upgopher" "prebuild" "latest" "/opt/upgopher" "upgopher_*_linux_amd64.tar.gz"
chmod +x /opt/upgopher/upgopher
msg_info "Starting Service"
systemctl start upgopher
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}:9090${CL}"

View File

@ -1,44 +0,0 @@
{
"name": "Domain Locker",
"slug": "domain-locker",
"categories": [
9
],
"date_created": "2025-11-10",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://domain-locker.com/about",
"config_path": "/opt/domain-locker.env",
"website": "https://github.com/Lissy93/domain-locker",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/domain-locker.webp",
"description": "The all-in-one tool, for keeping track of your domain name portfolio. Got domain names? Get Domain Locker! ",
"install_methods": [
{
"type": "default",
"script": "ct/domain-locker.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Show DB credentials: `cat ~/Domain-Locker.creds`",
"type": "info"
},
{
"text": "Domain-locker takes quite some time to build and a lot of ressources, RAM and Cores can be lowered after install.",
"type": "info"
}
]
}

View File

@ -0,0 +1,48 @@
{
"name": "Ente",
"slug": "ente",
"categories": [
20
],
"date_created": "2025-11-22",
"type": "ct",
"updateable": false,
"privileged": false,
"config_path": "/opt",
"interface_port": 3000,
"documentation": "https://github.com/ente-io/ente",
"website": "https://ente.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/ente-photos.svg",
"description": "Ente is a service that provides a fully open source, end-to-end encrypted platform for you to store your data in the cloud without needing to trust the service provider. On top of this platform, we have built two apps so far: Ente Photos (an alternative to Apple and Google Photos) and Ente Auth (a 2FA alternative to the deprecated Authy).",
"install_methods": [
{
"type": "default",
"script": "ct/ente.sh",
"resources": {
"cpu": 4,
"ram": 4096,
"hdd": 10,
"os": "debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Please use `journalctl -u ente-museum.service -n 10` to read logs for the signup verification code",
"type": "info"
},
{
"text": "If you want to use the Ente CLI to add/whitelist admins, please follow the instructions at https://ente.io/help/self-hosting/administration/cli",
"type": "info"
},
{
"text": "To see Museium config: `cat /opt/ente/server/museum.yaml`",
"type": "info"
}
]
}

View File

@ -1,35 +0,0 @@
{
"name": "LibreNMS",
"slug": "librenms",
"categories": [
9
],
"date_created": "2025-03-24",
"type": "ct",
"updateable": false,
"privileged": false,
"interface_port": 80,
"documentation": "https://docs.librenms.org/",
"website": "https://librenms.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/librenms.webp",
"config_path": "/opt/librenms/config.php and /opt/librenms/.env",
"description": "LibreNMS is an open-source, community-driven network monitoring system that provides automatic discovery, alerting, and performance tracking for network devices. It supports a wide range of hardware and integrates with various notification and logging platforms.",
"install_methods": [
{
"type": "default",
"script": "ct/librenms.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "Debian",
"version": "12"
}
}
],
"default_credentials": {
"username": "admin",
"password": "admin"
},
"notes": []
}

View File

@ -1,44 +0,0 @@
{
"name": "Passbolt",
"slug": "passbolt",
"categories": [
6
],
"date_created": "2025-09-04",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 443,
"documentation": "https://www.passbolt.com/docs/",
"config_path": "/etc/passbolt/passbolt.php",
"website": "https://www.passbolt.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/passbolt.webp",
"description": "Passbolt is a hybrid credential platform. It is built-first for modern IT teams, yet simple enough for everyone. A sovereign, battle-tested solution that delivers for a team of 5, or an organisation of 5000.",
"install_methods": [
{
"type": "default",
"script": "ct/passbolt.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 2,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Type `cat ~/.Passbolt.creds` to see MariaDB database credentials. You will need those to setup Passbolt.",
"type": "info"
},
{
"text": "The application uses self-signed certificates. You can also use Let's Encrypt to get a valid certificate for your domain. Please read the documentation for more information.",
"type": "info"
}
]
}

View File

@ -0,0 +1,46 @@
{
"name": "qbittorrent Exporter",
"slug": "qbittorrent-exporter",
"categories": [
9
],
"date_created": "2025-11-21",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": 8090,
"documentation": "https://github.com/martabal/qbittorrent-exporter",
"website": "https://github.com/martabal/qbittorrent-exporter",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/qbittorrent.webp",
"config_path": "/opt/qbittorrent-exporter.env",
"description": "A fast and lightweight prometheus exporter for qBittorrent ",
"install_methods": [
{
"type": "default",
"script": "tools/addon/qbittorrent-exporter.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
},
{
"type": "alpine",
"script": "tools/addon/qbittorrent-exporter.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@ -1,52 +0,0 @@
{
"name": "Upgopher",
"slug": "upgopher",
"categories": [
11
],
"date_created": "2025-10-31",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 9090,
"documentation": "https://github.com/wanetty/upgopher#readme",
"config_path": "",
"website": "https://github.com/wanetty/upgopher",
"logo": "https://raw.githubusercontent.com/wanetty/upgopher/main/static/logopher.webp",
"description": "A simple Go web server for file upload, download, and browsing. Cross-platform alternative to Python-based file servers with no library dependencies. Features file upload via web interface, directory navigation, URL copying to clipboard, optional basic authentication, HTTPS support, and hidden files toggle.",
"install_methods": [
{
"type": "default",
"script": "ct/upgopher.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 4,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Default: HTTP on port 9090, no authentication, uploads dir: /opt/upgopher/uploads",
"type": "info"
},
{
"text": "To customize: edit /etc/systemd/system/upgopher.service and modify ExecStart line. Available flags: -user <user> -pass <pass> (authentication), -ssl (HTTPS with self-signed cert), -port <port> (custom port), -dir <path> (upload directory), -disable-hidden-files (hide hidden files)",
"type": "info"
},
{
"text": "Example with auth: ExecStart=/opt/upgopher/upgopher -port 9090 -dir /opt/upgopher/uploads -user admin -pass mysecret",
"type": "info"
},
{
"text": "After editing service file: systemctl daemon-reload && systemctl restart upgopher",
"type": "info"
}
]
}

View File

@ -1,114 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: michelroegl-brunner
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://asterisk.org
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
ASTERISK_VERSIONS_URL="https://www.asterisk.org/downloads/asterisk/all-asterisk-versions/"
html=$(curl -fsSL "$ASTERISK_VERSIONS_URL")
LTS_VERSION=""
for major in 20 22 24 26; do
block=$(echo "$html" | awk "/Asterisk $major - LTS/,/<ul>/" || true)
ver=$(echo "$block" | grep -oE 'Download Latest - [0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1 | sed -E 's/.* - //' || true)
if [ -n "$ver" ]; then
LTS_VERSION="$LTS_VERSION $ver"
fi
unset ver block
done
LTS_VERSION=$(echo "$LTS_VERSION" | xargs | tr ' ' '\n' | sort -V | tail -n1)
STD_VERSION=""
for major in 21 23 25 27; do
block=$(echo "$html" | grep -A 20 "Asterisk $major</h3>" | head -n 20 || true)
ver=$(echo "$block" | grep -oE 'Download (Latest - )?'"$major"'\.[0-9]+\.[0-9]+' | head -n1 | sed -E 's/Download (Latest - )?//' || true)
if [ -n "$ver" ]; then
STD_VERSION="$STD_VERSION $ver"
fi
unset ver block
done
STD_VERSION=$(echo "$STD_VERSION" | xargs | tr ' ' '\n' | sort -V | tail -n1)
cert_block=$(echo "$html" | awk '/Certified Asterisk/,/<ul>/')
CERT_VERSION=$(echo "$cert_block" | grep -oE 'Download Latest - [0-9]+\.[0-9]+-cert[0-9]+' | head -n1 | sed -E 's/.* - //' || true)
cat <<EOF
Choose Asterisk version to install:
1) Latest Standard ($STD_VERSION)
2) Latest LTS ($LTS_VERSION)
3) Latest Certified ($CERT_VERSION)
EOF
read -rp "Enter choice [1-3]: " ASTERISK_CHOICE
CERTIFIED=0
case "$ASTERISK_CHOICE" in
2)
ASTERISK_VERSION="$LTS_VERSION"
;;
3)
ASTERISK_VERSION="$CERT_VERSION"
CERTIFIED=1
;;
*)
ASTERISK_VERSION="$STD_VERSION"
;;
esac
if [[ "$CERTIFIED" == "1" ]]; then
RELEASE="certified-asterisk-${ASTERISK_VERSION}.tar.gz"
DOWNLOAD_URL="https://downloads.asterisk.org/pub/telephony/certified-asterisk/$RELEASE"
else
RELEASE="asterisk-${ASTERISK_VERSION}.tar.gz"
DOWNLOAD_URL="https://downloads.asterisk.org/pub/telephony/asterisk/$RELEASE"
fi
msg_info "Installing Dependencies"
$STD apt install -y \
libsrtp2-dev \
build-essential \
libedit-dev \
uuid-dev \
libjansson-dev \
libxml2-dev \
libsqlite3-dev
msg_ok "Installed Dependencies"
msg_info "Downloading Asterisk"
temp_file=$(mktemp)
curl -fsSL "$DOWNLOAD_URL" -o "$temp_file"
mkdir -p /opt/asterisk
tar zxf "$temp_file" --strip-components=1 -C /opt/asterisk
cd /opt/asterisk
msg_ok "Downloaded Asterisk ($RELEASE)"
msg_info "Installing Asterisk"
$STD ./contrib/scripts/install_prereq install
$STD ./configure
$STD make -j$(nproc)
$STD make install
$STD make config
$STD make install-logrotate
$STD make samples
mkdir -p /etc/radiusclient-ng/
ln /etc/radcli/radiusclient.conf /etc/radiusclient-ng/radiusclient.conf
systemctl enable -q --now asterisk
msg_ok "Installed Asterisk"
motd_ssh
customize
msg_info "Cleaning up"
rm -f "$temp_file"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

View File

@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/fccview/cronmaster
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 pciutils
msg_ok "Installed dependencies"
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
setup_deb822_repo \
"docker" \
"https://download.docker.com/linux/debian/gpg" \
"https://download.docker.com/linux/debian" \
"trixie" \
"stable"
$STD apt install -y docker-ce-cli
fetch_and_deploy_gh_release "cronmaster" "fccview/cronmaster" "tarball"
msg_info "Setting up CronMaster"
AUTH_PASS="$(openssl rand -base64 18 | cut -c1-13)"
cd /opt/cronmaster
$STD yarn --frozen-lockfile
export NEXT_TELEMETRY_DISABLED=1
$STD yarn build
cat <<EOF >/opt/cronmaster/.env
NODE_ENV=production
APP_URL=
LOCALE=
HOME=
AUTH_PASSWORD=${AUTH_PASS}
PORT=3000
HOSTNAME="0.0.0.0"
NEXT_TELEMETRY_DISABLED=1
EOF
{
echo "CronMaster Credentials:"
echo ""
echo "Password: $AUTH_PASS"
}>>~/cronmaster.creds
msg_ok "Setup CronMaster"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/cronmaster.service
[Unit]
Description=CronMaster Service
After=network.target
[Service]
EnvironmentFile=/opt/cronmaster/.env
WorkingDirectory=/opt/cronmaster
ExecStart=/usr/bin/yarn start
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl start --now -q cronmaster
msg_info "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@ -1,72 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/CrazyWolf13/domain-locker
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
PG_VERSION="17" setup_postgresql
PG_DB_NAME="domainlocker" PG_DB_USER="domainlocker" setup_postgresql_db
NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "domain-locker" "Lissy93/domain-locker"
msg_info "Installing Modules (patience)"
cd /opt/domain-locker
$STD npm install
msg_ok "Installed Modules"
msg_info "Building Domain-Locker (a lot of patience)"
cat <<EOF >/opt/domain-locker.env
# Database connection
DL_PG_HOST=localhost
DL_PG_PORT=5432
DL_PG_USER=$PG_DB_USER
DL_PG_PASSWORD=$PG_DB_PASS
DL_PG_NAME=$PG_DB_NAME
# Build + Runtime
DL_ENV_TYPE=selfHosted
NITRO_PRESET=node_server
NODE_ENV=production
EOF
set -a
source /opt/domain-locker.env
set +a
$STD npm run build
msg_info "Built Domain-Locker"
msg_info "Building Database schema"
export PGPASSWORD="$DL_PG_PASSWORD"
$STD psql -h "$DL_PG_HOST" -p "$DL_PG_PORT" -U "$DL_PG_USER" -d "$DL_PG_NAME" -f "/opt/domain-locker/db/schema.sql"
msg_ok "Built Database schema"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/domain-locker.service
[Unit]
Description=Domain-Locker Service
After=network.target
[Service]
EnvironmentFile=/opt/domain-locker.env
WorkingDirectory=/opt/domain-locker
ExecStart=/opt/domain-locker/start.sh
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl start --now -q domain-locker
msg_info "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@ -28,8 +28,22 @@ PG_VERSION="17" setup_postgresql
setup_go
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
ENTE_CLI_VERSION=$(curl -s https://api.github.com/repos/ente-io/ente/releases | jq -r '[.[] | select(.tag_name | startswith("cli-v"))][0].tag_name')
fetch_and_deploy_gh_release "ente" "ente-io/ente" "tarball" "latest" "/opt/ente"
fetch_and_deploy_gh_release "ente" "ente-io/ente" "tarball" "$ENTE_CLI_VERSION" "/usr/local/bin/ente" "ente-cli-$ENTE_CLI_VERSION-linux-amd64.tar.gz"
fetch_and_deploy_gh_release "ente-server" "ente-io/ente" "tarball" "latest" "/opt/ente"
fetch_and_deploy_gh_release "ente-cli" "ente-io/ente" "prebuild" "$ENTE_CLI_VERSION" "/usr/local/bin" "ente-$ENTE_CLI_VERSION-linux-amd64.tar.gz"
$STD mkdir -p /opt/ente/cli
msg_info "Configuring Ente CLI"
cat <<EOF >>~/.bashrc
export ENTE_CLI_SECRETS_PATH=/opt/ente/cli/secrets.txt
export PATH="/usr/local/bin:$PATH"
EOF
$STD source ~/.bashrc
$STD mkdir -p ~/.ente
cat <<EOF >~/.ente/config.yaml
endpoint:
api: http://localhost:8080
EOF
msg_ok "Configured Ente CLI"
msg_info "Setting up PostgreSQL"
DB_NAME="ente_db"
@ -133,13 +147,37 @@ jwt:
EOF
msg_ok "Created museum.yaml"
read -r -p "Enter the public URL for Ente backend (e.g., https://api.ente.yourdomain.com or http://192.168.1.100:8080) leave empty to use container IP: " backend_url
if [[ -z "$backend_url" ]]; then
LOCAL_IP=$(hostname -I | awk '{print $1}')
ENTE_BACKEND_URL="http://$LOCAL_IP:8080"
msg_info "No URL provided"
msg_ok "using local IP: $ENTE_BACKEND_URL\n"
else
ENTE_BACKEND_URL="$backend_url"
msg_info "URL provided"
msg_ok "Using provided URL: $ENTE_BACKEND_URL\n"
fi
read -r -p "Enter the public URL for Ente albums (e.g., https://albums.ente.yourdomain.com or http://192.168.1.100:3002) leave empty to use container IP: " albums_url
if [[ -z "$albums_url" ]]; then
LOCAL_IP=$(hostname -I | awk '{print $1}')
ENTE_ALBUMS_URL="http://$LOCAL_IP:3002"
msg_info "No URL provided"
msg_ok "using local IP: $ENTE_ALBUMS_URL\n"
else
ENTE_ALBUMS_URL="$albums_url"
msg_info "URL provided"
msg_ok "Using provided URL: $ENTE_ALBUMS_URL\n"
fi
export NEXT_PUBLIC_ENTE_ENDPOINT=$ENTE_BACKEND_URL
export NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=$ENTE_ALBUMS_URL
msg_info "Building Web Applications"
# Get container IP address
CONTAINER_IP=$(hostname -I | awk '{print $1}')
cd /opt/ente/web
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
$STD yarn install
export NEXT_PUBLIC_ENTE_ENDPOINT=http://${CONTAINER_IP}:8080
export NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=http://${CONTAINER_IP}:3002
$STD yarn build
$STD yarn build:accounts
$STD yarn build:auth
@ -153,12 +191,35 @@ cp -r apps/cast/out /var/www/ente/apps/cast
# Save build configuration for future rebuilds
cat <<REBUILD_EOF >/opt/ente/rebuild-frontend.sh
#!/usr/bin/env bash
# Rebuild Ente frontend with current IP
CONTAINER_IP=\$(hostname -I | awk '{print \$1}')
echo "Building frontend with IP: \$CONTAINER_IP"
# Rebuild Ente frontend
# Prompt for backend URL
read -r -p "Enter the public URL for Ente backend (e.g., https://api.ente.yourdomain.com or http://192.168.1.100:8080) leave empty to use container IP: " backend_url
if [[ -z "\$backend_url" ]]; then
LOCAL_IP=$(hostname -I | awk '{print $1}')
ENTE_BACKEND_URL="http://\$LOCAL_IP:8080"
echo "No URL provided, using local IP: \$ENTE_BACKEND_URL\n"
else
ENTE_BACKEND_URL="\$backend_url"
echo "Using provided URL: \$ENTE_BACKEND_URL\n"
fi
# Prompt for albums URL
read -r -p "Enter the public URL for Ente albums (e.g., https://albums.ente.yourdomain.com or http://192.168.1.100:3002) leave empty to use container IP: " albums_url
if [[ -z "\$albums_url" ]]; then
LOCAL_IP=\$(hostname -I | awk '{print $1}')
ENTE_ALBUMS_URL="http://\$LOCAL_IP:3002"
echo "No URL provided, using local IP: \$ENTE_ALBUMS_URL\n"
else
ENTE_ALBUMS_URL="\$albums_url"
echo "Using provided URL: \$ENTE_ALBUMS_URL\n"
fi
export NEXT_PUBLIC_ENTE_ENDPOINT=\$ENTE_BACKEND_URL
export NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=\$ENTE_ALBUMS_URL
echo "Building Web Applications\n"
cd /opt/ente/web
export NEXT_PUBLIC_ENTE_ENDPOINT=http://\${CONTAINER_IP}:8080
export NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=http://\${CONTAINER_IP}:3002
yarn build
yarn build:accounts
yarn build:auth
@ -312,8 +373,9 @@ echo -e "━━━━━━━━━━━━━━━━━━━━━━━
echo -e "\n${BL}Access URLs:${CL}"
echo -e " Photos: http://${CONTAINER_IP}:3000"
echo -e " Accounts: http://${CONTAINER_IP}:3001"
echo -e " Albums: ${ENTE_ALBUMS_URL}"
echo -e " Auth: http://${CONTAINER_IP}:3003"
echo -e " API: http://${CONTAINER_IP}:8080"
echo -e " API: ${ENTE_BACKEND_URL}"
echo -e "\n${YW}⚠️ Important Post-Installation Steps:${CL}"
echo -e "\n${BL}1. Create your first account:${CL}"
echo -e " • Open http://${CONTAINER_IP}:3000 in your browser"

View File

@ -0,0 +1,94 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://joplinapp.org/
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 \
git \
rsync
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
NODE_VERSION=24 NODE_MODULE="yarn,npm,pm2" setup_nodejs
mkdir -p /opt/pm2
export PM2_HOME=/opt/pm2
$STD pm2 install pm2-logrotate
$STD pm2 set pm2-logrotate:max_size 100MB
$STD pm2 set pm2-logrotate:retain 5
$STD pm2 set pm2-logrotate:compress tr
msg_info "Setting up PostgreSQL Database"
DB_NAME=joplin
DB_USER=joplin
DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
{
echo "Joplin-Credentials"
echo "Joplin Database User: $DB_USER"
echo "Joplin Database Password: $DB_PASS"
echo "Joplin Database Name: $DB_NAME"
} >>~/joplin.creds
msg_ok "Set up PostgreSQL Database"
fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball" "latest"
msg_info "Setting up Joplin Server (Patience)"
LOCAL_IP=$(hostname -I | awk '{print $1}')
cd /opt/joplin-server
sed -i "/onenote-converter/d" packages/lib/package.json
$STD yarn config set --home enableTelemetry 0
export BUILD_SEQUENCIAL=1
$STD yarn install --inline-builds
cat <<EOF >/opt/joplin-server/.env
PM2_HOME=/opt/pm2
NODE_ENV=production
APP_BASE_URL=http://$LOCAL_IP:22300
APP_PORT=22300
DB_CLIENT=pg
POSTGRES_PASSWORD=$DB_PASS
POSTGRES_DATABASE=$DB_NAME
POSTGRES_USER=$DB_USER
POSTGRES_PORT=5432
POSTGRES_HOST=localhost
EOF
msg_ok "Setup Joplin Server"
msg_info "Setting up Service"
cat <<EOF >/etc/systemd/system/joplin-server.service
[Unit]
Description=Joplin Server Service
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/joplin-server/packages/server
EnvironmentFile=/opt/joplin-server/.env
ExecStart=/usr/bin/yarn start-prod
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now joplin-server
msg_ok "Service Setup"
motd_ssh
customize
cleanup_lxc

View File

@ -1,147 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: michelroegl-brunner
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/opf/openproject
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 \
acl \
fping \
graphviz \
imagemagick \
mtr-tiny \
nginx \
nmap \
rrdtool \
snmp \
snmpd \
whois
msg_ok "Installed Dependencies"
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="gmp,mysql,snmp" setup_php
setup_mariadb
setup_composer
PYTHON_VERSION="3.13" setup_uv
msg_info "Installing Python Dependencies"
$STD apt install -y \
python3-dotenv \
python3-pymysql \
python3-redis \
python3-setuptools \
python3-systemd \
python3-pip
msg_ok "Installed Python Dependencies"
MARIADB_DB_NAME="librenms" MARIADB_DB_USER="librenms" MARIADB_DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)" setup_mariadb_db
fetch_and_deploy_gh_release "librenms" "librenms/librenms"
msg_info "Configuring LibreNMS"
$STD useradd librenms -d /opt/librenms -M -r -s "$(which bash)"
mkdir -p /opt/librenms/{rrd,logs,bootstrap/cache,storage,html}
cd /opt/librenms
APP_KEY=$(openssl rand -base64 40 | tr -dc 'a-zA-Z0-9')
$STD uv venv .venv
$STD source .venv/bin/activate
$STD uv pip install -r requirements.txt
cat <<EOF >/opt/librenms/.env
DB_DATABASE=${MARIADB_DB_NAME}
DB_USERNAME=${MARIADB_DB_USER}
DB_PASSWORD=${MARIADB_DB_PASS}
APP_KEY=${APP_KEY}
EOF
chown -R librenms:librenms /opt/librenms
chmod 771 /opt/librenms
chmod -R ug=rwX /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
msg_ok "Configured LibreNMS"
msg_info "Configure MariaDB"
sed -i "/\[mysqld\]/a innodb_file_per_table=1\nlower_case_table_names=0" /etc/mysql/mariadb.conf.d/50-server.cnf
systemctl enable -q --now mariadb
msg_ok "Configured MariaDB"
msg_info "Configure PHP-FPM"
cp /etc/php/8.4/fpm/pool.d/www.conf /etc/php/8.4/fpm/pool.d/librenms.conf
sed -i "s/\[www\]/\[librenms\]/g" /etc/php/8.4/fpm/pool.d/librenms.conf
sed -i "s/user = www-data/user = librenms/g" /etc/php/8.4/fpm/pool.d/librenms.conf
sed -i "s/group = www-data/group = librenms/g" /etc/php/8.4/fpm/pool.d/librenms.conf
sed -i "s/listen = \/run\/php\/php8.4-fpm.sock/listen = \/run\/php-fpm-librenms.sock/g" /etc/php/8.4/fpm/pool.d/librenms.conf
msg_ok "Configured PHP-FPM"
msg_info "Configure Nginx"
IP_ADDR=$(hostname -I | awk '{print $1}')
cat >/etc/nginx/sites-enabled/librenms <<'EOF'
server {
listen 80;
server_name ${IP_ADDR};
root /opt/librenms/html;
index index.php;
charset utf-8;
gzip on;
gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ [^/]\.php(/|$) {
fastcgi_pass unix:/run/php-fpm-librenms.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi.conf;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
EOF
rm /etc/nginx/sites-enabled/default
$STD systemctl reload nginx
systemctl restart php8.4-fpm
msg_ok "Configured Nginx"
msg_info "Configure Services"
ln -s /opt/librenms/lnms /usr/bin/lnms
mkdir -p /etc/bash_completion.d/
cp /opt/librenms/misc/lnms-completion.bash /etc/bash_completion.d/
cp /opt/librenms/snmpd.conf.example /etc/snmp/snmpd.conf
$STD su - librenms -s /bin/bash -c "cd /opt/librenms && COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev"
$STD su - librenms -s /bin/bash -c "cd /opt/librenms && php8.4 artisan migrate --force"
$STD su - librenms -s /bin/bash -c "cd /opt/librenms && php8.4 artisan key:generate --force"
$STD su - librenms -s /bin/bash -c "cd /opt/librenms && lnms db:seed --force"
$STD su - librenms -s /bin/bash -c "cd /opt/librenms && lnms user:add -p admin -r admin admin"
RANDOM_STRING=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9')
sed -i "s/RANDOMSTRINGHERE/$RANDOM_STRING/g" /etc/snmp/snmpd.conf
echo "SNMP Community String: $RANDOM_STRING" >>~/librenms.creds
curl -qso /usr/bin/distro https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro
chmod +x /usr/bin/distro
systemctl enable -q --now snmpd
cp /opt/librenms/dist/librenms.cron /etc/cron.d/librenms
cp /opt/librenms/dist/librenms-scheduler.service /opt/librenms/dist/librenms-scheduler.timer /etc/systemd/system/
systemctl enable -q --now librenms-scheduler.timer
cp /opt/librenms/misc/librenms.logrotate /etc/logrotate.d/librenms
msg_ok "Configured Services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
msg_ok "Cleaned"

110
install/mealie-install.sh Normal file
View File

@ -0,0 +1,110 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://mealie.io
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 \
libpq-dev \
libwebp-dev \
libsasl2-dev \
libldap2-dev \
libssl-dev
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
POSTGRES_VERSION="16" setup_postgresql
NODE_MODULE="yarn" NODE_VERSION="24" setup_nodejs
fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie"
PG_DB_NAME="mealie_db" PG_DB_USER="mealie_user" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
msg_info "Installing Python Dependencies with uv"
cd /opt/mealie
$STD uv sync --frozen --extra pgsql
msg_ok "Installed Python Dependencies"
msg_info "Building Frontend"
export NUXT_TELEMETRY_DISABLED=1
cd /opt/mealie/frontend
$STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000
$STD yarn generate
msg_ok "Built Frontend"
msg_info "Copying Built Frontend"
mkdir -p /opt/mealie/mealie/frontend
cp -r /opt/mealie/frontend/dist/* /opt/mealie/mealie/frontend/
msg_ok "Copied Frontend"
msg_info "Downloading NLTK Data"
mkdir -p /nltk_data/
cd /opt/mealie
$STD uv run python -m nltk.downloader -d /nltk_data averaged_perceptron_tagger_eng
msg_ok "Downloaded NLTK Data"
msg_info "Writing Environment File"
SECRET=$(openssl rand -hex 32)
mkdir -p /run/secrets
cat <<EOF >/opt/mealie/mealie.env
MEALIE_HOME=/opt/mealie
NLTK_DATA=/nltk_data
SECRET=${SECRET}
DB_ENGINE=postgres
POSTGRES_SERVER=localhost
POSTGRES_PORT=5432
POSTGRES_USER=${PG_DB_USER}
POSTGRES_PASSWORD=${PG_DB_PASS}
POSTGRES_DB=${PG_DB_NAME}
PRODUCTION=true
HOST=0.0.0.0
PORT=9000
EOF
msg_ok "Wrote Environment File"
msg_info "Creating Start Script"
cat <<'EOF' >/opt/mealie/start.sh
#!/bin/bash
set -a
source /opt/mealie/mealie.env
set +a
exec uv run mealie
EOF
chmod +x /opt/mealie/start.sh
msg_ok "Created Start Script"
msg_info "Creating Systemd Service"
cat <<'EOF' >/etc/systemd/system/mealie.service
[Unit]
Description=Mealie Recipe Manager
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/mealie
ExecStart=/opt/mealie/start.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now mealie
msg_ok "Created and Started Service"
motd_ssh
customize
cleanup_lxc

View File

@ -1,53 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.tp-link.com/us/support/download/omada-software-controller/
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 jsvc
msg_ok "Installed Dependencies"
if lscpu | grep -q 'avx'; then
MONGO_VERSION="8.0" setup_mongodb
else
MONGO_VERSION="4.4" setup_mongodb
fi
JAVA_VERSION="21" setup_java
# if ! dpkg -l | grep -q 'libssl1.1'; then
# msg_info "Installing libssl (if needed)"
# curl -fsSL "https://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1w-0+deb11u4_amd64.deb" -o "/tmp/libssl.deb"
# $STD dpkg -i /tmp/libssl.deb
# rm -f /tmp/libssl.deb
# msg_ok "Installed libssl1.1"
# fi
msg_info "Installing Omada Controller"
OMADA_URL=$(curl -fsSL "https://support.omadanetworks.com/en/download/software/omada-controller/" |
grep -o 'https://static\.tp-link\.com/upload/software/[^"]*linux_x64[^"]*\.deb' |
head -n1)
OMADA_PKG=$(basename "$OMADA_URL")
curl -fsSL "$OMADA_URL" -o "$OMADA_PKG"
$STD dpkg -i "$OMADA_PKG"
msg_ok "Installed Omada Controller"
motd_ssh
customize
msg_info "Cleaning up"
rm -rf "$OMADA_PKG"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

View File

@ -1,51 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://www.passbolt.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing dependencies"
$STD apt install -y \
apt-transport-https \
python3-certbot-nginx \
debconf-utils
msg_ok "Installed dependencies"
setup_mariadb
MARIADB_DB_NAME="passboltdb" MARIADB_DB_USER="passbolt" MARIADB_DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)" setup_mariadb_db
setup_deb822_repo \
"passbolt" \
"https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x3D1A0346C8E1802F774AEF21DE8B853FC155581D" \
"https://download.passbolt.com/ce/debian" \
"buster" \
"stable"
create_self_signed_cert "passbolt"
msg_info "Setting up Passbolt (Patience)"
export DEBIAN_FRONTEND=noninteractive
IP_ADDR=$(hostname -I | awk '{print $1}')
echo passbolt-ce-server passbolt/mysql-configuration boolean true | debconf-set-selections
echo passbolt-ce-server passbolt/mysql-passbolt-username string $MARIADB_DB_USER | debconf-set-selections
echo passbolt-ce-server passbolt/mysql-passbolt-password password $MARIADB_DB_PASS | debconf-set-selections
echo passbolt-ce-server passbolt/mysql-passbolt-password-repeat password $MARIADB_DB_PASS | debconf-set-selections
echo passbolt-ce-server passbolt/mysql-passbolt-dbname string $MARIADB_DB_NAME | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-configuration boolean true | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-configuration-three-choices select manual | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-domain string $IP_ADDR | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-certificate-file string /etc/ssl/passbolt/passbolt.crt | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-certificate-key-file string /etc/ssl/passbolt/passbolt.key | debconf-set-selections
$STD apt install -y --no-install-recommends passbolt-ce-server
msg_ok "Setup Passbolt"
motd_ssh
customize
cleanup_lxc

View File

@ -49,12 +49,13 @@ chmod +x /opt/privoxy/*.sh
$STD ln -s /usr/bin/transmission-daemon /usr/local/bin/transmission-daemon
$STD update-alternatives --set iptables /usr/sbin/iptables-legacy
$STD update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
rm -rf /opt/docker-transmission-openvpn
msg_ok "Configured transmission-openvpn"
msg_info "Creating Service"
LOCAL_SUBNETS=$(
ip -o -4 addr show \
| awk '!/127.0.0.1/ {
ip -o -4 addr show |
awk '!/127.0.0.1/ {
split($4, a, "/"); ip=a[1]; mask=a[2];
split(ip, o, ".");
if (mask < 8) {
@ -66,8 +67,8 @@ LOCAL_SUBNETS=$(
} else {
print o[1]"."o[2]"."o[3]".*";
}
}' \
| sort -u | paste -sd, -
}' |
sort -u | paste -sd, -
)
TRANSMISSION_RPC_WHITELIST="127.0.0.*,${LOCAL_SUBNETS}"
mkdir -p /opt/transmission-openvpn
@ -126,15 +127,9 @@ EnvironmentFile=/opt/transmission-openvpn/.env
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now -q openvpn-custom.service
systemctl enable -q --now openvpn-custom
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
rm -rf /opt/docker-transmission-openvpn
msg_ok "Cleaned"
cleanup_lxc

View File

@ -1,47 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Eduardo González (wanetty)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/wanetty/upgopher
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Upgopher"
mkdir -p /opt/upgopher
fetch_and_deploy_gh_release "upgopher" "wanetty/upgopher" "prebuild" "latest" "/opt/upgopher" "upgopher_*_linux_amd64.tar.gz"
chmod +x /opt/upgopher/upgopher
mkdir -p /opt/upgopher/uploads
msg_ok "Installed Upgopher"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/upgopher.service
[Unit]
Description=Upgopher File Server
Documentation=https://github.com/wanetty/upgopher
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/upgopher
ExecStart=/opt/upgopher/upgopher -port 9090 -dir /opt/upgopher/uploads
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now upgopher
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

3549
misc/build copy 2.func Normal file

File diff suppressed because it is too large Load Diff

View File

@ -535,35 +535,6 @@ base_settings() {
TAGS="community-script,${var_tags:-}"
ENABLE_FUSE=${var_fuse:-"${1:-no}"}
ENABLE_TUN=${var_tun:-"${1:-no}"}
ENABLE_NESTING=${var_nesting:-"${1:-1}"}
ENABLE_KEYCTL=${var_keyctl:-"${1:-0}"}
ALLOW_MOUNT_FS=${var_mount_fs:-""}
ENABLE_MKNOD=${var_mknod:-"${1:-0}"}
PROTECT_CT=${var_protection:-"${1:-no}"}
CT_TIMEZONE=${var_timezone:-""}
# Normalize feature flags to 0/1 immediately (pct requires numeric values, not yes/no)
# This must happen here before any usage of these variables
case "${ENABLE_NESTING,,}" in
yes | true) ENABLE_NESTING="1" ;;
no | false) ENABLE_NESTING="0" ;;
esac
case "${ENABLE_KEYCTL,,}" in
yes | true) ENABLE_KEYCTL="1" ;;
no | false) ENABLE_KEYCTL="0" ;;
esac
case "${ENABLE_MKNOD,,}" in
yes | true) ENABLE_MKNOD="1" ;;
no | false) ENABLE_MKNOD="0" ;;
esac
case "${ENABLE_FUSE,,}" in
yes | true) ENABLE_FUSE="1" ;;
no | false) ENABLE_FUSE="0" ;;
esac
case "${PROTECT_CT,,}" in
yes | true) PROTECT_CT="1" ;;
no | false) PROTECT_CT="0" ;;
esac
# Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts
if [ -z "$var_os" ]; then
@ -1795,7 +1766,16 @@ install_script() {
fi
NEXTID=$(pvesh get /cluster/nextid)
# Get timezone using timedatectl (Debian 13+ compatible)
# Fallback to /etc/timezone for older systems
if command -v timedatectl >/dev/null 2>&1; then
timezone=$(timedatectl show --value --property=Timezone 2>/dev/null || echo "UTC")
elif [ -f /etc/timezone ]; then
timezone=$(cat /etc/timezone)
else
timezone="UTC"
fi
# Show APP Header
header_info
@ -2289,35 +2269,19 @@ build_container() {
none) ;;
esac
# Build FEATURES array with advanced settings
# Note: All feature flags are already normalized to 0/1 in default_settings()
# Proxmox requires each feature as a separate parameter, not comma-separated string
FEATURES_ARRAY=()
FEATURES_ARRAY+=("nesting=${ENABLE_NESTING}")
# keyctl: needed for Docker inside containers (systemd-networkd workaround)
# Typically needed for unprivileged containers with Docker
if [ "$CT_TYPE" == "1" ] || [ "$ENABLE_KEYCTL" == "1" ]; then
FEATURES_ARRAY+=("keyctl=1")
# Build FEATURES string (simple working version)
if [ "$CT_TYPE" == "1" ]; then
FEATURES="keyctl=1,nesting=1"
else
FEATURES="nesting=1"
fi
# mknod: allow device node creation (requires kernel 5.3+, experimental)
if [ "$ENABLE_MKNOD" == "1" ]; then
FEATURES_ARRAY+=("mknod=1")
if [ "$ENABLE_FUSE" == "yes" ]; then
FEATURES="$FEATURES,fuse=1"
fi
# FUSE: required for rclone, mergerfs, AppImage, etc.
if [ "$ENABLE_FUSE" == "1" ]; then
FEATURES_ARRAY+=("fuse=1")
fi
# mount: allow specific filesystems (e.g., nfs, ext4, etc.)
# Format: mount=fstype1;fstype2;fstype3 (semicolon-separated, not comma!)
if [ -n "$ALLOW_MOUNT_FS" ]; then
# Replace commas with semicolons for proper pct syntax
ALLOW_MOUNT_FS_FORMATTED="${ALLOW_MOUNT_FS//,/;}"
FEATURES_ARRAY+=("mount=$ALLOW_MOUNT_FS_FORMATTED")
fi
# NEW IMPLEMENTATION (Fixed): Build PCT_OPTIONS properly
# Key insight: Bash cannot export arrays, so we build the options as a string
TEMP_DIR=$(mktemp -d)
pushd "$TEMP_DIR" >/dev/null
@ -2326,19 +2290,11 @@ build_container() {
else
export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/heads/byparr/misc/install.func)"
fi
# Core exports for install.func
export DIAGNOSTICS="$DIAGNOSTICS"
export RANDOM_UUID="$RANDOM_UUID"
export SESSION_ID="$SESSION_ID"
export BUILD_LOG="$BUILD_LOG"
export INSTALL_LOG="/root/.install-${SESSION_ID}.log"
export dev_mode="${dev_mode:-}"
export DEV_MODE_MOTD="${DEV_MODE_MOTD:-false}"
export DEV_MODE_KEEP="${DEV_MODE_KEEP:-false}"
export DEV_MODE_TRACE="${DEV_MODE_TRACE:-false}"
export DEV_MODE_PAUSE="${DEV_MODE_PAUSE:-false}"
export DEV_MODE_BREAKPOINT="${DEV_MODE_BREAKPOINT:-false}"
export DEV_MODE_LOGS="${DEV_MODE_LOGS:-false}"
export DEV_MODE_DRYRUN="${DEV_MODE_DRYRUN:-false}"
export CACHER="$APT_CACHER"
export CACHER_IP="$APT_CACHER_IP"
export tz="$timezone"
@ -2352,61 +2308,75 @@ build_container() {
export CTTYPE="$CT_TYPE"
export ENABLE_FUSE="$ENABLE_FUSE"
export ENABLE_TUN="$ENABLE_TUN"
export ENABLE_NESTING="$ENABLE_NESTING"
export ENABLE_KEYCTL="$ENABLE_KEYCTL"
export ENABLE_MKNOD="$ENABLE_MKNOD"
export ALLOW_MOUNT_FS="$ALLOW_MOUNT_FS"
export PROTECT_CT="$PROTECT_CT"
export CT_TIMEZONE="$CT_TIMEZONE"
export PCT_OSTYPE="$var_os"
export PCT_OSVERSION="$var_version"
export PCT_DISK_SIZE="$DISK_SIZE"
# Build PCT_OPTIONS array (not string) for proper parameter handling
PCT_OPTIONS=()
# DEV_MODE exports (optional, for debugging)
export BUILD_LOG="$BUILD_LOG"
export INSTALL_LOG="/root/.install-${SESSION_ID}.log"
export dev_mode="${dev_mode:-}"
export DEV_MODE_MOTD="${DEV_MODE_MOTD:-false}"
export DEV_MODE_KEEP="${DEV_MODE_KEEP:-false}"
export DEV_MODE_TRACE="${DEV_MODE_TRACE:-false}"
export DEV_MODE_PAUSE="${DEV_MODE_PAUSE:-false}"
export DEV_MODE_BREAKPOINT="${DEV_MODE_BREAKPOINT:-false}"
export DEV_MODE_LOGS="${DEV_MODE_LOGS:-false}"
export DEV_MODE_DRYRUN="${DEV_MODE_DRYRUN:-false}"
# Add features - each as separate -features parameter
for feature in "${FEATURES_ARRAY[@]}"; do
PCT_OPTIONS+=("-features" "$feature")
done
PCT_OPTIONS+=("-hostname" "$HN")
PCT_OPTIONS+=("-tags" "$TAGS")
# Build PCT_OPTIONS as multi-line string
PCT_OPTIONS_STRING=" -features $FEATURES
-hostname $HN
-tags $TAGS"
# Add storage if specified
if [ -n "$SD" ]; then
PCT_OPTIONS+=($SD) # Storage device flags (already formatted)
PCT_OPTIONS_STRING="$PCT_OPTIONS_STRING
$SD"
fi
# Add nameserver if specified
if [ -n "$NS" ]; then
PCT_OPTIONS+=($NS) # Nameserver flags (already formatted)
PCT_OPTIONS_STRING="$PCT_OPTIONS_STRING
$NS"
fi
# Network configuration (single string with all network parameters)
PCT_OPTIONS+=($NET_STRING)
# Network configuration
PCT_OPTIONS_STRING="$PCT_OPTIONS_STRING
$NET_STRING
-onboot 1
-cores $CORE_COUNT
-memory $RAM_SIZE
-unprivileged $CT_TYPE"
PCT_OPTIONS+=("-onboot" "1")
PCT_OPTIONS+=("-cores" "$CORE_COUNT")
PCT_OPTIONS+=("-memory" "$RAM_SIZE")
PCT_OPTIONS+=("-unprivileged" "$CT_TYPE")
# Protection flag
if [ "$PROTECT_CT" == "1" ]; then
PCT_OPTIONS+=("-protection" "1")
# Protection flag (if var_protection was set)
if [ "${PROTECT_CT:-}" == "1" ] || [ "${PROTECT_CT:-}" == "yes" ]; then
PCT_OPTIONS_STRING="$PCT_OPTIONS_STRING
-protection 1"
fi
# Timezone flag
if [ -n "$CT_TIMEZONE" ]; then
PCT_OPTIONS+=("-timezone" "$CT_TIMEZONE")
# Timezone flag (if var_timezone was set)
if [ -n "${CT_TIMEZONE:-}" ]; then
PCT_OPTIONS_STRING="$PCT_OPTIONS_STRING
-timezone $CT_TIMEZONE"
fi
# Password flag (already formatted as "-password xxx")
# Password (already formatted)
if [ -n "$PW" ]; then
PCT_OPTIONS+=($PW)
PCT_OPTIONS_STRING="$PCT_OPTIONS_STRING
$PW"
fi
export PCT_OPTIONS
# Export as string (this works, unlike arrays!)
export PCT_OPTIONS="$PCT_OPTIONS_STRING"
export TEMPLATE_STORAGE="${var_template_storage:-}"
export CONTAINER_STORAGE="${var_container_storage:-}"
# # DEBUG: Show final PCT_OPTIONS being exported
# echo "[DEBUG] PCT_OPTIONS to be exported:"
# echo "$PCT_OPTIONS" | sed 's/^/ /'
# echo "[DEBUG] Calling create_lxc_container..."
create_lxc_container || exit $?
LXC_CONFIG="/etc/pve/lxc/${CTID}.conf"
@ -2548,7 +2518,7 @@ EOF
if [[ $gpu_count -eq 1 ]]; then
# Automatic selection for single GPU
selected_gpu="${available_gpus[0]}"
msg_custom "⚙️" "${GN}" "Automatically configuring ${selected_gpu} GPU passthrough"
msg_ok "Automatically configuring ${selected_gpu} GPU passthrough"
else
# Multiple GPUs - ask user
echo -e "\n${INFO} Multiple GPU types detected:"
@ -2714,7 +2684,9 @@ EOF'
fi
if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then
pct exec "$CTID" -- bash -c "tz='$tz'; echo \"\$tz\" >/etc/timezone && ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime"
# Set timezone using symlink (Debian 13+ compatible)
# Create /etc/timezone for backwards compatibility with older scripts
pct exec "$CTID" -- bash -c "tz='$tz'; ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime && echo \"\$tz\" >/etc/timezone || true"
else
msg_warn "Skipping timezone setup zone '$tz' not found in container"
fi
@ -2747,8 +2719,8 @@ EOF'
# Show available logs
echo ""
[[ $build_log_copied == true ]] && echo -e "${GN}✔${CL} Container creation log: ${BL}/tmp/create-lxc-${CTID}-${SESSION_ID}.log${CL}"
[[ $install_log_copied == true ]] && echo -e "${GN}✔${CL} Installation log: ${BL}/tmp/install-lxc-${CTID}-${SESSION_ID}.log${CL}"
[[ "$build_log_copied" == true ]] && echo -e "${GN}✔${CL} Container creation log: ${BL}/tmp/create-lxc-${CTID}-${SESSION_ID}.log${CL}"
[[ "$install_log_copied" == true ]] && echo -e "${GN}✔${CL} Installation log: ${BL}/tmp/install-lxc-${CTID}-${SESSION_ID}.log${CL}"
fi
# Dev mode: Keep container or open breakpoint shell
@ -2888,7 +2860,7 @@ fix_gpu_gids() {
return 0
fi
msg_custom "🔧" "${BL}" "Detecting and setting correct GPU group IDs"
msg_info "Detecting and setting correct GPU group IDs"
# Get actual GIDs from container
local video_gid=$(pct exec "$CTID" -- sh -c "getent group video 2>/dev/null | cut -d: -f3")
@ -3091,7 +3063,7 @@ create_lxc_container() {
msg_ok "LXC stack upgraded."
if [[ "$do_retry" == "yes" ]]; then
msg_info "Retrying container creation after upgrade"
if pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >>"$LOGFILE" 2>&1; then
if pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
msg_ok "Container created successfully after upgrade."
return 0
else
@ -3517,9 +3489,12 @@ create_lxc_container() {
grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid
grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
# Assemble pct options
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
[[ " ${PCT_OPTIONS[*]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
# PCT_OPTIONS is now a string (exported from build_container)
# Add rootfs if not already specified
if [[ ! "$PCT_OPTIONS" =~ "-rootfs" ]]; then
PCT_OPTIONS="$PCT_OPTIONS
-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}"
fi
# Lock by template file (avoid concurrent downloads/creates)
lockfile="/tmp/template.${TEMPLATE}.lock"
@ -3533,11 +3508,22 @@ create_lxc_container() {
}
LOGFILE="/tmp/pct_create_${CTID}_$(date +%Y%m%d_%H%M%S)_${SESSION_ID}.log"
msg_debug "pct create command: pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}"
# # DEBUG: Show the actual command that will be executed
# echo "[DEBUG] ===== PCT CREATE COMMAND DETAILS ====="
# echo "[DEBUG] CTID: $CTID"
# echo "[DEBUG] Template: ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}"
# echo "[DEBUG] PCT_OPTIONS (will be word-split):"
# echo "$PCT_OPTIONS" | sed 's/^/ /'
# echo "[DEBUG] Full command line:"
# echo " pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} $PCT_OPTIONS"
# echo "[DEBUG] ========================================"
msg_debug "pct create command: pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} $PCT_OPTIONS"
msg_debug "Logfile: $LOGFILE"
# First attempt
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >"$LOGFILE" 2>&1; then
# First attempt (PCT_OPTIONS is a multi-line string, use it directly)
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >"$LOGFILE" 2>&1; then
msg_debug "Container creation failed on ${TEMPLATE_STORAGE}. Validating template..."
# Validate template file
@ -3556,7 +3542,7 @@ create_lxc_container() {
fi
# Retry after repair
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >>"$LOGFILE" 2>&1; then
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
# Fallback to local storage if not already on local
if [[ "$TEMPLATE_STORAGE" != "local" ]]; then
msg_info "Retrying container creation with fallback to local storage..."
@ -3565,7 +3551,7 @@ create_lxc_container() {
msg_info "Downloading template to local..."
pveam download local "$TEMPLATE" >/dev/null 2>&1
fi
if ! pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >>"$LOGFILE" 2>&1; then
if ! pct create "$CTID" "local:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
# Local fallback also failed - check for LXC stack version issue
if grep -qiE 'unsupported .* version' "$LOGFILE"; then
echo
@ -3589,7 +3575,7 @@ create_lxc_container() {
msg_error "Container creation failed. See $LOGFILE"
if whiptail --yesno "pct create failed.\nDo you want to enable verbose debug mode and view detailed logs?" 12 70; then
set -x
pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" 2>&1 | tee -a "$LOGFILE"
pct create "$CTID" "local:vztmpl/${TEMPLATE}" $PCT_OPTIONS 2>&1 | tee -a "$LOGFILE"
set +x
fi
exit 209
@ -3621,7 +3607,7 @@ create_lxc_container() {
msg_error "Container creation failed. See $LOGFILE"
if whiptail --yesno "pct create failed.\nDo you want to enable verbose debug mode and view detailed logs?" 12 70; then
set -x
pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" 2>&1 | tee -a "$LOGFILE"
pct create "$CTID" "local:vztmpl/${TEMPLATE}" $PCT_OPTIONS 2>&1 | tee -a "$LOGFILE"
set +x
fi
exit 209

View File

@ -272,7 +272,7 @@ root_check() {
# pve_check()
#
# - Validates Proxmox VE version compatibility
# - Supported: PVE 8.0-8.9 and PVE 9.0 only
# - Supported: PVE 8.0-8.9 and PVE 9.0-9.1
# - Exits with error message if unsupported version detected
# ------------------------------------------------------------------------------
pve_check() {
@ -290,12 +290,12 @@ pve_check() {
return 0
fi
# Check for Proxmox VE 9.x: allow ONLY 9.0
# Check for Proxmox VE 9.x: allow 9.09.1
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR != 0)); then
if ((MINOR < 0 || MINOR > 1)); then
msg_error "This version of Proxmox VE is not yet supported."
msg_error "Supported: Proxmox VE version 9.0"
msg_error "Supported: Proxmox VE version 9.0 9.1"
exit 1
fi
return 0
@ -303,7 +303,7 @@ pve_check() {
# All other unsupported versions
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0"
msg_error "Supported versions: Proxmox VE 8.0 8.9 or 9.0 9.1"
exit 1
}
@ -817,7 +817,7 @@ cleanup_lxc() {
# Python pip
if command -v pip &>/dev/null; then $STD pip cache purge || true; fi
# Python uv
if command -v uv &>/dev/null; then $STD uv cache clear || true; fi
if command -v uv &>/dev/null; then $STD uv cache clean || true; fi
# Node.js npm
if command -v npm &>/dev/null; then $STD npm cache clean --force || true; fi
# Node.js yarn

277
misc/install copy.func Normal file
View File

@ -0,0 +1,277 @@
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# Co-Author: MickLesk
# Co-Author: michelroegl-brunner
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# ==============================================================================
# INSTALL.FUNC - CONTAINER INSTALLATION & SETUP
# ==============================================================================
#
# This file provides installation functions executed inside LXC containers
# after creation. Handles:
#
# - Network connectivity verification (IPv4/IPv6)
# - OS updates and package installation
# - DNS resolution checks
# - MOTD and SSH configuration
# - Container customization and auto-login
#
# Usage:
# - Sourced by <app>-install.sh scripts
# - Executes via pct exec inside container
# - Requires internet connectivity
#
# ==============================================================================
# ==============================================================================
# SECTION 1: INITIALIZATION
# ==============================================================================
if ! command -v curl >/dev/null 2>&1; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func)
load_functions
catch_errors
# ==============================================================================
# SECTION 2: NETWORK & CONNECTIVITY
# ==============================================================================
# ------------------------------------------------------------------------------
# verb_ip6()
#
# - Configures IPv6 based on DISABLEIPV6 variable
# - If DISABLEIPV6=yes: disables IPv6 via sysctl
# - Sets verbose mode via set_std_mode()
# ------------------------------------------------------------------------------
verb_ip6() {
set_std_mode # Set STD mode based on VERBOSE
if [ "$DISABLEIPV6" == "yes" ]; then
echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf
$STD sysctl -p
fi
}
# ------------------------------------------------------------------------------
# setting_up_container()
#
# - Verifies network connectivity via hostname -I
# - Retries up to RETRY_NUM times with RETRY_EVERY seconds delay
# - Removes Python EXTERNALLY-MANAGED restrictions
# - Disables systemd-networkd-wait-online.service for faster boot
# - Exits with error if network unavailable after retries
# ------------------------------------------------------------------------------
setting_up_container() {
msg_info "Setting up Container OS"
for ((i = RETRY_NUM; i > 0; i--)); do
if [ "$(hostname -I)" != "" ]; then
break
fi
echo 1>&2 -en "${CROSS}${RD} No Network! "
sleep $RETRY_EVERY
done
if [ "$(hostname -I)" = "" ]; then
echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}"
echo -e "${NETWORK}Check Network Settings"
exit 1
fi
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
systemctl disable -q --now systemd-networkd-wait-online.service
msg_ok "Set up Container OS"
#msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)"
msg_ok "Network Connected: ${BL}$(hostname -I)"
}
# ------------------------------------------------------------------------------
# network_check()
#
# - Comprehensive network connectivity check for IPv4 and IPv6
# - Tests connectivity to multiple DNS servers:
# * IPv4: 1.1.1.1 (Cloudflare), 8.8.8.8 (Google), 9.9.9.9 (Quad9)
# * IPv6: 2606:4700:4700::1111, 2001:4860:4860::8888, 2620:fe::fe
# - Verifies DNS resolution for GitHub and Community-Scripts domains
# - Prompts user to continue if no internet detected
# - Uses fatal() on DNS resolution failure for critical hosts
# ------------------------------------------------------------------------------
network_check() {
set +e
trap - ERR
ipv4_connected=false
ipv6_connected=false
sleep 1
# Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers.
if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
msg_ok "IPv4 Internet Connected"
ipv4_connected=true
else
msg_error "IPv4 Internet Not Connected"
fi
# Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers.
if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then
msg_ok "IPv6 Internet Connected"
ipv6_connected=true
else
msg_error "IPv6 Internet Not Connected"
fi
# If both IPv4 and IPv6 checks fail, prompt the user
if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
else
echo -e "${NETWORK}Check Network Settings"
exit 1
fi
fi
# DNS resolution checks for GitHub-related domains (IPv4 and/or IPv6)
GIT_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org")
GIT_STATUS="Git DNS:"
DNS_FAILED=false
for HOST in "${GIT_HOSTS[@]}"; do
RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1)
if [[ -z "$RESOLVEDIP" ]]; then
GIT_STATUS+="$HOST:($DNSFAIL)"
DNS_FAILED=true
else
GIT_STATUS+=" $HOST:($DNSOK)"
fi
done
if [[ "$DNS_FAILED" == true ]]; then
fatal "$GIT_STATUS"
else
msg_ok "$GIT_STATUS"
fi
set -e
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
# ==============================================================================
# SECTION 3: OS UPDATE & PACKAGE MANAGEMENT
# ==============================================================================
# ------------------------------------------------------------------------------
# update_os()
#
# - Updates container OS via apt-get update and dist-upgrade
# - Configures APT cacher proxy if CACHER=yes (accelerates package downloads)
# - Removes Python EXTERNALLY-MANAGED restrictions for pip
# - Sources tools.func for additional setup functions after update
# - Uses $STD wrapper to suppress output unless VERBOSE=yes
# ------------------------------------------------------------------------------
update_os() {
msg_info "Updating Container OS"
if [[ "$CACHER" == "yes" ]]; then
echo "Acquire::http::Proxy-Auto-Detect \"/usr/local/bin/apt-proxy-detect.sh\";" >/etc/apt/apt.conf.d/00aptproxy
cat <<'EOF' >/usr/local/bin/apt-proxy-detect.sh
#!/bin/bash
if nc -w1 -z "${CACHER_IP}" 3142; then
echo -n "http://${CACHER_IP}:3142"
else
echo -n "DIRECT"
fi
EOF
chmod +x /usr/local/bin/apt-proxy-detect.sh
fi
$STD apt-get update
$STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
msg_ok "Updated Container OS"
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func)
}
# ==============================================================================
# SECTION 4: MOTD & SSH CONFIGURATION
# ==============================================================================
# ------------------------------------------------------------------------------
# motd_ssh()
#
# - Configures Message of the Day (MOTD) with container information
# - Creates /etc/profile.d/00_lxc-details.sh with:
# * Application name
# * Warning banner (DEV repository)
# * OS name and version
# * Hostname and IP address
# * GitHub repository link
# - Disables executable flag on /etc/update-motd.d/* scripts
# - Enables root SSH access if SSH_ROOT=yes
# - Configures TERM environment variable for better terminal support
# ------------------------------------------------------------------------------
motd_ssh() {
grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc
if [ -f "/etc/os-release" ]; then
OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"')
OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"')
elif [ -f "/etc/debian_version" ]; then
OS_NAME="Debian"
OS_VERSION=$(cat /etc/debian_version)
fi
PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
echo "echo -e \"\"" >"$PROFILE_FILE"
echo -e "echo -e \"${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}\"" >>"$PROFILE_FILE"
echo -e "echo -e \"${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}\"" >>"$PROFILE_FILE"
echo -e "echo -e \"${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE"
echo -e "echo -e \"${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE"
echo -e "echo -e \"${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE"
echo -e "echo -e \"${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}\"" >>"$PROFILE_FILE"
echo "echo \"\"" >>"$PROFILE_FILE"
chmod -x /etc/update-motd.d/*
if [[ "${SSH_ROOT}" == "yes" ]]; then
sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
systemctl restart sshd
fi
}
# ==============================================================================
# SECTION 5: CONTAINER CUSTOMIZATION
# ==============================================================================
# ------------------------------------------------------------------------------
# customize()
#
# - Customizes container for passwordless root login if PASSWORD is empty
# - Configures getty for auto-login via /etc/systemd/system/container-getty@1.service.d/override.conf
# - Creates /usr/bin/update script for easy application updates
# - Injects SSH authorized keys if SSH_AUTHORIZED_KEY variable is set
# - Sets proper permissions on SSH directories and key files
# ------------------------------------------------------------------------------
customize() {
if [[ "$PASSWORD" == "" ]]; then
msg_info "Customizing Container"
GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf"
mkdir -p $(dirname $GETTY_OVERRIDE)
cat <<EOF >$GETTY_OVERRIDE
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM
EOF
systemctl daemon-reload
systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//')
msg_ok "Customized Container"
fi
echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update
chmod +x /usr/bin/update
if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then
mkdir -p /root/.ssh
echo "${SSH_AUTHORIZED_KEY}" >/root/.ssh/authorized_keys
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys
fi
}

View File

@ -28,17 +28,6 @@
# SECTION 1: INITIALIZATION
# ==============================================================================
# Ensure INSTALL_LOG is set (exported from build.func, but fallback if missing)
if [[ -z "${INSTALL_LOG:-}" ]]; then
INSTALL_LOG="/root/.install-${SESSION_ID:-unknown}.log"
fi
# Dev mode: Persistent logs directory
if [[ "${DEV_MODE_LOGS:-false}" == "true" ]]; then
mkdir -p /var/log/community-scripts
INSTALL_LOG="/var/log/community-scripts/install-${SESSION_ID:-unknown}-$(date +%Y%m%d_%H%M%S).log"
fi
if ! command -v curl >/dev/null 2>&1; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1
@ -49,9 +38,6 @@ source <(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/he
load_functions
catch_errors
# Re-parse dev_mode in container context (flags exported from host)
parse_dev_mode
# ==============================================================================
# SECTION 2: NETWORK & CONNECTIVITY
# ==============================================================================
@ -122,23 +108,20 @@ network_check() {
# Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers.
if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
msg_ok "IPv4 Internet Connected"
ipv4_connected=true
ipv4_status="${GN}✔${CL} IPv4"
else
ipv4_status="${RD}✖${CL} IPv4"
msg_error "IPv4 Internet Not Connected"
fi
# Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers.
if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then
msg_ok "IPv6 Internet Connected"
ipv6_connected=true
ipv6_status="${GN}✔${CL} IPv6"
else
ipv6_status="${RD}✖${CL} IPv6"
msg_error "IPv6 Internet Not Connected"
fi
# Show combined status
msg_ok "Internet: ${ipv4_status} ${ipv6_status}"
# If both IPv4 and IPv6 checks fail, prompt the user
if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt
@ -274,10 +257,10 @@ customize() {
msg_info "Customizing Container"
GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf"
mkdir -p $(dirname $GETTY_OVERRIDE)
cat <<EOF >$GETTY_OVERRIDE
cat <<'EOF' >$GETTY_OVERRIDE
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM
ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 $TERM
EOF
systemctl daemon-reload
systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//')

View File

@ -394,9 +394,9 @@ check_root() {
}
pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -51,29 +51,29 @@ pve_check() {
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
# Proxmox VE 8.x: allow 8.0 8.9
if [[ "$PVE_VER" =~ ^9\.([0-9]+)(\.[0-9]+)?$ ]]; then
if [[ "$PVE_VER" =~ ^8\.([0-9]+)(\.[0-9]+)?$ ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR != 0)); then
if ((MINOR < 0 || MINOR > 9)); then
msg_error "Unsupported Proxmox VE version: $PVE_VER"
msg_error "Supported versions: 8.0 8.9 or 9.0.x"
msg_error "Supported versions: 8.0 8.9 or 9.0 9.1"
exit 1
fi
return 0
fi
# Proxmox VE 9.x: allow only 9.0
# Proxmox VE 9.x: allow 9.0 9.1
if [[ "$PVE_VER" =~ ^9\.([0-9]+)$ ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR != 0)); then
if ((MINOR < 0 || MINOR > 1)); then
msg_error "Unsupported Proxmox VE version: $PVE_VER"
msg_error "Supported versions: 8.0 8.9 or 9.0"
msg_error "Supported versions: 8.0 8.9 or 9.0 9.1"
exit 1
fi
return 0
fi
msg_error "Unsupported Proxmox VE version: $PVE_VER"
msg_error "Supported versions: 8.0 8.9 or 9.0"
msg_error "Supported versions: 8.0 8.9 or 9.0 9.1"
exit 1
}

View File

@ -0,0 +1,147 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
VERBOSE=${var_verbose:-no}
APP="qbittorrent-exporter"
APP_TYPE="tools"
INSTALL_PATH="/opt/qbittorrent-exporter/src/qbittorrent-exporter"
CONFIG_PATH="/opt/qbittorrent-exporter.env"
header_info
ensure_usr_local_bin_persist
get_current_ip &>/dev/null
# OS Detection
if [[ -f "/etc/alpine-release" ]]; then
OS="Alpine"
SERVICE_PATH="/etc/init.d/qbittorrent-exporter"
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
OS="Debian"
SERVICE_PATH="/etc/systemd/system/qbittorrent-exporter.service"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 1
fi
# Existing installation
if [[ -f "$INSTALL_PATH" ]]; then
echo -e "${YW}⚠️ qbittorrent-exporter is already installed.${CL}"
echo -n "Uninstall ${APP}? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Uninstalling qbittorrent-exporter"
if [[ "$OS" == "Debian" ]]; then
systemctl disable --now qbittorrent-exporter.service &>/dev/null
rm -f "$SERVICE_PATH"
else
rc-service qbittorrent-exporter stop &>/dev/null
rc-update del qbittorrent-exporter &>/dev/null
rm -f "$SERVICE_PATH"
fi
rm -f "$INSTALL_PATH" "$CONFIG_PATH" ~/.qbittorrent-exporter
msg_ok "${APP} has been uninstalled."
exit 0
fi
echo -n "Update qbittorrent-exporter? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
if check_for_gh_release "qbittorrent-exporter" "martabal/qbittorrent-exporter"; then
fetch_and_deploy_gh_release "qbittorrent-exporter" "martabal/qbittorrent-exporter"
setup_go
msg_info "Updating qbittorrent-exporter"
cd /opt/qbittorrent-exporter/src
/usr/local/bin/go build -o ./qbittorrent-exporter
msg_ok "Updated Successfully!"
fi
exit 0
else
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
exit 0
fi
fi
echo -e "${YW}⚠️ qbittorrent-exporter is not installed.${CL}"
echo -n "Enter URL of qbittorrent example: (http://192.168.1.10:8080): "
read -er QBITTORRENT_BASE_URL
echo -n "Enter qbittorrent username: "
read -er QBITTORRENT_USERNAME
echo -n "Enter qbittorrent password: "
read -rs QBITTORRENT_PASSWORD
echo ""
echo -n "Install qbittorrent-exporter? (y/n): "
read -r install_prompt
if ! [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
exit 0
fi
fetch_and_deploy_gh_release "qbittorrent-exporter" "martabal/qbittorrent-exporter" "tarball" "v1.12.0"
setup_go
msg_info "Installing qbittorrent-exporter on ${OS}"
cd /opt/qbittorrent-exporter/src
/usr/local/bin/go build -o ./qbittorrent-exporter
msg_ok "Installed qbittorrent-exporter"
msg_info "Creating configuration"
cat <<EOF >"$CONFIG_PATH"
QBITTORRENT_BASE_URL=${QBITTORRENT_BASE_URL}
QBITTORRENT_USERNAME=${QBITTORRENT_USERNAME}
QBITTORRENT_PASSWORD=${QBITTORRENT_PASSWORD}
EOF
msg_ok "Created configuration"
msg_info "Creating service"
if [[ "$OS" == "Debian" ]]; then
cat <<EOF >"$SERVICE_PATH"
[Unit]
Description=qbittorrent-exporter
After=network.target
[Service]
User=root
WorkingDirectory=/opt/qbittorrent-exporter/src
EnvironmentFile=$CONFIG_PATH
ExecStart=/opt/qbittorrent-exporter/src/qbittorrent-exporter
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now qbittorrent-exporter &>/dev/null
else
cat <<EOF >"$SERVICE_PATH"
#!/sbin/openrc-run
command="$INSTALL_PATH"
command_args=""
command_background=true
directory="/opt/qbittorrent-exporter/src"
pidfile="/opt/qbittorrent-exporter/src/pidfile"
depend() {
need net
}
start_pre() {
if [ -f "$CONFIG_PATH" ]; then
export \$(grep -v '^#' $CONFIG_PATH | xargs)
fi
}
EOF
chmod +x "$SERVICE_PATH"
rc-update add qbittorrent-exporter default &>/dev/null
rc-service qbittorrent-exporter start &>/dev/null
fi
msg_ok "Service created successfully"
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$CURRENT_IP:8090/metrics${CL}"

View File

@ -0,0 +1,6 @@
__ _ __ __ __ __
____ _/ /_ (_) /_/ /_____ _____________ ____ / /_ ___ _ ______ ____ _____/ /____ _____
/ __ `/ __ \/ / __/ __/ __ \/ ___/ ___/ _ \/ __ \/ __/_____/ _ \| |/_/ __ \/ __ \/ ___/ __/ _ \/ ___/
/ /_/ / /_/ / / /_/ /_/ /_/ / / / / / __/ / / / /_/_____/ __/> </ /_/ / /_/ / / / /_/ __/ /
\__, /_.___/_/\__/\__/\____/_/ /_/ \___/_/ /_/\__/ \___/_/|_/ .___/\____/_/ \__/\___/_/
/_/ /_/

View File

@ -103,9 +103,9 @@ function check_root() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-3]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.3 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -137,9 +137,9 @@ function check_root() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -139,7 +139,7 @@ function check_root() {
}
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 (NOT 9.1+)
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 9.1
pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
@ -155,12 +155,12 @@ pve_check() {
return 0
fi
# Check for Proxmox VE 9.x: allow ONLY 9.0
# Check for Proxmox VE 9.x: allow 9.09.1
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR != 0)); then
if ((MINOR < 0 || MINOR > 1)); then
msg_error "This version of Proxmox VE is not yet supported."
msg_error "Supported: Proxmox VE version 9.0"
msg_error "Supported: Proxmox VE version 9.0 9.1"
exit 1
fi
return 0
@ -168,7 +168,7 @@ pve_check() {
# All other unsupported versions
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0"
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0 9.1"
exit 1
}

View File

@ -161,7 +161,7 @@ function check_root() {
}
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 (NOT 9.1+)
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 9.1
pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
@ -178,12 +178,12 @@ pve_check() {
return 0
fi
# Check for Proxmox VE 9.x: allow ONLY 9.0
# Check for Proxmox VE 9.x: allow 9.0 9.1
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR != 0)); then
if ((MINOR < 0 || MINOR > 1)); then
msg_error "This version of Proxmox VE is not yet supported."
msg_error "Supported: Proxmox VE version 9.0"
msg_error "Supported: Proxmox VE version 9.0 9.1"
exit 1
fi
PVE_MAJOR=9
@ -192,7 +192,7 @@ pve_check() {
# All other unsupported versions
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0"
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0 9.1"
exit 1
}

View File

@ -29,7 +29,7 @@ var_os="debian"
var_version="13"
DISK_SIZE="10G"
USE_CLOUD_INIT="no"
INSTALL_PORTAINER="no"
# INSTALL_PORTAINER="no"
OS_TYPE=""
OS_VERSION=""
@ -161,7 +161,7 @@ function check_root() {
}
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 (NOT 9.1+)
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 9.1
pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
@ -178,12 +178,12 @@ pve_check() {
return 0
fi
# Check for Proxmox VE 9.x: allow ONLY 9.0
# Check for Proxmox VE 9.x: allow 9.09.1
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR != 0)); then
if ((MINOR < 0 || MINOR > 1)); then
msg_error "This version of Proxmox VE is not yet supported."
msg_error "Supported: Proxmox VE version 9.0"
msg_error "Supported: Proxmox VE version 9.0 9.1"
exit 1
fi
PVE_MAJOR=9
@ -192,7 +192,7 @@ pve_check() {
# All other unsupported versions
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0"
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0 9.1"
exit 1
}
@ -284,16 +284,16 @@ function select_cloud_init() {
fi
}
function select_portainer() {
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "PORTAINER" \
--yesno "Install Portainer for Docker management?\n\nPortainer is a lightweight management UI for Docker.\n\nAccess after installation:\n• HTTP: http://<VM-IP>:9000\n• HTTPS: https://<VM-IP>:9443" 14 68); then
INSTALL_PORTAINER="yes"
echo -e "${ADVANCED}${BOLD}${DGN}Portainer: ${BGN}yes${CL}"
else
INSTALL_PORTAINER="no"
echo -e "${ADVANCED}${BOLD}${DGN}Portainer: ${BGN}no${CL}"
fi
}
# function select_portainer() {
# if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "PORTAINER" \
# --yesno "Install Portainer for Docker management?\n\nPortainer is a lightweight management UI for Docker.\n\nAccess after installation:\n• HTTP: http://<VM-IP>:9000\n• HTTPS: https://<VM-IP>:9443" 14 68); then
# INSTALL_PORTAINER="yes"
# echo -e "${ADVANCED}${BOLD}${DGN}Portainer: ${BGN}yes${CL}"
# else
# INSTALL_PORTAINER="no"
# echo -e "${ADVANCED}${BOLD}${DGN}Portainer: ${BGN}no${CL}"
# fi
# }
function get_image_url() {
local arch=$(dpkg --print-architecture)
@ -323,7 +323,7 @@ function default_settings() {
select_cloud_init
# Portainer Selection - ALWAYS ask
select_portainer
# select_portainer
# Set defaults for other settings
VMID=$(get_valid_nextid)
@ -367,7 +367,7 @@ function advanced_settings() {
select_cloud_init
# Portainer Selection - ALWAYS ask (at the beginning)
select_portainer
# select_portainer
METHOD="advanced"
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
@ -703,7 +703,7 @@ for i in {1..10}; do
done
# Install Portainer if requested
INSTALL_PORTAINER_PLACEHOLDER
# INSTALL_PORTAINER_PLACEHOLDER
# Create completion flag
echo \"[\\$(date)] Docker installation completed successfully\"
@ -711,20 +711,20 @@ touch /root/.docker-installed
INSTALLEOF" >/dev/null
# Add Portainer installation script if requested
if [ "$INSTALL_PORTAINER" = "yes" ]; then
virt-customize -q -a "${FILE}" --run-command "cat > /root/install-portainer.sh << 'PORTAINEREOF'
#!/bin/bash
exec >> /var/log/install-docker.log 2>&1
echo \"[\\$(date)] Installing Portainer\"
docker volume create portainer_data
docker run -d -p 9000:9000 -p 9443:9443 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
echo \"[\\$(date)] Portainer installed and started\"
PORTAINEREOF" >/dev/null
virt-customize -q -a "${FILE}" --run-command "chmod +x /root/install-portainer.sh" >/dev/null
virt-customize -q -a "${FILE}" --run-command "sed -i 's|INSTALL_PORTAINER_PLACEHOLDER|/root/install-portainer.sh|' /root/install-docker.sh" >/dev/null
else
virt-customize -q -a "${FILE}" --run-command "sed -i 's|INSTALL_PORTAINER_PLACEHOLDER|echo \"[\\\\\\$(date)] Skipping Portainer installation\"|' /root/install-docker.sh" >/dev/null
fi
# if [ "$INSTALL_PORTAINER" = "yes" ]; then
# virt-customize -q -a "${FILE}" --run-command "cat > /root/install-portainer.sh << 'PORTAINEREOF'
# #!/bin/bash
# exec >> /var/log/install-docker.log 2>&1
# echo \"[\\$(date)] Installing Portainer\"
# docker volume create portainer_data
# docker run -d -p 9000:9000 -p 9443:9443 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
# echo \"[\\$(date)] Portainer installed and started\"
# PORTAINEREOF" >/dev/null
# virt-customize -q -a "${FILE}" --run-command "chmod +x /root/install-portainer.sh" >/dev/null
# virt-customize -q -a "${FILE}" --run-command "sed -i 's|INSTALL_PORTAINER_PLACEHOLDER|/root/install-portainer.sh|' /root/install-docker.sh" >/dev/null
# else
# virt-customize -q -a "${FILE}" --run-command "sed -i 's|INSTALL_PORTAINER_PLACEHOLDER|echo \"[\\\\\\$(date)] Skipping Portainer installation\"|' /root/install-docker.sh" >/dev/null
# fi
virt-customize -q -a "${FILE}" --run-command "chmod +x /root/install-docker.sh" >/dev/null
@ -899,15 +899,15 @@ else
echo -e "${TAB}${DGN}Docker: ${BGN}Latest (via get.docker.com)${CL}"
fi
if [ "$INSTALL_PORTAINER" = "yes" ]; then
if [ -n "$VM_IP" ]; then
echo -e "${TAB}${DGN}Portainer: ${BGN}https://${VM_IP}:9443${CL}"
else
echo -e "${TAB}${DGN}Portainer: ${BGN}Will be accessible at https://<VM-IP>:9443${CL}"
echo -e "${TAB}${YW}⚠️ Wait 2-3 minutes after boot for installation to complete${CL}"
echo -e "${TAB}${YW}⚠️ Get IP with: ${BL}qm guest cmd ${VMID} network-get-interfaces${CL}"
fi
fi
# if [ "$INSTALL_PORTAINER" = "yes" ]; then
# if [ -n "$VM_IP" ]; then
# echo -e "${TAB}${DGN}Portainer: ${BGN}https://${VM_IP}:9443${CL}"
# else
# echo -e "${TAB}${DGN}Portainer: ${BGN}Will be accessible at https://<VM-IP>:9443${CL}"
# echo -e "${TAB}${YW}⚠️ Wait 2-3 minutes after boot for installation to complete${CL}"
# echo -e "${TAB}${YW}⚠️ Get IP with: ${BL}qm guest cmd ${VMID} network-get-interfaces${CL}"
# fi
# fi
if [ "$USE_CLOUD_INIT" = "yes" ]; then
display_cloud_init_info "$VMID" "$HN"
fi

View File

@ -118,9 +118,9 @@ function check_root() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -185,9 +185,9 @@ function msg_error() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -181,9 +181,9 @@ function msg_error() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -119,9 +119,9 @@ function check_root() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -135,9 +135,9 @@ function check_root() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -138,9 +138,9 @@ function check_root() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -138,9 +138,9 @@ function check_root() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -130,9 +130,9 @@ function check_root() {
}
function pve_check() {
if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
echo -e "Exiting..."
sleep 2
exit

View File

@ -147,7 +147,7 @@ function check_root() {
}
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 (NOT 9.1+)
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 9.1
pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
@ -163,12 +163,12 @@ pve_check() {
return 0
fi
# Check for Proxmox VE 9.x: allow ONLY 9.0
# Check for Proxmox VE 9.x: allow 9.09.1
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR != 0)); then
if ((MINOR < 0 || MINOR > 1)); then
msg_error "This version of Proxmox VE is not yet supported."
msg_error "Supported: Proxmox VE version 9.0"
msg_error "Supported: Proxmox VE version 9.0 9.1"
exit 1
fi
return 0