Compare commits

...

16 Commits

Author SHA1 Message Date
community-scripts-pr-app[bot]
9aa0390553 Update CHANGELOG.md (#13245)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 21:22:47 +00:00
CanbiZ (MickLesk)
c8606e9fcc core: harden shell scripts against injection and insecure permissions (#13239) 2026-03-23 22:22:23 +01:00
community-scripts-pr-app[bot]
283e762b83 Update CHANGELOG.md (#13243)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 20:54:05 +00:00
MickLesk
15b5542ad6 fix(nginxproxymanager): reset PWD before certbot update to avoid deleted cwd
After building OpenResty, the script does cd /opt/openresty followed by
rm -rf /opt/openresty, leaving $PWD pointing to a deleted directory.
When pip runs in the certbot block, the subprocess inherits the invalid
PWD and fails with OSError: No such file or directory.

Add cd /root before the certbot block to reset to a valid directory.

Closes #13240
2026-03-23 21:53:35 +01:00
community-scripts-pr-app[bot]
b1604ceae0 Update CHANGELOG.md (#13238)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 19:44:25 +00:00
community-scripts-pr-app[bot]
89c205d57c Update CHANGELOG.md (#13237)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 19:44:06 +00:00
CanbiZ (MickLesk)
5c795395ca Refactor: nginxproxymanager update and OpenResty flow (#13216) 2026-03-23 20:44:04 +01:00
community-scripts-pr-app[bot]
1512711435 Update CHANGELOG.md (#13236)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 19:43:58 +00:00
CanbiZ (MickLesk)
a2616ee258 Improve network connectivity and DNS checks (#13222) 2026-03-23 20:43:48 +01:00
community-scripts-pr-app[bot]
4ce6271ec0 Update CHANGELOG.md (#13235)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 19:43:43 +00:00
community-scripts-pr-app[bot]
da932e62d0 Update CHANGELOG.md (#13234)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 19:43:35 +00:00
CanbiZ (MickLesk)
c2838b69ce Refactor: PartDB (#13229) 2026-03-23 20:43:17 +01:00
community-scripts-pr-app[bot]
676397add0 Update CHANGELOG.md (#13233)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 19:43:12 +00:00
CanbiZ (MickLesk)
ec7f2a2e33 Tracearr: modify service restart and modify build ressources (#13230) 2026-03-23 20:42:46 +01:00
community-scripts-pr-app[bot]
e2027a43b4 Update CHANGELOG.md (#13232)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 19:42:26 +00:00
CanbiZ (MickLesk)
f29606ae87 fix(build): allow /31 and /32 CIDR with out-of-subnet gateway (#13231) 2026-03-23 20:41:55 +01:00
13 changed files with 186 additions and 167 deletions

View File

@@ -428,17 +428,11 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
## 2026-03-23
### 🆕 New Scripts
- Alpine-Borgbackup-Server ([#13219](https://github.com/community-scripts/ProxmoxVE/pull/13219))
### 🚀 Updated Scripts
- NginxProxyManager: build OpenResty from source via GitHub releases [@MickLesk](https://github.com/MickLesk) ([#13134](https://github.com/community-scripts/ProxmoxVE/pull/13134))
- #### 🔧 Refactor
- #### ✨ New Features
- Kometa: optimize config.yml sed patterns, add Quickstart integration [@MickLesk](https://github.com/MickLesk) ([#13198](https://github.com/community-scripts/ProxmoxVE/pull/13198))
- core: harden shell scripts against injection and insecure permissions [@MickLesk](https://github.com/MickLesk) ([#13239](https://github.com/community-scripts/ProxmoxVE/pull/13239))
## 2026-03-22

View File

@@ -49,41 +49,25 @@ function update_script() {
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
RELEASE=$(get_latest_github_release "NginxProxyManager/nginx-proxy-manager")
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "v${RELEASE}" "/opt/nginxproxymanager"
msg_info "Stopping Services"
systemctl stop openresty
systemctl stop npm
msg_ok "Stopped Services"
msg_info "Cleaning old files"
$STD rm -rf /app \
/var/www/html \
/etc/nginx \
/var/log/nginx \
/var/lib/nginx \
/var/cache/nginx
msg_ok "Cleaned old files"
msg_info "Migrating to OpenResty from source"
rm -f /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg /etc/apt/trusted.gpg.d/openresty.gpg
rm -f /etc/apt/sources.list.d/openresty.list /etc/apt/sources.list.d/openresty.sources
if dpkg -l openresty &>/dev/null; then
if dpkg -s openresty &>/dev/null 2>&1; then
msg_info "Migrating from packaged OpenResty to source"
rm -f /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg /etc/apt/trusted.gpg.d/openresty.gpg
rm -f /etc/apt/sources.list.d/openresty.list /etc/apt/sources.list.d/openresty.sources
$STD apt remove -y openresty
$STD apt autoremove -y
rm -f ~/.openresty
msg_ok "Migrated from packaged OpenResty to source"
fi
local pcre_pkg="libpcre3-dev"
if grep -qE 'VERSION_ID="1[3-9]"' /etc/os-release 2>/dev/null; then
pcre_pkg="libpcre2-dev"
fi
$STD apt install -y build-essential "$pcre_pkg" libssl-dev zlib1g-dev
msg_ok "Migrated to OpenResty from source"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "openresty" "openresty/openresty" "prebuild" "latest" "/opt/openresty" "openresty-*.tar.gz"
if check_for_gh_release "openresty" "openresty/openresty"; then
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "openresty" "openresty/openresty" "prebuild" "${CHECK_UPDATE_RELEASE}" "/opt/openresty" "openresty-*.tar.gz"
if [[ -d /opt/openresty ]]; then
msg_info "Building OpenResty"
cd /opt/openresty
$STD ./configure \
@@ -114,75 +98,101 @@ ExecStart=/usr/local/openresty/nginx/sbin/nginx -g 'daemon off;'
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl restart openresty
msg_ok "Built OpenResty"
fi
msg_info "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i "0,/\"version\": \"[^\"]*\"/s|\"version\": \"[^\"]*\"|\"version\": \"$RELEASE\"|" /opt/nginxproxymanager/backend/package.json
sed -i "0,/\"version\": \"[^\"]*\"/s|\"version\": \"[^\"]*\"|\"version\": \"$RELEASE\"|" /opt/nginxproxymanager/frontend/package.json
sed -i 's+^daemon+#daemon+g' /opt/nginxproxymanager/docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find /opt/nginxproxymanager -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cp -r /opt/nginxproxymanager/docker/rootfs/var/www/html/* /var/www/html/
cp -r /opt/nginxproxymanager/docker/rootfs/etc/nginx/* /etc/nginx/
cp /opt/nginxproxymanager/docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp /opt/nginxproxymanager/docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
$STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
cd /root
if [ -d /opt/certbot ]; then
msg_info "Updating Certbot"
$STD /opt/certbot/bin/pip install --upgrade pip setuptools wheel
$STD /opt/certbot/bin/pip install --upgrade certbot certbot-dns-cloudflare
msg_ok "Updated Certbot"
fi
mkdir -p /app/frontend/images
cp -r /opt/nginxproxymanager/backend/* /app
msg_ok "Set up Environment"
if check_for_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager"; then
msg_info "Stopping Services"
systemctl stop openresty
systemctl stop npm
msg_ok "Stopped Services"
msg_info "Building Frontend"
export NODE_OPTIONS="--max_old_space_size=2048 --openssl-legacy-provider"
cd /opt/nginxproxymanager/frontend
# Replace node-sass with sass in package.json before installation
sed -E -i 's/"node-sass" *: *"([^"]*)"/"sass": "\1"/g' package.json
$STD yarn install --network-timeout 600000
$STD yarn locale-compile
$STD yarn build
cp -r /opt/nginxproxymanager/frontend/dist/* /app/frontend
cp -r /opt/nginxproxymanager/frontend/public/images/* /app/frontend/images
msg_ok "Built Frontend"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "${CHECK_UPDATE_RELEASE}" "/opt/nginxproxymanager"
msg_info "Initializing Backend"
rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
msg_info "Cleaning old files"
$STD rm -rf /app \
/var/www/html \
/etc/nginx \
/var/log/nginx \
/var/lib/nginx \
/var/cache/nginx
msg_ok "Cleaned old files"
local RELEASE="${CHECK_UPDATE_RELEASE#v}"
msg_info "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i "0,/\"version\": \"[^\"]*\"/s|\"version\": \"[^\"]*\"|\"version\": \"$RELEASE\"|" /opt/nginxproxymanager/backend/package.json
sed -i "0,/\"version\": \"[^\"]*\"/s|\"version\": \"[^\"]*\"|\"version\": \"$RELEASE\"|" /opt/nginxproxymanager/frontend/package.json
sed -i 's+^daemon+#daemon+g' /opt/nginxproxymanager/docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find /opt/nginxproxymanager -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cp -r /opt/nginxproxymanager/docker/rootfs/var/www/html/* /var/www/html/
cp -r /opt/nginxproxymanager/docker/rootfs/etc/nginx/* /etc/nginx/
cp /opt/nginxproxymanager/docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp /opt/nginxproxymanager/docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
$STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
fi
mkdir -p /app/frontend/images
cp -r /opt/nginxproxymanager/backend/* /app
msg_ok "Set up Environment"
msg_info "Building Frontend"
export NODE_OPTIONS="--max_old_space_size=2048 --openssl-legacy-provider"
cd /opt/nginxproxymanager/frontend
sed -E -i 's/"node-sass" *: *"([^"]*)"/"sass": "\1"/g' package.json
$STD yarn install --network-timeout 600000
$STD yarn locale-compile
$STD yarn build
cp -r /opt/nginxproxymanager/frontend/dist/* /app/frontend
cp -r /opt/nginxproxymanager/frontend/public/images/* /app/frontend/images
msg_ok "Built Frontend"
msg_info "Initializing Backend"
rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{
"database": {
"engine": "knex-native",
@@ -196,28 +206,21 @@ EOF
}
}
EOF
fi
sed -i 's/"client": "sqlite3"/"client": "better-sqlite3"/' /app/config/production.json
cd /app
$STD yarn install --network-timeout 600000
msg_ok "Initialized Backend"
msg_info "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
systemctl daemon-reload
systemctl enable -q --now openresty
systemctl enable -q --now npm
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
sed -i 's/"client": "sqlite3"/"client": "better-sqlite3"/' /app/config/production.json
cd /app
$STD yarn install --network-timeout 600000
msg_ok "Initialized Backend"
msg_info "Updating Certbot"
if [ -d /opt/certbot ]; then
$STD /opt/certbot/bin/pip install --upgrade pip setuptools wheel
$STD /opt/certbot/bin/pip install --upgrade certbot certbot-dns-cloudflare
fi
msg_ok "Updated Certbot"
msg_info "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
systemctl daemon-reload
systemctl enable -q --now openresty
systemctl enable -q --now npm
msg_ok "Started Services"
msg_ok "Updated successfully!"
exit
}

View File

@@ -27,36 +27,27 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(get_latest_github_release "Part-DB/Part-DB-server")
if check_for_gh_release "partdb" "Part-DB/Part-DB-server"; then
msg_info "Stopping Service"
systemctl stop apache2
msg_ok "Stopped Service"
msg_info "Updating $APP to v${RELEASE}"
cd /opt
mv /opt/partdb/ /opt/partdb-backup
curl -fsSL "https://github.com/Part-DB/Part-DB-server/archive/refs/tags/v${RELEASE}.zip" -o "/opt/v${RELEASE}.zip"
$STD unzip "v${RELEASE}.zip"
mv /opt/Part-DB-server-${RELEASE}/ /opt/partdb
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "partdb" "Part-DB/Part-DB-server" "prebuild" "latest" "/opt/partdb" "partdb_with_assets.zip"
msg_info "Updating Part-DB"
cd /opt/partdb/
cp -r "/opt/partdb-backup/.env.local" /opt/partdb/
cp -r "/opt/partdb-backup/public/media" /opt/partdb/public/
cp -r "/opt/partdb-backup/config/banner.md" /opt/partdb/config/
cp -r /opt/partdb-backup/.env.local /opt/partdb/
cp -r /opt/partdb-backup/public/media /opt/partdb/public/
cp -r /opt/partdb-backup/config/banner.md /opt/partdb/config/
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-dev -o --no-interaction
$STD yarn install
$STD yarn build
$STD php bin/console cache:clear
$STD php bin/console doctrine:migrations:migrate -n
chown -R www-data:www-data /opt/partdb
rm -r "/opt/v${RELEASE}.zip"
rm -r /opt/partdb-backup
echo "${RELEASE}" >~/.partdb
msg_ok "Updated $APP to v${RELEASE}"
msg_ok "Updated Part-DB"
msg_info "Starting Service"
systemctl start apache2

View File

@@ -8,7 +8,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
APP="Tracearr"
var_tags="${var_tags:-media}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_ram="${var_ram:-8192}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
@@ -102,7 +102,7 @@ EOF
if check_for_gh_release "tracearr" "connorgallopo/Tracearr"; then
msg_info "Stopping Services"
systemctl stop tracearr postgresql redis
systemctl stop tracearr postgresql redis-server
msg_ok "Stopped Services"
msg_info "Updating pnpm"
@@ -115,6 +115,7 @@ EOF
msg_info "Building Tracearr"
export TZ=$(cat /etc/timezone)
export NODE_OPTIONS="--max-old-space-size=4096"
cd /opt/tracearr.build
$STD pnpm install --frozen-lockfile --force
$STD pnpm turbo telemetry disable
@@ -148,7 +149,7 @@ EOF
msg_ok "Configured Tracearr"
msg_info "Starting services"
systemctl start postgresql redis tracearr
systemctl start postgresql redis-server tracearr
msg_ok "Started services"
msg_ok "Updated successfully!"
else

View File

@@ -13,27 +13,19 @@ setting_up_container
network_check
update_os
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
PG_VERSION="16" setup_postgresql
PG_DB_NAME="partdb" PG_DB_USER="partdb" setup_postgresql_db
PHP_VERSION="8.4" PHP_APACHE="YES" PHP_MODULE="xsl" PHP_POST_MAX_SIZE="100M" PHP_UPLOAD_MAX_FILESIZE="100M" setup_php
setup_composer
msg_info "Installing Part-DB (Patience)"
cd /opt
RELEASE=$(get_latest_github_release "Part-DB/Part-DB-server")
curl -fsSL "https://github.com/Part-DB/Part-DB-server/archive/refs/tags/v${RELEASE}.zip" -o "/opt/v${RELEASE}.zip"
$STD unzip "v${RELEASE}.zip"
mv /opt/Part-DB-server-${RELEASE}/ /opt/partdb
fetch_and_deploy_gh_release "partdb" "Part-DB/Part-DB-server" "prebuild" "latest" "/opt/partdb" "partdb_with_assets.zip"
msg_info "Installing Part-DB"
cd /opt/partdb/
cp .env .env.local
sed -i "s|DATABASE_URL=\"sqlite:///%kernel.project_dir%/var/app.db\"|DATABASE_URL=\"postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}?serverVersion=12.19&charset=utf8\"|" .env.local
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-dev -o --no-interaction
$STD yarn install
$STD yarn build
$STD php bin/console cache:clear
php bin/console doctrine:migrations:migrate -n >~/database-migration-output
chown -R www-data:www-data /opt/partdb
@@ -44,8 +36,6 @@ ADMIN_PASS=$(grep -oP 'The initial password for the "admin" user is: \K\w+' ~/da
echo "Part-DB Admin Password: $ADMIN_PASS"
} >>~/partdb.creds
rm -rf ~/database-migration-output
rm -rf "/opt/v${RELEASE}.zip"
echo "${RELEASE}" >~/.partdb
msg_ok "Installed Part-DB"
msg_info "Creating Service"

View File

@@ -35,7 +35,7 @@ cd Shinobi
gitVersionNumber=$(git rev-parse HEAD)
theDateRightNow=$(date)
touch version.json
chmod 777 version.json
chmod 644 version.json
echo '{"Product" : "'"Shinobi"'" , "Branch" : "'"master"'" , "Version" : "'"$gitVersionNumber"'" , "Date" : "'"$theDateRightNow"'" , "Repository" : "'"https://gitlab.com/Shinobi-Systems/Shinobi.git"'"}' >version.json
msg_ok "Cloned Shinobi"

View File

@@ -23,7 +23,7 @@ fetch_and_deploy_gh_release "tasmoadmin" "TasmoAdmin/TasmoAdmin" "prebuild" "lat
msg_info "Configuring TasmoAdmin"
rm -rf /etc/php/8.4/apache2/conf.d/10-opcache.ini
chown -R www-data:www-data /var/www/tasmoadmin
chmod 777 /var/www/tasmoadmin/tmp /var/www/tasmoadmin/data
chmod 775 /var/www/tasmoadmin/tmp /var/www/tasmoadmin/data
cat <<EOF >/etc/apache2/sites-available/tasmoadmin.conf
<VirtualHost *:9999>
ServerName tasmoadmin

View File

@@ -62,6 +62,7 @@ fetch_and_deploy_gh_release "tracearr" "connorgallopo/Tracearr" "tarball" "lates
msg_info "Building Tracearr"
export TZ=$(cat /etc/timezone)
export NODE_OPTIONS="--max-old-space-size=4096"
cd /opt/tracearr.build
$STD pnpm install --frozen-lockfile --force
$STD pnpm turbo telemetry disable

View File

@@ -90,11 +90,18 @@ setting_up_container() {
network_check() {
set +e
trap - ERR
ipv4_connected=false
# Check IPv4 connectivity to Cloudflare, Google & 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
ipv4_status="${GN}${CL} IPv4"
msg_ok "IPv4 Internet Connected"
ipv4_connected=true
else
ipv4_status="${RD}${CL} IPv4"
read -r -p "Internet NOT connected. Continue anyway? <y/N> " prompt
msg_error "IPv4 Internet Not Connected"
fi
if [[ $ipv4_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
@@ -102,12 +109,28 @@ network_check() {
exit 122
fi
fi
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
if [[ -z "$RESOLVEDIP" ]]; then
msg_error "Internet: ${ipv4_status} DNS Failed"
# DNS resolution checks for GitHub-related domains
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 "Internet: ${ipv4_status} DNS: ${BL}${RESOLVEDIP}${CL}"
msg_ok "$GIT_STATUS"
fi
set -e
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}

View File

@@ -221,6 +221,11 @@ update_motd_ip() {
local current_hostname="$(hostname)"
local current_ip="$(hostname -I | awk '{print $1}')"
# Escape sed special chars in replacement strings (& \ |)
current_os="${current_os//\\/\\\\}"; current_os="${current_os//&/\\&}"
current_hostname="${current_hostname//\\/\\\\}"; current_hostname="${current_hostname//&/\\&}"
current_ip="${current_ip//\\/\\\\}"; current_ip="${current_ip//&/\\&}"
# Update only if values actually changed
if ! grep -q "OS:.*$current_os" "$PROFILE_FILE" 2>/dev/null; then
sed -i "s|OS:.*|OS: \${GN}$current_os\${CL}\\\"|" "$PROFILE_FILE"
@@ -529,6 +534,10 @@ validate_gateway_in_subnet() {
local ip="${static_ip%%/*}"
local cidr="${static_ip##*/}"
# /31 and /32 are valid point-to-point / zero-trust DMZ configurations
# where the gateway is technically outside the subnet — skip validation
((cidr >= 31)) && return 0
# Convert CIDR to netmask bits
local mask=$((0xFFFFFFFF << (32 - cidr) & 0xFFFFFFFF))
@@ -4072,8 +4081,8 @@ EOF
if [ "$var_os" == "alpine" ]; then
sleep 3
pct exec "$CTID" -- /bin/sh -c 'cat <<EOF >/etc/apk/repositories
http://dl-cdn.alpinelinux.org/alpine/latest-stable/main
http://dl-cdn.alpinelinux.org/alpine/latest-stable/community
https://dl-cdn.alpinelinux.org/alpine/latest-stable/main
https://dl-cdn.alpinelinux.org/alpine/latest-stable/community
EOF'
pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses jq" >>"$BUILD_LOG" 2>&1 || {
msg_error "Failed to install base packages in Alpine container"
@@ -4082,7 +4091,9 @@ EOF'
else
sleep 3
LANG=${LANG:-en_US.UTF-8}
pct exec "$CTID" -- bash -c "sed -i \"/$LANG/ s/^# //\" /etc/locale.gen"
local LANG_ESC="${LANG//./\\.}"
LANG_ESC="${LANG_ESC//|/\\|}"
pct exec "$CTID" -- bash -c "sed -i \"/$LANG_ESC/ s/^# //\" /etc/locale.gen"
pct exec "$CTID" -- bash -c "locale_line=\$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print \$1}' | head -n 1) && \
echo LANG=\$locale_line >/etc/default/locale && \
locale-gen >/dev/null && \
@@ -4755,6 +4766,10 @@ fix_gpu_gids() {
pct stop "$CTID" >/dev/null 2>&1
sleep 1
# Validate GIDs are numeric before sed
[[ "$render_gid" =~ ^[0-9]+$ ]] || render_gid="104"
[[ "$video_gid" =~ ^[0-9]+$ ]] || video_gid="44"
# Update dev entries with correct GIDs
sed -i.bak -E "s|(dev[0-9]+: /dev/dri/renderD[0-9]+),gid=[0-9]+|\1,gid=${render_gid}|g" "$LXC_CONFIG"
sed -i -E "s|(dev[0-9]+: /dev/dri/card[0-9]+),gid=[0-9]+|\1,gid=${video_gid}|g" "$LXC_CONFIG"

View File

@@ -309,14 +309,14 @@ 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
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//')
systemctl restart "$(basename "$(dirname "$GETTY_OVERRIDE")" | sed 's/\.d//')"
msg_ok "Customized Container"
fi
echo "bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${app}.sh)\"" >/usr/bin/update

View File

@@ -242,7 +242,7 @@ download_gpg_key() {
# Process based on mode
if [[ "$mode" == "dearmor" ]]; then
if gpg --dearmor --yes -o "$output" <"$temp_key" 2>/dev/null; then
if gpg --dearmor --yes -o "$output" <"$temp_key" 2>/dev/null && [[ -s "$output" ]]; then
rm -f "$temp_key"
debug_log "GPG key installed (dearmored): $output"
return 0
@@ -5192,7 +5192,7 @@ _setup_gpu_permissions() {
for nvidia_dev in /dev/nvidia*; do
[[ -e "$nvidia_dev" ]] && {
chgrp video "$nvidia_dev" 2>/dev/null || true
chmod 666 "$nvidia_dev" 2>/dev/null || true
chmod 660 "$nvidia_dev" 2>/dev/null || true
}
done
if [[ -d /dev/nvidia-caps ]]; then
@@ -5200,7 +5200,7 @@ _setup_gpu_permissions() {
for caps_dev in /dev/nvidia-caps/*; do
[[ -e "$caps_dev" ]] && {
chgrp video "$caps_dev" 2>/dev/null || true
chmod 666 "$caps_dev" 2>/dev/null || true
chmod 660 "$caps_dev" 2>/dev/null || true
}
done
fi
@@ -5217,7 +5217,8 @@ _setup_gpu_permissions() {
# /dev/kfd permissions (AMD ROCm)
if [[ -e /dev/kfd ]]; then
chmod 666 /dev/kfd 2>/dev/null || true
chgrp render /dev/kfd 2>/dev/null || true
chmod 660 /dev/kfd 2>/dev/null || true
msg_info "AMD ROCm compute device configured"
fi

View File

@@ -150,7 +150,7 @@ function install() {
curl -fsSL "https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh" -o "install.sh"
chmod +x install.sh
$STD ./install.sh
chmod 666 /opt/runtipi/state/settings.json 2>/dev/null || true
chmod 660 /opt/runtipi/state/settings.json 2>/dev/null || true
rm -f /opt/install.sh
msg_ok "Installed ${APP}"