Compare commits

..

30 Commits

Author SHA1 Message Date
e5c24229e9 add: note about deb13 requirement temp 2025-12-15 16:40:21 +01:00
126b0c339a Update CHANGELOG.md (#9990)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 14:22:59 +00:00
c2034039e8 fix(tools): prevent awk errors in setup_rust on restricted containers (#9985)
Add error suppression and || true to awk commands that parse rustc version.
Prevents 'Operation not permitted' errors in containers with restricted syscalls.
2025-12-15 15:22:32 +01:00
9374e5d183 Update CHANGELOG.md (#9986)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 13:42:48 +00:00
6311584fef fix(pangolin-install): add network-online dependency (#9984)
Co-authored-by: Andrey Yantsen <worried-networking@users.noreply.github.com>
2025-12-15 14:42:24 +01:00
5bbf0861e9 Update .app files (#9978)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-12-15 13:09:52 +01:00
7cb02a0cc3 Update versions.json (#9981)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 13:07:48 +01:00
010e8d5f27 Update CHANGELOG.md (#9980)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 12:04:07 +00:00
2b322bf182 Update CHANGELOG.md (#9979)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 12:03:53 +00:00
d12215dea8 Update date in json (#9977)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-12-15 12:03:40 +00:00
f258ab7ae5 Koel (#9972)
* Add koel (ct)

* Remove unnecessary newline in koel.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ <47820557+MickLesk@users.noreply.github.com>
2025-12-15 13:03:20 +01:00
33f167f278 Update CHANGELOG.md (#9976)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 12:02:51 +00:00
3568cf52f9 fix(build): App Defaults force mode and prevent unbound variables (#9971)
- load_vars_file() now supports force parameter to override existing variables
- App Defaults uses force=yes to properly apply saved user preferences
- Added safety check for SSH_KEYS_FILE in install_ssh_keys_into_ct()
- Initialize ENABLE_GPU, ENABLE_NESTING, ENABLE_KEYCTL, ENABLE_MKNOD, PROTECT_CT, CT_TIMEZONE in base_settings()
- Added fallback defaults in echo_default() to prevent unbound variable errors when advanced_settings is skipped
2025-12-15 13:02:28 +01:00
5f5144c661 Update CHANGELOG.md (#9970)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 09:10:31 +00:00
09134d94dd Refactor: Heimdall Dashboard (#9959)
* Refactor

* VED>VE
2025-12-15 10:10:04 +01:00
33103ad256 Update project statistics in README
Removed an outdated project statistics image link.
2025-12-15 10:06:07 +01:00
fd75da89c4 Update CHANGELOG.md (#9969)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 08:53:00 +00:00
ee49576f3a README; add project statistics and formatting (#9967) 2025-12-15 09:52:36 +01:00
e651c14f76 fix(build): App Defaults now override script defaults with force mode 2025-12-15 09:46:49 +01:00
1fc5c031cc Update CHANGELOG.md (#9968)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 08:37:22 +00:00
35793051a1 core: load app defaults before applying base_settings / fix composer cleanup after install/update (#9965)
* fix(build): load app defaults before applying base_settings

App defaults were loaded after base_settings, causing saved values to be ignored.
Now loads var_* from app defaults file before calling base_settings.

* fix(cleanup): suppress composer root warning in cleanup_lxc

Composer's clear-cache command prompts for confirmation when run as root,
causing scripts to hang at 'Cleaning up' stage. Set COMPOSER_ALLOW_SUPERUSER=1
to suppress the interactive prompt.

Fixes #9952 (Heimdall Dashboard), also affects BentoPDF and other PHP apps.

* Fix COMPOSER_ALLOW_SUPERUSER export in cleanup_lxc

Exports COMPOSER_ALLOW_SUPERUSER before running composer clear-cache to ensure the environment variable is set correctly during cleanup.
2025-12-15 09:37:01 +01:00
9a6a0379a6 Update CHANGELOG.md (#9961)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 00:16:31 +00:00
4fab369a5b Update versions.json (#9960)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-15 01:16:03 +01:00
f977f6c987 Update CHANGELOG.md (#9958)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-14 22:57:09 +00:00
2524dd1af7 refactor: homarr (#9948) 2025-12-14 23:56:45 +01:00
dfcaa70647 add additional line in PR template 2025-12-14 23:08:57 +01:00
7b911403a3 Update CHANGELOG.md (#9956)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-14 22:06:50 +00:00
1a96ed2221 Update dependencies and remove unused files (#9945)
* chore: remove unused prettier files to avoid confusion

* chore: update copyright year in LICENSE file to reflect current status

* chore: remove vitest configuration file as it is no longer needed

* chore: remove unused dependencies from package.json

* chore: remove pocketbase dependency from package.json

* chore: update dependencies in package.json and bun.lock

* chore: update dependencies in bun.lock to latest versions

* chore: update bun.lock to reflect new dependency versions and configurations

* chore: add @radix-ui/react-scroll-area dependency to package.json and bun.lock

* chore: remove deprecated overrides for React and update date-fns version in package.json and bun.lock
2025-12-14 23:06:28 +01:00
b180694d46 Update CHANGELOG.md (#9953)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-14 19:00:24 +00:00
f807ec748d Update SonarQube database configuration variables (#9946) 2025-12-14 19:59:56 +01:00
19 changed files with 669 additions and 369 deletions

1
.github/pull_request_template.md generated vendored
View File

@ -3,6 +3,7 @@ PRs without prior testing will be closed. -->
## ✍️ Description
## 🔗 Related Issue
Fixes #

View File

@ -10,8 +10,50 @@
> [!CAUTION]
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
## 2025-12-15
### 🆕 New Scripts
- Koel ([#9972](https://github.com/community-scripts/ProxmoxVE/pull/9972))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix(pangolin-install): add network-online dependency [@worried-networking](https://github.com/worried-networking) ([#9984](https://github.com/community-scripts/ProxmoxVE/pull/9984))
- #### 🔧 Refactor
- Refactor: Heimdall Dashboard [@tremor021](https://github.com/tremor021) ([#9959](https://github.com/community-scripts/ProxmoxVE/pull/9959))
### 💾 Core
- #### 🐞 Bug Fixes
- tools: prevent awk errors in setup_rust on restricted containers [@MickLesk](https://github.com/MickLesk) ([#9985](https://github.com/community-scripts/ProxmoxVE/pull/9985))
- core: App Defaults force mode and prevent unbound variables [@MickLesk](https://github.com/MickLesk) ([#9971](https://github.com/community-scripts/ProxmoxVE/pull/9971))
- core: load app defaults before applying base_settings / fix composer cleanup after install/update [@MickLesk](https://github.com/MickLesk) ([#9965](https://github.com/community-scripts/ProxmoxVE/pull/9965))
### 📚 Documentation
- README; add project statistics / formatting [@MickLesk](https://github.com/MickLesk) ([#9967](https://github.com/community-scripts/ProxmoxVE/pull/9967))
## 2025-12-14
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- SonarQube: Fix database variables [@tremor021](https://github.com/tremor021) ([#9946](https://github.com/community-scripts/ProxmoxVE/pull/9946))
- #### 💥 Breaking Changes
- refactor: homarr [@CrazyWolf13](https://github.com/CrazyWolf13) ([#9948](https://github.com/community-scripts/ProxmoxVE/pull/9948))
### 🌐 Website
- Update dependencies and remove unused files [@BramSuurdje](https://github.com/BramSuurdje) ([#9945](https://github.com/community-scripts/ProxmoxVE/pull/9945))
## 2025-12-13
### 🚀 Updated Scripts

View File

@ -30,8 +30,8 @@
<br />
> **Simplify your Proxmox VE setup with community-driven automation scripts**
> Originally created by tteck, now maintained and expanded by the community
**Simplify your Proxmox VE setup with community-driven automation scripts**
Originally created by tteck, now maintained and expanded by the community
</div>
@ -239,17 +239,34 @@ This project is maintained by volunteers in memory of tteck. Your support helps
---
## 📈 Project Growth
## 📈 Project Statistics
<p align="center">
<img
src="https://repobeats.axiom.co/api/embed/57edde03e00f88d739bdb5b844ff7d07dd079375.svg"
alt="Repobeats analytics"
width="650"
/>
</p>
<div align="center">
<p align="center">
<a href="https://star-history.com/#community-scripts/ProxmoxVE&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" />
<source
media="(prefers-color-scheme: dark)"
srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark"
/>
<source
media="(prefers-color-scheme: light)"
srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date"
/>
<img
alt="Star History Chart"
src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date"
width="650"
/>
</picture>
</a>
</div>
</p>
---

6
ct/headers/koel Normal file
View File

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

View File

@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@ -27,45 +27,45 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(curl -fsSL "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]')
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
if check_for_gh_release "Heimdall" "linuxserver/Heimdall"; then
msg_info "Stopping Service"
systemctl stop heimdall
sleep 1
msg_ok "Stopped Service"
msg_info "Backing up Data"
cp -R /opt/Heimdall/database database-backup
cp -R /opt/Heimdall/public public-backup
sleep 1
msg_ok "Backed up Data"
msg_info "Updating Heimdall Dashboard to ${RELEASE}"
curl -fsSL "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" -o $(basename "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz")
tar xzf "${RELEASE}".tar.gz
VER=$(curl -fsSL https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
cp -R Heimdall-"${VER}"/* /opt/Heimdall
setup_composer
fetch_and_deploy_gh_release "Heimdall" "linuxserver/Heimdall" "tarball"
msg_info "Updating Heimdall-Dashboard"
cd /opt/Heimdall
$STD apt-get install -y composer
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer dump-autoload
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated Heimdall Dashboard to ${RELEASE}"
msg_ok "Updated Heimdall-Dashboard"
msg_info "Restoring Data"
cd ~
cp -R database-backup/* /opt/Heimdall/database
cp -R public-backup/* /opt/Heimdall/public
sleep 1
msg_ok "Restored Data"
msg_info "Cleanup"
rm -rf {"${RELEASE}".tar.gz,Heimdall-"${VER}",public-backup,database-backup,Heimdall}
msg_info "Cleaning Up"
rm -rf {public-backup,database-backup}
sleep 1
msg_ok "Cleaned"
msg_ok "Cleaned Up"
msg_info "Starting Service"
systemctl start heimdall.service
sleep 2
msg_ok "Started Service"
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}."
fi
exit
}

View File

@ -1,21 +1,20 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: CrazyWolf13
# Author: MickLesk (CanbiZ) | Co-Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://homarr.dev/
APP="homarr"
var_tags="${var_tags:-arr;dashboard}"
var_cpu="${var_cpu:-3}"
var_ram="${var_ram:-6144}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
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
@ -28,69 +27,43 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
if [[ -f /opt/homarr/database/db.sqlite ]]; then
msg_error "Old Homarr detected due to existing database file (/opt/homarr/database/db.sqlite)."
msg_error "Update not supported. Refer to:"
msg_error " - https://github.com/community-scripts/ProxmoxVE/discussions/1551"
msg_error " - https://homarr.dev/docs/getting-started/after-the-installation/#importing-a-zip-from-version-before-100"
exit
fi
if [[ ! -f /opt/run_homarr.sh ]]; then
msg_info "Detected outdated and missing service files"
msg_error "Warning - The port of homarr changed from 3000 to 7575"
$STD apt-get install -y nginx gettext openssl gpg
sed -i '/^NODE_ENV=/d' /opt/homarr/.env && echo "NODE_ENV='production'" >>/opt/homarr/.env
sed -i '/^DB_DIALECT=/d' /opt/homarr/.env && echo "DB_DIALECT='sqlite'" >>/opt/homarr/.env
cat <<'EOF' >/opt/run_homarr.sh
#!/bin/bash
set -a
source /opt/homarr/.env
set +a
export DB_DIALECT='sqlite'
export AUTH_SECRET=$(openssl rand -base64 32)
export CRON_JOB_API_KEY=$(openssl rand -base64 32)
node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
for dir in $(find /opt/homarr_db/migrations/migrations -mindepth 1 -maxdepth 1 -type d); do
dirname=$(basename "$dir")
mkdir -p "/opt/homarr_db/migrations/$dirname"
cp -r "$dir"/* "/opt/homarr_db/migrations/$dirname/" 2>/dev/null || true
done
export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
nginx -g 'daemon off;' &
redis-server /opt/homarr/packages/redis/redis.conf &
node apps/tasks/tasks.cjs &
node apps/websocket/wssServer.cjs &
node apps/nextjs/server.js & PID=$!
wait $PID
EOF
chmod +x /opt/run_homarr.sh
rm /etc/systemd/system/homarr.service
cat <<EOF >/etc/systemd/system/homarr.service
[Unit]
Description=Homarr Service
After=network.target
[Service]
Type=exec
WorkingDirectory=/opt/homarr
EnvironmentFile=-/opt/homarr/.env
ExecStart=/opt/run_homarr.sh
[Install]
WantedBy=multi-user.target
EOF
msg_ok "Updated Services"
systemctl daemon-reload
fi
if check_for_gh_release "homarr" "homarr-labs/homarr"; then
msg_info "Stopping Services (Patience)"
systemctl stop homarr
systemctl stop redis-server
msg_ok "Services Stopped"
msg_info "Backup Data"
mkdir -p /opt/homarr-data-backup
cp /opt/homarr/.env /opt/homarr-data-backup/.env
msg_ok "Backup Data"
if ! { grep -q '^REDIS_IS_EXTERNAL=' /opt/homarr/.env 2>/dev/null || grep -q '^REDIS_IS_EXTERNAL=' /opt/homarr.env 2>/dev/null; }; then
DEBIAN_VERSION=$(cat /etc/debian_version 2>/dev/null | cut -d'.' -f1)
if [[ -n "$DEBIAN_VERSION" ]] && [[ "$DEBIAN_VERSION" -lt 13 ]]; then
msg_warn "⚠️ COMPATIBILITY WARNING ⚠️"
msg_warn "You are running Debian ${DEBIAN_VERSION}. Homarr's requires Debian 13"
msg_warn ""
msg_warn "Please Upgrade to Debian 13:"
msg_warn "See: https://github.com/community-scripts/ProxmoxVE/discussions/7489"
msg_warn ""
exit
fi
msg_info "Fixing old structure"
# fix musl issues because homarr compiles on alpine not debian soure: https://github.com/alexander-akhmetov/python-telegram/issues/3
$STD apt install -y musl-dev
ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1
cp /opt/homarr/.env /opt/homarr.env
echo "REDIS_IS_EXTERNAL='true'" >> /opt/homarr.env
sed -i 's|^ExecStart=.*|ExecStart=/opt/homarr/run.sh|' /etc/systemd/system/homarr.service
sed -i 's|^EnvironmentFile=.*|EnvironmentFile=-/opt/homarr.env|' /etc/systemd/system/homarr.service
chown -R redis:redis /appdata/redis
chmod 744 /appdata/redis
mkdir -p /etc/systemd/system/redis-server.service.d/
cat <<EOF >/etc/systemd/system/redis-server.service.d/override.conf
[Service]
ReadWritePaths=-/appdata/redis -/var/lib/redis -/var/log/redis -/var/run/redis -/etc/redis
EOF
systemctl daemon-reload
rm /opt/run_homarr.sh
msg_ok "Fixed old structure"
fi
msg_info "Updating Nodejs"
$STD apt update
@ -98,69 +71,21 @@ EOF
msg_ok "Updated Nodejs"
NODE_VERSION=$(curl -s https://raw.githubusercontent.com/homarr-labs/homarr/dev/package.json | jq -r '.engines.node | split(">=")[1] | split(".")[0]')
NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/homarr-labs/homarr/dev/package.json | jq -r '.packageManager | split("@")[1]')"
setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "homarr" "homarr-labs/homarr" "prebuild" "latest" "/opt/homarr" "build-amd64.tar.gz"
rm -rf /opt/homarr
fetch_and_deploy_gh_release "homarr" "homarr-labs/homarr"
msg_info "Updating and rebuilding ${APP} (Patience)"
rm /opt/run_homarr.sh
cat <<'EOF' >/opt/run_homarr.sh
#!/bin/bash
set -a
source /opt/homarr/.env
set +a
export DB_DIALECT='sqlite'
export AUTH_SECRET=$(openssl rand -base64 32)
export CRON_JOB_API_KEY=$(openssl rand -base64 32)
node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
for dir in $(find /opt/homarr_db/migrations/migrations -mindepth 1 -maxdepth 1 -type d); do
dirname=$(basename "$dir")
mkdir -p "/opt/homarr_db/migrations/$dirname"
cp -r "$dir"/* "/opt/homarr_db/migrations/$dirname/" 2>/dev/null || true
done
export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
nginx -g 'daemon off;' &
redis-server /opt/homarr/packages/redis/redis.conf &
node apps/tasks/tasks.cjs &
node apps/websocket/wssServer.cjs &
node apps/nextjs/server.js & PID=$!
wait $PID
EOF
chmod +x /opt/run_homarr.sh
mv /opt/homarr-data-backup/.env /opt/homarr/.env
cd /opt/homarr
$STD pnpm install --recursive --frozen-lockfile --shamefully-hoist
$STD pnpm build
cp /opt/homarr/apps/nextjs/next.config.ts .
cp /opt/homarr/apps/nextjs/package.json .
cp -r /opt/homarr/packages/db/migrations /opt/homarr_db/migrations
cp -r /opt/homarr/apps/nextjs/.next/standalone/* /opt/homarr
mkdir -p /appdata/redis
cp /opt/homarr/packages/redis/redis.conf /opt/homarr/redis.conf
msg_info "Updating Homarr"
cp /opt/homarr/redis.conf /etc/redis/redis.conf
rm /etc/nginx/nginx.conf
mkdir -p /etc/nginx/templates
cp /opt/homarr/nginx.conf /etc/nginx/templates/nginx.conf
mkdir -p /opt/homarr/apps/cli
cp /opt/homarr/packages/cli/cli.cjs /opt/homarr/apps/cli/cli.cjs
echo $'#!/bin/bash\ncd /opt/homarr/apps/cli && node ./cli.cjs "$@"' >/usr/bin/homarr
chmod +x /usr/bin/homarr
mkdir /opt/homarr/build
cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
msg_ok "Updated ${APP}"
msg_ok "Updated Homarr"
msg_info "Starting Services"
chmod +x /opt/homarr/run.sh
systemctl start homarr
systemctl start redis-server
msg_ok "Started Services"
msg_ok "Updated successfully!"
read -p "${TAB3}It's recommended to reboot the LXC after an update, would you like to reboot the LXC now ? (y/n): " choice
if [[ "$choice" =~ ^[Yy]$ ]]; then
reboot
fi
fi
exit
}

81
ct/koel.sh Normal file
View File

@ -0,0 +1,81 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/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://koel.dev/
APP="Koel"
var_tags="${var_tags:-music;streaming}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/koel ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "koel" "koel/koel"; then
msg_info "Stopping Services"
systemctl stop nginx php8.4-fpm
msg_ok "Stopped Services"
msg_info "Creating Backup"
mkdir -p /tmp/koel_backup
cp /opt/koel/.env /tmp/koel_backup/
cp -r /opt/koel/storage /tmp/koel_backup/ 2>/dev/null || true
cp -r /opt/koel/public/img /tmp/koel_backup/ 2>/dev/null || true
msg_ok "Created Backup"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "koel" "koel/koel" "prebuild" "latest" "/opt/koel" "koel-*.tar.gz"
msg_info "Restoring Data"
cp /tmp/koel_backup/.env /opt/koel/
cp -r /tmp/koel_backup/storage/* /opt/koel/storage/ 2>/dev/null || true
cp -r /tmp/koel_backup/img/* /opt/koel/public/img/ 2>/dev/null || true
rm -rf /tmp/koel_backup
msg_ok "Restored Data"
msg_info "Running Migrations"
cd /opt/koel
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-interaction --no-dev --optimize-autoloader
$STD php artisan migrate --force
$STD php artisan config:clear
$STD php artisan cache:clear
$STD php artisan view:clear
$STD php artisan koel:init --no-assets --no-interaction
chown -R www-data:www-data /opt/koel
chmod -R 775 /opt/koel/storage
msg_ok "Ran Migrations"
msg_info "Starting Services"
systemctl start php8.4-fpm nginx
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}${CL}"

View File

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

View File

@ -19,8 +19,8 @@
"type": "default",
"script": "ct/homarr.sh",
"resources": {
"cpu": 3,
"ram": 6144,
"cpu": 2,
"ram": 1024,
"hdd": 8,
"os": "debian",
"version": "13"

View File

@ -0,0 +1,48 @@
{
"name": "Koel",
"slug": "koel",
"categories": [
13
],
"date_created": "2025-12-15",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://docs.koel.dev/",
"config_path": "/opt/koel/.env",
"website": "https://koel.dev/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/koel-light.webp",
"description": "Koel is a simple web-based personal audio streaming service written in Vue and Laravel. It supports multiple users, audio visualization, smart playlists, YouTube integration, and Last.fm scrobbling.",
"install_methods": [
{
"type": "default",
"script": "ct/koel.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "admin@koel.dev",
"password": "KoelIsCool"
},
"notes": [
{
"text": "Media files should be placed in /opt/koel_media",
"type": "info"
},
{
"text": "Database credentials are stored in ~/koel.creds",
"type": "info"
},
{
"text": "Music library is scanned hourly via cron job",
"type": "info"
}
]
}

View File

@ -1,4 +1,139 @@
[
{
"name": "cockpit-project/cockpit",
"version": "353.1",
"date": "2025-12-15T10:29:34Z"
},
{
"name": "VictoriaMetrics/VictoriaMetrics",
"version": "pmm-6401-v1.132.0",
"date": "2025-12-15T09:38:46Z"
},
{
"name": "Prowlarr/Prowlarr",
"version": "v2.3.0.5236",
"date": "2025-11-16T22:41:22Z"
},
{
"name": "Lidarr/Lidarr",
"version": "v3.1.0.4875",
"date": "2025-11-16T22:40:18Z"
},
{
"name": "Radarr/Radarr",
"version": "v6.0.4.10291",
"date": "2025-11-16T22:39:01Z"
},
{
"name": "mattermost/mattermost",
"version": "v10.11.8",
"date": "2025-11-21T17:06:07Z"
},
{
"name": "firefly-iii/firefly-iii",
"version": "v6.4.11",
"date": "2025-12-15T08:01:35Z"
},
{
"name": "morpheus65535/bazarr",
"version": "v1.5.3",
"date": "2025-09-20T12:12:33Z"
},
{
"name": "Jackett/Jackett",
"version": "v0.24.454",
"date": "2025-12-15T05:54:27Z"
},
{
"name": "scanopy/scanopy",
"version": "v0.12.0",
"date": "2025-12-15T04:12:10Z"
},
{
"name": "jellyfin/jellyfin",
"version": "v10.11.5",
"date": "2025-12-15T02:44:19Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.1.0",
"date": "2025-11-23T12:13:34Z"
},
{
"name": "jeedom/core",
"version": "4.5",
"date": "2025-12-15T00:27:03Z"
},
{
"name": "esphome/esphome",
"version": "2025.11.5",
"date": "2025-12-09T17:54:33Z"
},
{
"name": "9001/copyparty",
"version": "v1.19.22",
"date": "2025-12-14T23:38:57Z"
},
{
"name": "BerriAI/litellm",
"version": "v1.80.10.rc.2",
"date": "2025-12-14T22:47:12Z"
},
{
"name": "nickheyer/discopanel",
"version": "v1.0.15",
"date": "2025-12-14T21:49:36Z"
},
{
"name": "AlexxIT/go2rtc",
"version": "v1.9.13",
"date": "2025-12-14T20:18:28Z"
},
{
"name": "alexta69/metube",
"version": "2025.12.14",
"date": "2025-12-14T18:24:33Z"
},
{
"name": "openhab/openhab-core",
"version": "5.1.0.M4",
"date": "2025-12-14T18:12:04Z"
},
{
"name": "rcourtman/Pulse",
"version": "v4.36.2",
"date": "2025-12-03T22:46:29Z"
},
{
"name": "semaphoreui/semaphore",
"version": "v2.17.0-beta24",
"date": "2025-12-14T14:04:23Z"
},
{
"name": "blakeblackshear/frigate",
"version": "v0.14.1",
"date": "2024-08-29T22:32:51Z"
},
{
"name": "docmost/docmost",
"version": "v0.24.1",
"date": "2025-12-14T13:49:16Z"
},
{
"name": "laurent22/joplin",
"version": "server-v3.5.1",
"date": "2025-12-03T11:56:50Z"
},
{
"name": "chrisbenincasa/tunarr",
"version": "v1.0.3",
"date": "2025-12-14T13:32:31Z"
},
{
"name": "C4illin/ConvertX",
"version": "v0.16.1",
"date": "2025-12-14T13:21:05Z"
},
{
"name": "globaleaks/globaleaks-whistleblowing-software",
"version": "v5.0.87",
@ -9,21 +144,6 @@
"version": "2.223.0",
"date": "2025-12-14T08:16:54Z"
},
{
"name": "netvisor-io/netvisor",
"version": "v0.12.0",
"date": "2025-12-14T06:08:25Z"
},
{
"name": "morpheus65535/bazarr",
"version": "v1.5.3",
"date": "2025-09-20T12:12:33Z"
},
{
"name": "Jackett/Jackett",
"version": "v0.24.448",
"date": "2025-12-14T05:55:44Z"
},
{
"name": "release-argus/Argus",
"version": "0.28.1",
@ -34,26 +154,6 @@
"version": "1.3.12",
"date": "2025-12-14T02:58:24Z"
},
{
"name": "BerriAI/litellm",
"version": "v1.80.10.rc.1",
"date": "2025-12-14T02:32:50Z"
},
{
"name": "nickheyer/discopanel",
"version": "v1.0.14",
"date": "2025-12-14T00:51:39Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.1.0",
"date": "2025-11-23T12:13:34Z"
},
{
"name": "jeedom/core",
"version": "4.5",
"date": "2025-12-14T00:27:06Z"
},
{
"name": "martabal/qbittorrent-exporter",
"version": "v1.13.2",
@ -104,11 +204,6 @@
"version": "cli/v0.29.1",
"date": "2025-12-13T13:55:51Z"
},
{
"name": "chrisbenincasa/tunarr",
"version": "v1.0.2",
"date": "2025-12-13T13:34:22Z"
},
{
"name": "fuma-nama/fumadocs",
"version": "fumadocs-openapi@10.1.4",
@ -129,11 +224,6 @@
"version": "v0.26.2",
"date": "2025-12-13T07:48:09Z"
},
{
"name": "firefly-iii/firefly-iii",
"version": "v6.4.9",
"date": "2025-11-28T20:36:20Z"
},
{
"name": "mealie-recipes/mealie",
"version": "v3.7.0",
@ -179,21 +269,11 @@
"version": "2025.12.3",
"date": "2025-12-12T18:12:39Z"
},
{
"name": "docmost/docmost",
"version": "v0.24.0",
"date": "2025-12-12T18:05:49Z"
},
{
"name": "booklore-app/booklore",
"version": "v1.14.1",
"date": "2025-12-12T17:37:58Z"
},
{
"name": "esphome/esphome",
"version": "2025.11.5",
"date": "2025-12-09T17:54:33Z"
},
{
"name": "keycloak/keycloak",
"version": "26.4.7",
@ -219,11 +299,6 @@
"version": "n8n@1.123.5-exp.0",
"date": "2025-12-10T16:35:50Z"
},
{
"name": "mattermost/mattermost",
"version": "v10.11.8",
"date": "2025-11-21T17:06:07Z"
},
{
"name": "zitadel/zitadel",
"version": "v4.7.5",
@ -279,6 +354,11 @@
"version": "0.43.1",
"date": "2025-12-11T22:45:52Z"
},
{
"name": "meilisearch/meilisearch",
"version": "prototype-v1.30.0-network-topology.3",
"date": "2025-12-11T21:57:10Z"
},
{
"name": "coollabsio/coolify",
"version": "v4.0.0-beta.454",
@ -289,11 +369,6 @@
"version": "v1.30.22",
"date": "2025-12-11T18:02:06Z"
},
{
"name": "meilisearch/meilisearch",
"version": "prototype-v1.30.0-network-topology.2",
"date": "2025-12-11T16:47:51Z"
},
{
"name": "endurain-project/endurain",
"version": "v0.16.2",
@ -364,11 +439,6 @@
"version": "0.211.1",
"date": "2025-12-10T12:25:19Z"
},
{
"name": "cockpit-project/cockpit",
"version": "353",
"date": "2025-12-10T10:55:50Z"
},
{
"name": "kyantech/Palmr",
"version": "v3.3.2-beta",
@ -454,11 +524,6 @@
"version": "v1.4.7",
"date": "2025-12-09T11:44:49Z"
},
{
"name": "alexta69/metube",
"version": "2025.12.09",
"date": "2025-12-09T00:16:11Z"
},
{
"name": "Dispatcharr/Dispatcharr",
"version": "v0.14.0",
@ -529,11 +594,6 @@
"version": "2.7.1",
"date": "2025-12-06T20:30:34Z"
},
{
"name": "blakeblackshear/frigate",
"version": "v0.14.1",
"date": "2024-08-29T22:32:51Z"
},
{
"name": "navidrome/navidrome",
"version": "v0.59.0",
@ -544,11 +604,6 @@
"version": "v5.19.2",
"date": "2025-12-06T14:56:53Z"
},
{
"name": "openhab/openhab-core",
"version": "4.3.9",
"date": "2025-12-06T14:31:36Z"
},
{
"name": "prometheus/blackbox_exporter",
"version": "v0.28.0",
@ -639,11 +694,6 @@
"version": "11.0.4",
"date": "2025-12-04T09:26:37Z"
},
{
"name": "rcourtman/Pulse",
"version": "v4.36.2",
"date": "2025-12-03T22:46:29Z"
},
{
"name": "danielbrendel/hortusfox-web",
"version": "v5.5",
@ -659,11 +709,6 @@
"version": "6.2.10",
"date": "2025-12-03T13:58:32Z"
},
{
"name": "laurent22/joplin",
"version": "server-v3.5.1",
"date": "2025-12-03T11:56:50Z"
},
{
"name": "SigNoz/signoz",
"version": "v0.104.0",
@ -689,11 +734,6 @@
"version": "v0.6.41",
"date": "2025-12-02T22:28:58Z"
},
{
"name": "9001/copyparty",
"version": "v1.19.21",
"date": "2025-12-02T21:48:12Z"
},
{
"name": "WordPress/WordPress",
"version": "6.9",
@ -734,11 +774,6 @@
"version": "3000.7.0",
"date": "2025-12-01T23:29:47Z"
},
{
"name": "C4illin/ConvertX",
"version": "v0.16.0",
"date": "2025-12-01T21:35:19Z"
},
{
"name": "slskd/slskd",
"version": "0.24.1",
@ -749,11 +784,6 @@
"version": "v3.6.0",
"date": "2025-12-01T18:48:10Z"
},
{
"name": "VictoriaMetrics/VictoriaMetrics",
"version": "pmm-6401-v1.131.0",
"date": "2025-12-01T17:18:24Z"
},
{
"name": "OctoPrint/OctoPrint",
"version": "1.11.5",
@ -764,11 +794,6 @@
"version": "251130-b3068414c",
"date": "2025-12-01T05:07:31Z"
},
{
"name": "jellyfin/jellyfin",
"version": "v10.11.4",
"date": "2025-12-01T02:33:37Z"
},
{
"name": "recyclarr/recyclarr",
"version": "v7.5.2",
@ -904,11 +929,6 @@
"version": "2.3.0",
"date": "2025-11-24T09:48:32Z"
},
{
"name": "semaphoreui/semaphore",
"version": "v2.17.0-beta22",
"date": "2025-11-24T06:07:49Z"
},
{
"name": "webmin/webmin",
"version": "2.610",
@ -1064,31 +1084,11 @@
"version": "v4.2.1",
"date": "2025-11-17T02:47:15Z"
},
{
"name": "Prowlarr/Prowlarr",
"version": "v2.3.0.5236",
"date": "2025-11-16T22:41:22Z"
},
{
"name": "Lidarr/Lidarr",
"version": "v3.1.0.4875",
"date": "2025-11-16T22:40:18Z"
},
{
"name": "Radarr/Radarr",
"version": "v6.0.4.10291",
"date": "2025-11-16T22:39:01Z"
},
{
"name": "binwiederhier/ntfy",
"version": "v2.15.0",
"date": "2025-11-16T18:53:49Z"
},
{
"name": "AlexxIT/go2rtc",
"version": "v1.9.12",
"date": "2025-11-16T16:14:55Z"
},
{
"name": "outline/outline",
"version": "v1.1.0",

View File

@ -14,27 +14,22 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y apt-transport-https
$STD apt-get install -y composer
$STD apt-get install -y php8.2-{bz2,curl,sqlite3,zip,xml}
$STD apt install -y apt-transport-https
msg_ok "Installed Dependencies"
RELEASE=$(curl -fsSL "https://api.github.com/repos/linuxserver/Heimdall/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]')
echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt
msg_info "Installing Heimdall Dashboard ${RELEASE}"
curl -fsSL "https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz" -o "${RELEASE}".tar.gz
tar xzf "${RELEASE}".tar.gz
VER=$(curl -fsSL https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
rm -rf "${RELEASE}".tar.gz
mv Heimdall-"${VER}" /opt/Heimdall
PHP_VERSION="8.4" PHP_MODULE="bz2,sqlite3" PHP_FPM="YES" setup_php
setup_composer
fetch_and_deploy_gh_release "Heimdall" "linuxserver/Heimdall" "tarball"
msg_info "Setting up Heimdall-Dashboard"
cd /opt/Heimdall
cp .env.example .env
$STD php artisan key:generate
msg_ok "Installed Heimdall Dashboard ${RELEASE}"
msg_ok "Setup Heimdall-Dashboard"
msg_info "Creating Service"
service_path="/etc/systemd/system/heimdall.service"
echo "[Unit]
cat <<EOF >/etc/systemd/system/heimdall.service
[Unit]
Description=Heimdall
After=network.target
@ -44,14 +39,16 @@ RestartSec=5
Type=simple
User=root
WorkingDirectory=/opt/Heimdall
ExecStart="/usr/bin/php" artisan serve --port 7990 --host 0.0.0.0
ExecStart=/usr/bin/php artisan serve --port 7990 --host 0.0.0.0
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target" >$service_path
WantedBy=multi-user.target"
EOF
systemctl enable -q --now heimdall
cd /opt/Heimdall
COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer dump-autoload
systemctl restart heimdall.service
msg_ok "Created Service"

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (Canbiz)
# Author: MickLesk (CanbiZ) | Co-Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/homarr-labs/homarr
@ -16,28 +16,24 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
redis-server \
ca-certificates \
make \
g++ \
build-essential \
nginx \
gettext \
jq \
openssl
openssl \
musl-dev
msg_ok "Installed Dependencies"
NODE_VERSION=$(curl -s https://raw.githubusercontent.com/homarr-labs/homarr/dev/package.json | jq -r '.engines.node | split(">=")[1] | split(".")[0]')
NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/homarr-labs/homarr/dev/package.json | jq -r '.packageManager | split("@")[1]')"
setup_nodejs
fetch_and_deploy_gh_release "homarr" "homarr-labs/homarr"
fetch_and_deploy_gh_release "homarr" "homarr-labs/homarr" "prebuild" "latest" "/opt/homarr" "build-amd64.tar.gz"
msg_info "Installing Homarr (Patience)"
cd /opt
msg_info "Installing Homarr"
# fix musl issues because homarr compiles on alpine not debian soure: https://github.com/alexander-akhmetov/python-telegram/issues/3
ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1
mkdir -p /opt/homarr_db
touch /opt/homarr_db/db.sqlite
SECRET_ENCRYPTION_KEY="$(openssl rand -hex 32)"
cd /opt/homarr
cat <<EOF >/opt/homarr/.env
cat <<EOF >/opt/homarr.env
DB_DRIVER='better-sqlite3'
DB_DIALECT='sqlite'
SECRET_ENCRYPTION_KEY='${SECRET_ENCRYPTION_KEY}'
@ -45,54 +41,28 @@ DB_URL='/opt/homarr_db/db.sqlite'
TURBO_TELEMETRY_DISABLED=1
AUTH_PROVIDERS='credentials'
NODE_ENV='production'
REDIS_IS_EXTERNAL='true'
EOF
$STD pnpm install --recursive --frozen-lockfile --shamefully-hoist
$STD pnpm build
msg_ok "Installed Homarr"
msg_info "Copying build and config files"
cp /opt/homarr/apps/nextjs/next.config.ts .
cp /opt/homarr/apps/nextjs/package.json .
cp -r /opt/homarr/packages/db/migrations /opt/homarr_db/migrations
cp -r /opt/homarr/apps/nextjs/.next/standalone/* /opt/homarr
msg_info "Copying config files"
mkdir -p /appdata/redis
cp /opt/homarr/packages/redis/redis.conf /opt/homarr/redis.conf
mkdir -p /etc/nginx/templates
chown -R redis:redis /appdata/redis
chmod 744 /appdata/redis
cp /opt/homarr/redis.conf /etc/redis/redis.conf
rm /etc/nginx/nginx.conf
mkdir -p /etc/nginx/templates
cp /opt/homarr/nginx.conf /etc/nginx/templates/nginx.conf
mkdir -p /opt/homarr/apps/cli
cp /opt/homarr/packages/cli/cli.cjs /opt/homarr/apps/cli/cli.cjs
echo $'#!/bin/bash\ncd /opt/homarr/apps/cli && node ./cli.cjs "$@"' >/usr/bin/homarr
chmod +x /usr/bin/homarr
mkdir /opt/homarr/build
cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
msg_ok "Finished copying"
msg_ok "Copied config files"
msg_info "Creating Services"
cat <<'EOF' >/opt/run_homarr.sh
#!/bin/bash
set -a
source /opt/homarr/.env
set +a
export DB_DIALECT='sqlite'
export AUTH_SECRET=$(openssl rand -base64 32)
export CRON_JOB_API_KEY=$(openssl rand -base64 32)
node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
for dir in $(find /opt/homarr_db/migrations/migrations -mindepth 1 -maxdepth 1 -type d); do
dirname=$(basename "$dir")
mkdir -p "/opt/homarr_db/migrations/$dirname"
cp -r "$dir"/* "/opt/homarr_db/migrations/$dirname/" 2>/dev/null || true
done
export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
nginx -g 'daemon off;' &
redis-server /opt/homarr/packages/redis/redis.conf &
node apps/tasks/tasks.cjs &
node apps/websocket/wssServer.cjs &
node apps/nextjs/server.js & PID=$!
wait $PID
mkdir -p /etc/systemd/system/redis-server.service.d/
cat <<EOF >/etc/systemd/system/redis-server.service.d/override.conf
[Service]
ReadWritePaths=-/appdata/redis -/var/lib/redis -/var/log/redis -/var/run/redis -/etc/redis
EOF
chmod +x /opt/run_homarr.sh
cat <<EOF >/etc/systemd/system/homarr.service
[Unit]
Description=Homarr Service
@ -101,14 +71,17 @@ After=network.target
[Service]
Type=exec
WorkingDirectory=/opt/homarr
EnvironmentFile=-/opt/homarr/.env
ExecStart=/opt/run_homarr.sh
EnvironmentFile=-/opt/homarr.env
ExecStart=/opt/homarr/run.sh
[Install]
WantedBy=multi-user.target
EOF
chmod +x /opt/homarr/run.sh
systemctl daemon-reload
systemctl enable -q --now redis-server && sleep 5
systemctl enable -q --now homarr
msg_ok "Created Service"
msg_ok "Created Services"
motd_ssh
customize

189
install/koel-install.sh Normal file
View File

@ -0,0 +1,189 @@
#!/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://koel.dev/
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 \
nginx \
ffmpeg \
cron \
locales
msg_ok "Installed Dependencies"
import_local_ip
PG_VERSION="16" setup_postgresql
PG_DB_NAME="koel" PG_DB_USER="koel" setup_postgresql_db
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bz2,exif,imagick,pgsql,sqlite3" setup_php
NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs
setup_composer
fetch_and_deploy_gh_release "koel" "koel/koel" "prebuild" "latest" "/opt/koel" "koel-*.tar.gz"
msg_info "Configuring Koel"
mkdir -p /opt/koel_media /opt/koel_sync
cd /opt/koel
cat <<EOF >/opt/koel/.env
APP_NAME=Koel
APP_ENV=production
APP_DEBUG=false
APP_URL=http://${LOCAL_IP}
APP_KEY=
TRUSTED_HOSTS=
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=${PG_DB_NAME}
DB_USERNAME=${PG_DB_USER}
DB_PASSWORD=${PG_DB_PASS}
STORAGE_DRIVER=local
MEDIA_PATH=/opt/koel_media
ARTIFACTS_PATH=
IGNORE_DOT_FILES=true
APP_MAX_SCAN_TIME=600
MEMORY_LIMIT=
STREAMING_METHOD=php
SCOUT_DRIVER=tntsearch
USE_MUSICBRAINZ=true
MUSICBRAINZ_USER_AGENT=
LASTFM_API_KEY=
LASTFM_API_SECRET=
SPOTIFY_CLIENT_ID=
SPOTIFY_CLIENT_SECRET=
YOUTUBE_API_KEY=
CDN_URL=
TRANSCODE_FLAC=false
FFMPEG_PATH=/usr/bin/ffmpeg
TRANSCODE_BIT_RATE=128
ALLOW_DOWNLOAD=true
BACKUP_ON_DELETE=true
MEDIA_BROWSER_ENABLED=false
PROXY_AUTH_ENABLED=false
SYNC_LOG_LEVEL=error
FORCE_HTTPS=
MAIL_FROM_ADDRESS="noreply@localhost"
MAIL_FROM_NAME="Koel"
MAIL_MAILER=log
MAIL_HOST=null
MAIL_PORT=null
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
BROADCAST_CONNECTION=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
EOF
mkdir -p /opt/koel/storage/{app/public,framework/{cache/data,sessions,views},logs}
chown -R www-data:www-data /opt/koel /opt/koel_media /opt/koel_sync
chmod -R 775 /opt/koel/storage /opt/koel/bootstrap/cache
msg_ok "Configured Koel"
msg_info "Installing Koel (Patience)"
export COMPOSER_ALLOW_SUPERUSER=1
cd /opt/koel
$STD composer install --no-interaction --no-dev --optimize-autoloader
$STD php artisan key:generate --force
$STD php artisan config:clear
$STD php artisan cache:clear
$STD php artisan koel:init --no-assets --no-interaction
chown -R www-data:www-data /opt/koel
msg_ok "Installed Koel"
msg_info "Tuning PHP-FPM"
PHP_FPM_CONF="/etc/php/8.4/fpm/pool.d/www.conf"
sed -i 's/^pm.max_children = .*/pm.max_children = 15/' "$PHP_FPM_CONF"
sed -i 's/^pm.start_servers = .*/pm.start_servers = 4/' "$PHP_FPM_CONF"
sed -i 's/^pm.min_spare_servers = .*/pm.min_spare_servers = 2/' "$PHP_FPM_CONF"
sed -i 's/^pm.max_spare_servers = .*/pm.max_spare_servers = 8/' "$PHP_FPM_CONF"
$STD systemctl restart php8.4-fpm
msg_ok "Tuned PHP-FPM"
msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/koel
server {
listen 80;
server_name _;
root /opt/koel/public;
index index.php;
client_max_body_size 50M;
charset utf-8;
gzip on;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json;
gzip_comp_level 9;
send_timeout 3600;
location / {
try_files $uri $uri/ /index.php?$args;
}
location /media/ {
internal;
alias $upstream_http_x_media_root;
}
location ~ \.php$ {
try_files $uri $uri/ /index.php?$args;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_intercept_errors on;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
EOF
rm -f /etc/nginx/sites-enabled/default
ln -sf /etc/nginx/sites-available/koel /etc/nginx/sites-enabled/koel
$STD systemctl reload nginx
msg_ok "Configured Nginx"
msg_info "Setting up Cron Job"
cat <<'EOF' >/etc/cron.d/koel
0 * * * * www-data cd /opt/koel && /usr/bin/php artisan koel:scan >/dev/null 2>&1
EOF
chmod 644 /etc/cron.d/koel
msg_ok "Set up Cron Job"
motd_ssh
customize
cleanup_lxc

View File

@ -230,6 +230,8 @@ systemctl enable -q --now gerbil
cat <<'EOF' >/etc/systemd/system/traefik.service
[Unit]
Description=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience
Wants=network-online.target
After=network-online.target
[Service]
Type=notify

View File

@ -27,9 +27,9 @@ chown -R sonarqube:sonarqube /opt/sonarqube
chmod -R 755 /opt/sonarqube
mkdir -p /opt/sonarqube/conf
cat <<EOF >/opt/sonarqube/conf/sonar.properties
sonar.jdbc.username=${DB_USER}
sonar.jdbc.password=${DB_PASS}
sonar.jdbc.url=jdbc:postgresql://localhost/${DB_NAME}
sonar.jdbc.username=${PG_DB_USER}
sonar.jdbc.password=${PG_DB_PASS}
sonar.jdbc.url=jdbc:postgresql://localhost/${PG_DB_NAME}
sonar.web.host=0.0.0.0
sonar.web.port=9000
EOF

View File

@ -205,7 +205,10 @@ update_motd_ip() {
# - Falls back to warning if no keys provided
# ------------------------------------------------------------------------------
install_ssh_keys_into_ct() {
[[ "$SSH" != "yes" ]] && return 0
[[ "${SSH:-no}" != "yes" ]] && return 0
# Ensure SSH_KEYS_FILE is defined (may not be set if advanced_settings was skipped)
: "${SSH_KEYS_FILE:=}"
if [[ -n "$SSH_KEYS_FILE" && -s "$SSH_KEYS_FILE" ]]; then
msg_info "Installing selected SSH keys into CT ${CTID}"
@ -430,6 +433,14 @@ base_settings() {
ENABLE_FUSE=${var_fuse:-"${1:-no}"}
ENABLE_TUN=${var_tun:-"${1:-no}"}
# Additional settings that may be skipped if advanced_settings is not run (e.g., App Defaults)
ENABLE_GPU=${var_gpu:-"no"}
ENABLE_NESTING=${var_nesting:-"1"}
ENABLE_KEYCTL=${var_keyctl:-"0"}
ENABLE_MKNOD=${var_mknod:-"0"}
PROTECT_CT=${var_protection:-"no"}
CT_TIMEZONE=${var_timezone:-"$timezone"}
# 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
var_os="debian"
@ -445,9 +456,11 @@ base_settings() {
# - Safe parser for KEY=VALUE lines from vars files
# - Used by default_var_settings and app defaults loading
# - Only loads whitelisted var_* keys
# - Optional force parameter to override existing values (for app defaults)
# ------------------------------------------------------------------------------
load_vars_file() {
local file="$1"
local force="${2:-no}" # If "yes", override existing variables
[ -f "$file" ] || return 0
msg_info "Loading defaults from ${file}"
@ -485,8 +498,12 @@ load_vars_file() {
var_val="${BASH_REMATCH[1]}"
fi
# Set only if not already exported
[[ -z "${!var_key+x}" ]] && export "${var_key}=${var_val}"
# Set variable: force mode overrides existing, otherwise only set if empty
if [[ "$force" == "yes" ]]; then
export "${var_key}=${var_val}"
else
[[ -z "${!var_key+x}" ]] && export "${var_key}=${var_val}"
fi
fi
done <"$file"
msg_ok "Loaded ${file}"
@ -1892,13 +1909,13 @@ Advanced:
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
echo -e "${NETWORK}${BOLD}${DGN}IPv4: ${BGN}$NET${CL}"
echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}$IPV6_METHOD${CL}"
echo -e "${FUSE}${BOLD}${DGN}FUSE Support: ${BGN}$ENABLE_FUSE${CL}"
[[ "$ENABLE_TUN" == "yes" ]] && echo -e "${NETWORK}${BOLD}${DGN}TUN/TAP Support: ${BGN}$ENABLE_TUN${CL}"
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Nesting: ${BGN}$([ "$ENABLE_NESTING" == "1" ] && echo "Enabled" || echo "Disabled")${CL}"
[[ "$ENABLE_KEYCTL" == "1" ]] && echo -e "${CONTAINERTYPE}${BOLD}${DGN}Keyctl: ${BGN}Enabled${CL}"
echo -e "${GPU}${BOLD}${DGN}GPU Passthrough: ${BGN}$ENABLE_GPU${CL}"
[[ "$PROTECT_CT" == "yes" || "$PROTECT_CT" == "1" ]] && echo -e "${CONTAINERTYPE}${BOLD}${DGN}Protection: ${BGN}Enabled${CL}"
[[ -n "$CT_TIMEZONE" ]] && echo -e "${INFO}${BOLD}${DGN}Timezone: ${BGN}$CT_TIMEZONE${CL}"
echo -e "${FUSE}${BOLD}${DGN}FUSE Support: ${BGN}${ENABLE_FUSE:-no}${CL}"
[[ "${ENABLE_TUN:-no}" == "yes" ]] && echo -e "${NETWORK}${BOLD}${DGN}TUN/TAP Support: ${BGN}$ENABLE_TUN${CL}"
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Nesting: ${BGN}$([ "${ENABLE_NESTING:-1}" == "1" ] && echo "Enabled" || echo "Disabled")${CL}"
[[ "${ENABLE_KEYCTL:-0}" == "1" ]] && echo -e "${CONTAINERTYPE}${BOLD}${DGN}Keyctl: ${BGN}Enabled${CL}"
echo -e "${GPU}${BOLD}${DGN}GPU Passthrough: ${BGN}${ENABLE_GPU:-no}${CL}"
[[ "${PROTECT_CT:-no}" == "yes" || "${PROTECT_CT:-no}" == "1" ]] && echo -e "${CONTAINERTYPE}${BOLD}${DGN}Protection: ${BGN}Enabled${CL}"
[[ -n "${CT_TIMEZONE:-}" ]] && echo -e "${INFO}${BOLD}${DGN}Timezone: ${BGN}$CT_TIMEZONE${CL}"
[[ "$APT_CACHER" == "yes" ]] && echo -e "${INFO}${BOLD}${DGN}APT Cacher: ${BGN}$APT_CACHER_IP${CL}"
echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}"
echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}"
@ -2148,8 +2165,8 @@ install_script() {
header_info
echo -e "${DEFAULT}${BOLD}${BL}Using App Defaults for ${APP} on node $PVEHOST_NAME${CL}"
METHOD="appdefaults"
load_vars_file "$(get_app_defaults_path)" "yes" # Force override script defaults
base_settings
load_vars_file "$(get_app_defaults_path)"
echo_default
defaults_target="$(get_app_defaults_path)"
break

View File

@ -828,7 +828,7 @@ cleanup_lxc() {
# Ruby gem
if command -v gem &>/dev/null; then $STD gem cleanup || true; fi
# Composer (PHP)
if command -v composer &>/dev/null; then $STD composer clear-cache || true; fi
if command -v composer &>/dev/null; then COMPOSER_ALLOW_SUPERUSER=1 && $STD composer clear-cache || true; fi
if command -v journalctl &>/dev/null; then
$STD journalctl --vacuum-time=10m || true

View File

@ -4424,7 +4424,7 @@ function setup_rust() {
# Get currently installed version
local CURRENT_VERSION=""
if command -v rustc &>/dev/null; then
CURRENT_VERSION=$(rustc --version 2>/dev/null | awk '{print $2}')
CURRENT_VERSION=$(rustc --version 2>/dev/null | awk '{print $2}' 2>/dev/null) || true
fi
# Scenario 1: Rustup not installed - fresh install
@ -4443,7 +4443,8 @@ function setup_rust() {
return 1
fi
local RUST_VERSION=$(rustc --version 2>/dev/null | awk '{print $2}')
local RUST_VERSION
RUST_VERSION=$(rustc --version 2>/dev/null | awk '{print $2}' 2>/dev/null) || true
if [[ -z "$RUST_VERSION" ]]; then
msg_error "Failed to determine Rust version"
return 1
@ -4474,7 +4475,8 @@ function setup_rust() {
# Ensure PATH is updated for current shell session
export PATH="$CARGO_BIN:$PATH"
local RUST_VERSION=$(rustc --version 2>/dev/null | awk '{print $2}')
local RUST_VERSION
RUST_VERSION=$(rustc --version 2>/dev/null | awk '{print $2}' 2>/dev/null) || true
if [[ -z "$RUST_VERSION" ]]; then
msg_error "Failed to determine Rust version after update"
return 1