mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-03-02 17:05:55 +01:00
Compare commits
51 Commits
add-script
...
automated/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe20476c07 | ||
|
|
5c246310f4 | ||
|
|
bdad2cc941 | ||
|
|
f23c33fee7 | ||
|
|
5b207cf5bd | ||
|
|
f20c9e4ec9 | ||
|
|
1398ff8397 | ||
|
|
ebc3512f50 | ||
|
|
564a8136a5 | ||
|
|
00047c95b8 | ||
|
|
9849ce79a7 | ||
|
|
cea9858193 | ||
|
|
ee8ea672ef | ||
|
|
fc59910bd2 | ||
|
|
20ab7bc005 | ||
|
|
17de8e761b | ||
|
|
ab1e1cc66e | ||
|
|
256143af42 | ||
|
|
5dc244a8c1 | ||
|
|
9f15ca6242 | ||
|
|
750b904abc | ||
|
|
96b5411d1d | ||
|
|
a3404102ce | ||
|
|
374c4492d9 | ||
|
|
3cfe86512d | ||
|
|
47e3e415b9 | ||
|
|
3373533725 | ||
|
|
62c7c329d7 | ||
|
|
da04899558 | ||
|
|
e49f09b5ec | ||
|
|
53efcdc9df | ||
|
|
d9e53d5a16 | ||
|
|
8699013eef | ||
|
|
e3af8ad287 | ||
|
|
f2970522a9 | ||
|
|
e1a45c4831 | ||
|
|
d258ff476f | ||
|
|
a0ea2263a6 | ||
|
|
d29e4cf4a2 | ||
|
|
6095defed4 | ||
|
|
edd88d33d5 | ||
|
|
fd67210906 | ||
|
|
393e9bd868 | ||
|
|
339863366c | ||
|
|
d8db023931 | ||
|
|
71ccc82853 | ||
|
|
4d837d82d8 | ||
|
|
59792ad8b9 | ||
|
|
020796d411 | ||
|
|
cc7461d959 | ||
|
|
0fc12576c0 |
155
.github/workflows/push-json-to-pocketbase.yml
generated
vendored
Normal file
155
.github/workflows/push-json-to-pocketbase.yml
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
name: Push JSON changes to PocketBase
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "frontend/public/json/**"
|
||||
|
||||
jobs:
|
||||
push-json:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get changed JSON files with slug
|
||||
id: changed
|
||||
run: |
|
||||
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- frontend/public/json/ | grep '\.json$' || true)
|
||||
with_slug=""
|
||||
for f in $changed; do
|
||||
[[ -f "$f" ]] || continue
|
||||
jq -e '.slug' "$f" >/dev/null 2>&1 && with_slug="$with_slug $f"
|
||||
done
|
||||
with_slug=$(echo $with_slug | xargs -n1)
|
||||
if [[ -z "$with_slug" ]]; then
|
||||
echo "No app JSON files changed (or no files with slug)."
|
||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
echo "$with_slug" > changed_app_jsons.txt
|
||||
echo "count=$(echo "$with_slug" | wc -w)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Push to PocketBase
|
||||
if: steps.changed.outputs.count != '0'
|
||||
env:
|
||||
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
|
||||
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
|
||||
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
|
||||
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
|
||||
run: |
|
||||
node << 'ENDSCRIPT'
|
||||
(async function() {
|
||||
const fs = require('fs');
|
||||
const https = require('https');
|
||||
const http = require('http');
|
||||
const url = require('url');
|
||||
function request(fullUrl, opts) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
const u = url.parse(fullUrl);
|
||||
const isHttps = u.protocol === 'https:';
|
||||
const body = opts.body;
|
||||
const options = {
|
||||
hostname: u.hostname,
|
||||
port: u.port || (isHttps ? 443 : 80),
|
||||
path: u.path,
|
||||
method: opts.method || 'GET',
|
||||
headers: opts.headers || {}
|
||||
};
|
||||
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
|
||||
const lib = isHttps ? https : http;
|
||||
const req = lib.request(options, function(res) {
|
||||
let data = '';
|
||||
res.on('data', function(chunk) { data += chunk; });
|
||||
res.on('end', function() {
|
||||
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
|
||||
});
|
||||
});
|
||||
req.on('error', reject);
|
||||
if (body) req.write(body);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
|
||||
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
|
||||
const coll = process.env.POCKETBASE_COLLECTION;
|
||||
const files = fs.readFileSync('changed_app_jsons.txt', 'utf8').trim().split(/\s+/).filter(Boolean);
|
||||
const authBody = JSON.stringify({
|
||||
identity: process.env.POCKETBASE_ADMIN_EMAIL,
|
||||
password: process.env.POCKETBASE_ADMIN_PASSWORD
|
||||
});
|
||||
let authRes = await request(apiBase + '/admins/auth-with-password', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: authBody
|
||||
});
|
||||
if (!authRes.ok && authRes.statusCode === 404) {
|
||||
authRes = await request(raw + '/admins/auth-with-password', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: authBody
|
||||
});
|
||||
}
|
||||
if (!authRes.ok) throw new Error('Auth failed (check POCKETBASE_URL): ' + authRes.body);
|
||||
const token = JSON.parse(authRes.body).token;
|
||||
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
||||
for (const file of files) {
|
||||
if (!fs.existsSync(file)) continue;
|
||||
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
if (!data.slug) { console.log('Skipping', file, '(no slug)'); continue; }
|
||||
var payload = {
|
||||
name: data.name,
|
||||
slug: data.slug,
|
||||
script_created: data.date_created || data.script_created,
|
||||
script_updated: data.date_created || data.script_updated,
|
||||
updateable: data.updateable,
|
||||
privileged: data.privileged,
|
||||
port: data.interface_port != null ? data.interface_port : data.port,
|
||||
documentation: data.documentation,
|
||||
website: data.website,
|
||||
logo: data.logo,
|
||||
description: data.description,
|
||||
config_path: data.config_path,
|
||||
default_user: (data.default_credentials && data.default_credentials.username) || data.default_user,
|
||||
default_passwd: (data.default_credentials && data.default_credentials.password) || data.default_passwd,
|
||||
categories: data.categories,
|
||||
install_methods: data.install_methods,
|
||||
notes: data.notes,
|
||||
type: data.type,
|
||||
is_dev: false
|
||||
};
|
||||
if (data.version !== undefined) payload.version = data.version;
|
||||
if (data.changelog !== undefined) payload.changelog = data.changelog;
|
||||
if (data.screenshots !== undefined) payload.screenshots = data.screenshots;
|
||||
const filter = "(slug='" + data.slug + "')";
|
||||
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
|
||||
headers: { 'Authorization': token }
|
||||
});
|
||||
const list = JSON.parse(listRes.body);
|
||||
const existingId = list.items && list.items[0] && list.items[0].id;
|
||||
if (existingId) {
|
||||
console.log('Updating', file, '(slug=' + data.slug + ')');
|
||||
const r = await request(recordsUrl + '/' + existingId, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
if (!r.ok) throw new Error('PATCH failed: ' + r.body);
|
||||
} else {
|
||||
console.log('Creating', file, '(slug=' + data.slug + ')');
|
||||
const r = await request(recordsUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
if (!r.ok) throw new Error('POST failed: ' + r.body);
|
||||
}
|
||||
}
|
||||
console.log('Done.');
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
ENDSCRIPT
|
||||
shell: bash
|
||||
45
CHANGELOG.md
45
CHANGELOG.md
@@ -410,8 +410,53 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-03-02
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Profilarr ([#12441](https://github.com/community-scripts/ProxmoxVE/pull/12441))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Tracearr: prepare for imminent v1.4.19 release [@durzo](https://github.com/durzo) ([#12413](https://github.com/community-scripts/ProxmoxVE/pull/12413))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Frigate: Bump to v0.17 [@MickLesk](https://github.com/MickLesk) ([#12474](https://github.com/community-scripts/ProxmoxVE/pull/12474))
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
|
||||
- Migrate: DokPloy, Komodo, Coolify, Dockge, Runtipi to Addons [@MickLesk](https://github.com/MickLesk) ([#12275](https://github.com/community-scripts/ProxmoxVE/pull/12275))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- ref: replace generic exit 1 with specific exit codes in ct & install [@MickLesk](https://github.com/MickLesk) ([#12475](https://github.com/community-scripts/ProxmoxVE/pull/12475))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- tools.func: Improve stability with retry logic, caching, and debug mode [@MickLesk](https://github.com/MickLesk) ([#10351](https://github.com/community-scripts/ProxmoxVE/pull/10351))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- core: standardize exit codes and add mappings [@MickLesk](https://github.com/MickLesk) ([#12467](https://github.com/community-scripts/ProxmoxVE/pull/12467))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- frontend: improve detail view badges, addon texts, and HTML title [@MickLesk](https://github.com/MickLesk) ([#12461](https://github.com/community-scripts/ProxmoxVE/pull/12461))
|
||||
|
||||
## 2026-03-01
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Sparkyfitness: use pnpm [@tomfrenzel](https://github.com/tomfrenzel) ([#12445](https://github.com/community-scripts/ProxmoxVE/pull/12445))
|
||||
- OpenArchiver: Fix installation [@tremor021](https://github.com/tremor021) ([#12447](https://github.com/community-scripts/ProxmoxVE/pull/12447))
|
||||
|
||||
## 2026-02-28
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
@@ -19,44 +19,46 @@ variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
ADDON_SCRIPT="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh"
|
||||
|
||||
function update_script() {
|
||||
[[ -d /opt/komodo ]] || {
|
||||
if [[ ! -d /opt/komodo ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
}
|
||||
|
||||
msg_info "Updating ${APP}"
|
||||
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||
if [[ -z "$COMPOSE_FILE" ]]; then
|
||||
msg_error "No valid compose file found in /opt/komodo!"
|
||||
exit
|
||||
fi
|
||||
COMPOSE_BASENAME=$(basename "$COMPOSE_FILE")
|
||||
|
||||
if [[ "$COMPOSE_BASENAME" == "sqlite.compose.yaml" || "$COMPOSE_BASENAME" == "postgres.compose.yaml" ]]; then
|
||||
msg_error "❌ Detected outdated Komodo setup using SQLite or PostgreSQL (FerretDB v1)."
|
||||
echo -e "${YW}This configuration is no longer supported since Komodo v1.18.0.${CL}"
|
||||
echo -e "${YW}Please follow the migration guide:${CL}"
|
||||
echo -e "${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/5689${CL}\n"
|
||||
msg_warn "⚠️ ${APP} has been migrated to an addon script."
|
||||
echo ""
|
||||
msg_info "This is a one-time migration. After this, you can update ${APP} anytime with:"
|
||||
echo -e "${TAB}${TAB}${GN}update_komodo${CL} or ${GN}bash <(curl -fsSL ${ADDON_SCRIPT})${CL}"
|
||||
echo ""
|
||||
read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM
|
||||
if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Migration skipped. The old update will continue to work for now."
|
||||
msg_info "Updating ${APP} (legacy)"
|
||||
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||
if [[ -z "$COMPOSE_FILE" ]]; then
|
||||
msg_error "No valid compose file found in /opt/komodo!"
|
||||
exit 252
|
||||
fi
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env pull
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||
msg_ok "Updated ${APP}"
|
||||
exit
|
||||
fi
|
||||
|
||||
BACKUP_FILE="/opt/komodo/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$COMPOSE_FILE" "$BACKUP_FILE" || {
|
||||
msg_error "Failed to create backup of ${COMPOSE_BASENAME}!"
|
||||
exit
|
||||
}
|
||||
GITHUB_URL="https://raw.githubusercontent.com/moghtech/komodo/main/compose/${COMPOSE_BASENAME}"
|
||||
if ! curl -fsSL "$GITHUB_URL" -o "$COMPOSE_FILE"; then
|
||||
msg_error "Failed to download ${COMPOSE_BASENAME} from GitHub!"
|
||||
mv "$BACKUP_FILE" "$COMPOSE_FILE"
|
||||
exit
|
||||
fi
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env pull
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||
msg_ok "Updated Alpine-Komodo"
|
||||
msg_ok "Updated successfully!"
|
||||
exit 0
|
||||
msg_info "Migrating update function"
|
||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh)"
|
||||
MIGRATION_EOF
|
||||
chmod +x /usr/bin/update
|
||||
|
||||
ln -sf /usr/bin/update /usr/bin/update_komodo 2>/dev/null || true
|
||||
msg_ok "Migration complete"
|
||||
|
||||
msg_info "Running addon update"
|
||||
type=update bash <(curl -fsSL "${ADDON_SCRIPT}")
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
|
||||
@@ -19,6 +19,8 @@ variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
ADDON_SCRIPT="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/coolify.sh"
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
@@ -29,10 +31,31 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Updating Coolify"
|
||||
$STD bash <(curl -fsSL https://cdn.coollabs.io/coolify/install.sh)
|
||||
msg_ok "Updated Coolify"
|
||||
msg_ok "Updated successfully!"
|
||||
msg_warn "⚠️ ${APP} has been migrated to an addon script."
|
||||
echo ""
|
||||
msg_info "This is a one-time migration. After this, you can update ${APP} anytime with:"
|
||||
echo -e "${TAB}${TAB}${GN}update_coolify${CL} or ${GN}bash <(curl -fsSL ${ADDON_SCRIPT})${CL}"
|
||||
echo ""
|
||||
read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM
|
||||
if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Migration skipped. The old update will continue to work for now."
|
||||
msg_info "Updating ${APP} (legacy)"
|
||||
$STD bash <(curl -fsSL https://cdn.coollabs.io/coolify/install.sh)
|
||||
msg_ok "Updated ${APP}"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Migrating update function"
|
||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/coolify.sh)"
|
||||
MIGRATION_EOF
|
||||
chmod +x /usr/bin/update
|
||||
|
||||
ln -sf /usr/bin/update /usr/bin/update_coolify 2>/dev/null || true
|
||||
msg_ok "Migration complete"
|
||||
|
||||
msg_info "Running addon update"
|
||||
type=update bash <(curl -fsSL "${ADDON_SCRIPT}")
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
41
ct/dockge.sh
41
ct/dockge.sh
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# Author: tteck (tteckster) | Migration: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://dockge.kuma.pet/
|
||||
|
||||
@@ -19,26 +19,45 @@ variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
ADDON_SCRIPT="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dockge.sh"
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/dockge ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Updating base system"
|
||||
$STD apt update
|
||||
$STD apt upgrade -y
|
||||
msg_ok "Base system updated"
|
||||
msg_warn "⚠️ ${APP} has been migrated to an addon script."
|
||||
echo ""
|
||||
msg_info "This is a one-time migration. After this, you can update ${APP} anytime with:"
|
||||
echo -e "${TAB}${TAB}${GN}update_dockge${CL} or ${GN}bash <(curl -fsSL ${ADDON_SCRIPT})${CL}"
|
||||
echo ""
|
||||
read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM
|
||||
if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Migration skipped. The old update will continue to work for now."
|
||||
msg_info "Updating ${APP} (legacy)"
|
||||
cd /opt/dockge
|
||||
$STD docker compose pull
|
||||
$STD docker compose up -d
|
||||
msg_ok "Updated ${APP}"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Updating Dockge"
|
||||
cd /opt/dockge
|
||||
$STD docker compose pull
|
||||
$STD docker compose up -d
|
||||
msg_ok "Updated Dockge"
|
||||
msg_ok "Updated successfully!"
|
||||
msg_info "Migrating update function"
|
||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dockge.sh)"
|
||||
MIGRATION_EOF
|
||||
chmod +x /usr/bin/update
|
||||
|
||||
ln -sf /usr/bin/update /usr/bin/update_dockge 2>/dev/null || true
|
||||
msg_ok "Migration complete"
|
||||
|
||||
msg_info "Running addon update"
|
||||
type=update bash <(curl -fsSL "${ADDON_SCRIPT}")
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
ADDON_SCRIPT="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dokploy.sh"
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
@@ -29,10 +31,31 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Updating Dokploy"
|
||||
curl -sSL https://dokploy.com/install.sh | $STD bash -s update
|
||||
msg_ok "Updated Dokploy"
|
||||
msg_ok "Updated successfully!"
|
||||
msg_warn "⚠️ ${APP} has been migrated to an addon script."
|
||||
echo ""
|
||||
msg_info "This is a one-time migration. After this, you can update ${APP} anytime with:"
|
||||
echo -e "${TAB}${TAB}${GN}update_dokploy${CL} or ${GN}bash <(curl -fsSL ${ADDON_SCRIPT})${CL}"
|
||||
echo ""
|
||||
read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM
|
||||
if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Migration skipped. The old update will continue to work for now."
|
||||
msg_info "Updating ${APP} (legacy)"
|
||||
curl -sSL https://dokploy.com/install.sh | $STD bash -s update
|
||||
msg_ok "Updated ${APP}"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Migrating update function"
|
||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dokploy.sh)"
|
||||
MIGRATION_EOF
|
||||
chmod +x /usr/bin/update
|
||||
|
||||
ln -sf /usr/bin/update /usr/bin/update_dokploy 2>/dev/null || true
|
||||
msg_ok "Migration complete"
|
||||
|
||||
msg_info "Running addon update"
|
||||
type=update bash <(curl -fsSL "${ADDON_SCRIPT}")
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ function update_script() {
|
||||
|
||||
if [[ ! -d /opt/endurain ]]; then
|
||||
msg_error "No ${APP} installation found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
if check_for_gh_release "endurain" "endurain-project/endurain"; then
|
||||
msg_info "Stopping Service"
|
||||
|
||||
@@ -25,7 +25,7 @@ function update_script() {
|
||||
check_container_resources
|
||||
if ! command -v evcc >/dev/null 2>&1; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
|
||||
if [[ -f /etc/apt/sources.list.d/evcc-stable.list ]]; then
|
||||
|
||||
@@ -26,7 +26,7 @@ function update_script() {
|
||||
|
||||
if ! dpkg -s grafana >/dev/null 2>&1; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
|
||||
if [[ -f /etc/apt/sources.list.d/grafana.list ]] || [[ ! -f /etc/apt/sources.list.d/grafana.sources ]]; then
|
||||
|
||||
6
ct/headers/profilarr
Normal file
6
ct/headers/profilarr
Normal file
@@ -0,0 +1,6 @@
|
||||
____ _____ __
|
||||
/ __ \_________ / __(_) /___ ___________
|
||||
/ /_/ / ___/ __ \/ /_/ / / __ `/ ___/ ___/
|
||||
/ ____/ / / /_/ / __/ / / /_/ / / / /
|
||||
/_/ /_/ \____/_/ /_/_/\__,_/_/ /_/
|
||||
|
||||
@@ -26,7 +26,7 @@ function update_script() {
|
||||
|
||||
if [[ ! -f /etc/itsm-ng/config_db.php ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
setup_mariadb
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ function update_script() {
|
||||
|
||||
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
||||
msg_error "Unable to detect latest Kasm release URL."
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_info "Checked for new version"
|
||||
|
||||
|
||||
70
ct/komodo.sh
70
ct/komodo.sh
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://komo.do/
|
||||
|
||||
@@ -19,49 +19,49 @@ variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
ADDON_SCRIPT="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh"
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
[[ -d /opt/komodo ]] || {
|
||||
if [[ ! -d /opt/komodo ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
msg_info "Updating Komodo"
|
||||
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||
if [[ -z "$COMPOSE_FILE" ]]; then
|
||||
msg_error "No valid compose file found in /opt/komodo!"
|
||||
exit 1
|
||||
fi
|
||||
COMPOSE_BASENAME=$(basename "$COMPOSE_FILE")
|
||||
|
||||
if [[ "$COMPOSE_BASENAME" == "sqlite.compose.yaml" || "$COMPOSE_BASENAME" == "postgres.compose.yaml" ]]; then
|
||||
msg_error "❌ Detected outdated Komodo setup using SQLite or PostgreSQL (FerretDB v1)."
|
||||
echo -e "${YW}This configuration is no longer supported since Komodo v1.18.0.${CL}"
|
||||
echo -e "${YW}Please follow the migration guide:${CL}"
|
||||
echo -e "${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/5689${CL}\n"
|
||||
exit 1
|
||||
exit
|
||||
fi
|
||||
|
||||
BACKUP_FILE="/opt/komodo/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$COMPOSE_FILE" "$BACKUP_FILE" || {
|
||||
msg_error "Failed to create backup of ${COMPOSE_BASENAME}!"
|
||||
exit 1
|
||||
}
|
||||
GITHUB_URL="https://raw.githubusercontent.com/moghtech/komodo/main/compose/${COMPOSE_BASENAME}"
|
||||
if ! curl -fsSL "$GITHUB_URL" -o "$COMPOSE_FILE"; then
|
||||
msg_error "Failed to download ${COMPOSE_BASENAME} from GitHub!"
|
||||
mv "$BACKUP_FILE" "$COMPOSE_FILE"
|
||||
exit 1
|
||||
msg_warn "⚠️ ${APP} has been migrated to an addon script."
|
||||
echo ""
|
||||
msg_info "This is a one-time migration. After this, you can update ${APP} anytime with:"
|
||||
echo -e "${TAB}${TAB}${GN}update_komodo${CL} or ${GN}bash <(curl -fsSL ${ADDON_SCRIPT})${CL}"
|
||||
echo ""
|
||||
read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM
|
||||
if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Migration skipped. The old update will continue to work for now."
|
||||
msg_info "Updating ${APP} (legacy)"
|
||||
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||
if [[ -z "$COMPOSE_FILE" ]]; then
|
||||
msg_error "No valid compose file found in /opt/komodo!"
|
||||
exit 252
|
||||
fi
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env pull
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||
msg_ok "Updated ${APP}"
|
||||
exit
|
||||
fi
|
||||
if ! grep -qxF 'COMPOSE_KOMODO_BACKUPS_PATH=/etc/komodo/backups' /opt/komodo/compose.env; then
|
||||
sed -i '/^COMPOSE_KOMODO_IMAGE_TAG=latest$/a COMPOSE_KOMODO_BACKUPS_PATH=/etc/komodo/backups' /opt/komodo/compose.env
|
||||
fi
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env pull
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||
msg_ok "Updated Komodo"
|
||||
|
||||
msg_info "Migrating update function"
|
||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh)"
|
||||
MIGRATION_EOF
|
||||
chmod +x /usr/bin/update
|
||||
|
||||
ln -sf /usr/bin/update /usr/bin/update_komodo 2>/dev/null || true
|
||||
msg_ok "Migration complete"
|
||||
|
||||
msg_info "Running addon update"
|
||||
type=update bash <(curl -fsSL "${ADDON_SCRIPT}")
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ function update_script() {
|
||||
|
||||
if ! dpkg -s loki >/dev/null 2>&1; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
|
||||
CHOICE=$(msg_menu "Loki Update Options" \
|
||||
|
||||
@@ -44,7 +44,7 @@ function update_script() {
|
||||
echo -e "${TAB}${GATEWAY}${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/9223${CL}"
|
||||
echo -e ""
|
||||
msg_custom "⚠️" "Update aborted. Please migrate your data first."
|
||||
exit 1
|
||||
exit 253
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
85
ct/profilarr.sh
Normal file
85
ct/profilarr.sh
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: michelroegl-brunner
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/Dictionarry-Hub/profilarr
|
||||
|
||||
APP="Profilarr"
|
||||
var_tags="${var_tags:-arr;radarr;sonarr;config}"
|
||||
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/profilarr ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "profilarr" "Dictionarry-Hub/profilarr"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop profilarr
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Backing up Data"
|
||||
if [[ -d /config ]]; then
|
||||
cp -r /config /opt/profilarr_config_backup
|
||||
fi
|
||||
msg_ok "Backed up Data"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "profilarr" "Dictionarry-Hub/profilarr" "tarball"
|
||||
|
||||
msg_info "Installing Python Dependencies"
|
||||
cd /opt/profilarr/backend
|
||||
$STD uv venv /opt/profilarr/backend/.venv
|
||||
sed 's/==/>=/g' requirements.txt >requirements-relaxed.txt
|
||||
$STD uv pip install --python /opt/profilarr/backend/.venv/bin/python -r requirements-relaxed.txt
|
||||
rm -f requirements-relaxed.txt
|
||||
msg_ok "Installed Python Dependencies"
|
||||
|
||||
msg_info "Building Frontend"
|
||||
if [[ -d /opt/profilarr/frontend ]]; then
|
||||
cd /opt/profilarr/frontend
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
cp -r dist /opt/profilarr/backend/app/static
|
||||
fi
|
||||
msg_ok "Built Frontend"
|
||||
|
||||
msg_info "Restoring Data"
|
||||
if [[ -d /opt/profilarr_config_backup ]]; then
|
||||
mkdir -p /config
|
||||
cp -r /opt/profilarr_config_backup/. /config/
|
||||
rm -rf /opt/profilarr_config_backup
|
||||
fi
|
||||
msg_ok "Restored Data"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start profilarr
|
||||
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}:6868${CL}"
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# Author: tteck (tteckster) | Migration: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://runtipi.io/
|
||||
|
||||
@@ -19,16 +19,43 @@ variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
ADDON_SCRIPT="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/runtipi.sh"
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/runtipi ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
cd /opt/runtipi && ./runtipi-cli update latest
|
||||
msg_ok "Updated successfully!"
|
||||
|
||||
msg_warn "⚠️ ${APP} has been migrated to an addon script."
|
||||
echo ""
|
||||
msg_info "This is a one-time migration. After this, you can update ${APP} anytime with:"
|
||||
echo -e "${TAB}${TAB}${GN}update_runtipi${CL} or ${GN}bash <(curl -fsSL ${ADDON_SCRIPT})${CL}"
|
||||
echo ""
|
||||
read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM
|
||||
if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Migration skipped. The old update will continue to work for now."
|
||||
msg_info "Updating ${APP} (legacy)"
|
||||
cd /opt/runtipi && ./runtipi-cli update latest
|
||||
msg_ok "Updated ${APP}"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Migrating update function"
|
||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/runtipi.sh)"
|
||||
MIGRATION_EOF
|
||||
chmod +x /usr/bin/update
|
||||
|
||||
ln -sf /usr/bin/update /usr/bin/update_runtipi 2>/dev/null || true
|
||||
msg_ok "Migration complete"
|
||||
|
||||
msg_info "Running addon update"
|
||||
type=update bash <(curl -fsSL "${ADDON_SCRIPT}")
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
NODE_VERSION="25" setup_nodejs
|
||||
|
||||
if check_for_gh_release "sparkyfitness" "CodeWithCJ/SparkyFitness"; then
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop sparkyfitness-server nginx
|
||||
@@ -48,6 +46,9 @@ function update_script() {
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "sparkyfitness" "CodeWithCJ/SparkyFitness" "tarball"
|
||||
|
||||
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1]' /opt/sparkyfitness/package.json)"
|
||||
NODE_VERSION="25" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
|
||||
|
||||
msg_info "Updating Sparky Fitness Backend"
|
||||
cd /opt/sparkyfitness/SparkyFitnessServer
|
||||
$STD npm install
|
||||
@@ -55,8 +56,8 @@ function update_script() {
|
||||
|
||||
msg_info "Updating Sparky Fitness Frontend (Patience)"
|
||||
cd /opt/sparkyfitness/SparkyFitnessFrontend
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
$STD pnpm install
|
||||
$STD pnpm run build
|
||||
cp -a /opt/sparkyfitness/SparkyFitnessFrontend/dist/. /var/www/sparkyfitness/
|
||||
msg_ok "Updated Sparky Fitness Frontend"
|
||||
|
||||
|
||||
@@ -75,10 +75,31 @@ if [ -f \$pg_config_file ]; then
|
||||
fi
|
||||
fi
|
||||
systemctl restart postgresql
|
||||
sudo -u postgres psql -c "ALTER USER tracearr WITH SUPERUSER;"
|
||||
EOF
|
||||
chmod +x /data/tracearr/prestart.sh
|
||||
msg_ok "Updated prestart script"
|
||||
|
||||
# check if tailscale is installed
|
||||
if command -v tailscale >/dev/null 2>&1; then
|
||||
# Tracearr runs tailscaled in user mode, disable the service.
|
||||
$STD systemctl disable --now tailscaled
|
||||
$STD systemctl stop tailscaled
|
||||
msg_ok "Tailscale already installed"
|
||||
else
|
||||
msg_info "Installing tailscale"
|
||||
setup_deb822_repo \
|
||||
"tailscale" \
|
||||
"https://pkgs.tailscale.com/stable/$(get_os_info id)/$(get_os_info codename).noarmor.gpg" \
|
||||
"https://pkgs.tailscale.com/stable/$(get_os_info id)/" \
|
||||
"$(get_os_info codename)"
|
||||
$STD apt install -y tailscale
|
||||
# Tracearr runs tailscaled in user mode, disable the service.
|
||||
$STD systemctl disable --now tailscaled
|
||||
$STD systemctl stop tailscaled
|
||||
msg_ok "Installed tailscale"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "tracearr" "connorgallopo/Tracearr"; then
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop tracearr postgresql redis
|
||||
@@ -122,6 +143,8 @@ EOF
|
||||
sed -i "s/^APP_VERSION=.*/APP_VERSION=$(cat /root/.tracearr)/" /data/tracearr/.env
|
||||
chmod 600 /data/tracearr/.env
|
||||
chown -R tracearr:tracearr /data/tracearr
|
||||
mkdir -p /data/backup
|
||||
chown -R tracearr:tracearr /data/backup
|
||||
msg_ok "Configured Tracearr"
|
||||
|
||||
msg_info "Starting services"
|
||||
|
||||
@@ -34,14 +34,14 @@ function update_script() {
|
||||
msg_warn "This requires MANUAL config changes in /etc/vikunja/config.yml."
|
||||
msg_warn "See: https://vikunja.io/changelog/whats-new-in-vikunja-1.0.0/#config-changes"
|
||||
|
||||
read -rp "Continue with update? (y to proceed): " -t 30 CONFIRM1 || exit 1
|
||||
read -rp "Continue with update? (y to proceed): " -t 30 CONFIRM1 || exit 254
|
||||
[[ "$CONFIRM1" =~ ^[yY]$ ]] || exit 0
|
||||
|
||||
echo
|
||||
msg_warn "Vikunja may not start after the update until you manually adjust the config."
|
||||
msg_warn "Details: https://vikunja.io/changelog/whats-new-in-vikunja-1.0.0/#config-changes"
|
||||
|
||||
read -rp "Acknowledge and continue? (y): " -t 30 CONFIRM2 || exit 1
|
||||
read -rp "Acknowledge and continue? (y): " -t 30 CONFIRM2 || exit 254
|
||||
[[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"website": "https://2fauth.app/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/2fauth.webp",
|
||||
"config_path": "cat /opt/2fauth/.env",
|
||||
"description": "2FAuth is a web based self-hosted alternative to One Time Passcode (OTP) generators like Google Authenticator, designed for both mobile and desktop. It aims to ease you perform your 2FA authentication steps whatever the device you handle, with a clean and suitable interface.",
|
||||
"description": "2FAuth is a web based self-hosted alternative to One Time Passcode (OTP) generators like Google Authenticator, designed for both mobile and desktop. It aims to ease you perform your 2FA authentication steps whatever the device you handle, with a clean and suitable interface. - Workflow - Test",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
|
||||
@@ -1,52 +1,56 @@
|
||||
{
|
||||
"name": "Coolify",
|
||||
"slug": "coolify",
|
||||
"categories": [
|
||||
3
|
||||
],
|
||||
"date_created": "2025-12-09",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 8000,
|
||||
"documentation": "https://coolify.io/docs",
|
||||
"config_path": "/data/coolify",
|
||||
"website": "https://coolify.io/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/coolify.webp",
|
||||
"description": "Coolify is an open-source & self-hostable alternative to Heroku, Netlify, and Vercel. It helps you manage your servers, applications, and databases on your own hardware with Docker. Deploy any application from Git repositories, Docker images, or use pre-built templates.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/coolify.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 4096,
|
||||
"hdd": 30,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
"name": "Coolify",
|
||||
"slug": "coolify",
|
||||
"categories": [
|
||||
3
|
||||
],
|
||||
"date_created": "2025-12-09",
|
||||
"type": "addon",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 8000,
|
||||
"documentation": "https://coolify.io/docs",
|
||||
"website": "https://coolify.io/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/coolify.webp",
|
||||
"config_path": "/data/coolify",
|
||||
"description": "Coolify is an open-source & self-hostable alternative to Heroku, Netlify, and Vercel. It helps you manage your servers, applications, and databases on your own hardware with Docker. Deploy any application from Git repositories, Docker images, or use pre-built templates.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "tools/addon/coolify.sh",
|
||||
"resources": {
|
||||
"cpu": null,
|
||||
"ram": null,
|
||||
"hdd": null,
|
||||
"os": null,
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "This is an addon script intended to be used on top of an existing Docker container.",
|
||||
"type": "info"
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "Initial setup will be done via the web interface on first access.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Coolify has built-in auto-updates. You can configure update frequency in Settings.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Coolify requires SSH access to manage deployments. SSH is enabled automatically.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "This container uses Docker-in-Docker (nesting) for application deployments.",
|
||||
"type": "warning"
|
||||
}
|
||||
]
|
||||
{
|
||||
"text": "Execute within an existing LXC console (Debian / Ubuntu / Alpine supported)",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Initial setup will be done via the web interface on first access.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Coolify has built-in auto-updates. You can configure update frequency in Settings.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "To update via CLI, run the addon script again and select Update, or use: bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/coolify.sh)",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,25 +5,25 @@
|
||||
3
|
||||
],
|
||||
"date_created": "2024-05-02",
|
||||
"type": "ct",
|
||||
"type": "addon",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 5001,
|
||||
"documentation": null,
|
||||
"website": "https://github.com/louislam/dockge",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/dockge.webp",
|
||||
"config_path": "",
|
||||
"config_path": "/opt/dockge/compose.yaml",
|
||||
"description": "Dockge is a fancy, easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/dockge.sh",
|
||||
"script": "tools/addon/dockge.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 18,
|
||||
"os": "debian",
|
||||
"version": "13"
|
||||
"cpu": null,
|
||||
"ram": null,
|
||||
"hdd": null,
|
||||
"os": null,
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -33,12 +33,16 @@
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "Options to add Immich and/or Home Assistant",
|
||||
"text": "This is an addon script intended to be used on top of an existing Docker container.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "If the LXC is created Privileged, the script will automatically set up USB passthrough.",
|
||||
"type": "warning"
|
||||
"text": "Execute within an existing LXC console (Debian / Ubuntu / Alpine supported)",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "To update, run the addon script again and select Update, or use: bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dockge.sh)",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,48 +1,56 @@
|
||||
{
|
||||
"name": "Dokploy",
|
||||
"slug": "dokploy",
|
||||
"categories": [
|
||||
3
|
||||
],
|
||||
"date_created": "2025-12-09",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": true,
|
||||
"interface_port": 3000,
|
||||
"documentation": "https://docs.dokploy.com/",
|
||||
"config_path": "/etc/dokploy",
|
||||
"website": "https://dokploy.com/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/png/dokploy.png",
|
||||
"description": "Dokploy is a free, self-hostable Platform as a Service (PaaS) that simplifies the deployment and management of applications and databases. Built with Docker and Traefik, it offers features like automatic SSL, Docker Compose support, database backups, and a real-time monitoring dashboard.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/dokploy.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 10,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
"name": "Dokploy",
|
||||
"slug": "dokploy",
|
||||
"categories": [
|
||||
3
|
||||
],
|
||||
"date_created": "2025-12-09",
|
||||
"type": "addon",
|
||||
"updateable": true,
|
||||
"privileged": true,
|
||||
"interface_port": 3000,
|
||||
"documentation": "https://docs.dokploy.com/",
|
||||
"website": "https://dokploy.com/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/png/dokploy.png",
|
||||
"config_path": "/etc/dokploy",
|
||||
"description": "Dokploy is a free, self-hostable Platform as a Service (PaaS) that simplifies the deployment and management of applications and databases. Built with Docker and Traefik, it offers features like automatic SSL, Docker Compose support, database backups, and a real-time monitoring dashboard.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "tools/addon/dokploy.sh",
|
||||
"resources": {
|
||||
"cpu": null,
|
||||
"ram": null,
|
||||
"hdd": null,
|
||||
"os": null,
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "This is an addon script intended to be used on top of an existing Docker container.",
|
||||
"type": "info"
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "Initial setup will be done via the web interface on first access.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Dokploy has built-in auto-updates via the web interface.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "This container uses Docker-in-Docker (nesting) for application deployments.",
|
||||
"type": "warning"
|
||||
}
|
||||
]
|
||||
{
|
||||
"text": "Execute within an existing LXC console (Debian / Ubuntu / Alpine supported)",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Initial setup will be done via the web interface on first access.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Dokploy has built-in auto-updates via the web interface.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "To update via CLI, run the addon script again and select Update, or use: bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dokploy.sh)",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated": "2026-03-01T06:15:59Z",
|
||||
"generated": "2026-03-02T13:48:26Z",
|
||||
"versions": [
|
||||
{
|
||||
"slug": "2fauth",
|
||||
@@ -116,9 +116,9 @@
|
||||
{
|
||||
"slug": "bentopdf",
|
||||
"repo": "alam00000/bentopdf",
|
||||
"version": "v2.3.3",
|
||||
"version": "v2.4.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-27T08:40:05Z"
|
||||
"date": "2026-03-01T14:25:43Z"
|
||||
},
|
||||
{
|
||||
"slug": "beszel",
|
||||
@@ -151,9 +151,9 @@
|
||||
{
|
||||
"slug": "booklore",
|
||||
"repo": "booklore-app/BookLore",
|
||||
"version": "v2.0.4",
|
||||
"version": "v2.0.5",
|
||||
"pinned": false,
|
||||
"date": "2026-02-28T01:54:25Z"
|
||||
"date": "2026-03-01T16:13:13Z"
|
||||
},
|
||||
{
|
||||
"slug": "bookstack",
|
||||
@@ -200,9 +200,9 @@
|
||||
{
|
||||
"slug": "cleanuparr",
|
||||
"repo": "Cleanuparr/Cleanuparr",
|
||||
"version": "v2.7.6",
|
||||
"version": "v2.7.7",
|
||||
"pinned": false,
|
||||
"date": "2026-02-27T19:32:02Z"
|
||||
"date": "2026-03-02T13:08:32Z"
|
||||
},
|
||||
{
|
||||
"slug": "cloudreve",
|
||||
@@ -270,9 +270,9 @@
|
||||
{
|
||||
"slug": "databasus",
|
||||
"repo": "databasus/databasus",
|
||||
"version": "v3.16.3",
|
||||
"version": "v3.16.4",
|
||||
"pinned": false,
|
||||
"date": "2026-02-25T19:57:26Z"
|
||||
"date": "2026-03-01T08:20:17Z"
|
||||
},
|
||||
{
|
||||
"slug": "dawarich",
|
||||
@@ -312,9 +312,9 @@
|
||||
{
|
||||
"slug": "domain-monitor",
|
||||
"repo": "Hosteroid/domain-monitor",
|
||||
"version": "v1.1.3",
|
||||
"version": "v1.1.4",
|
||||
"pinned": false,
|
||||
"date": "2026-02-11T15:48:18Z"
|
||||
"date": "2026-03-02T09:25:01Z"
|
||||
},
|
||||
{
|
||||
"slug": "donetick",
|
||||
@@ -424,9 +424,9 @@
|
||||
{
|
||||
"slug": "frigate",
|
||||
"repo": "blakeblackshear/frigate",
|
||||
"version": "v0.16.4",
|
||||
"version": "v0.17.0",
|
||||
"pinned": true,
|
||||
"date": "2026-01-29T00:42:14Z"
|
||||
"date": "2026-02-27T03:03:01Z"
|
||||
},
|
||||
{
|
||||
"slug": "gatus",
|
||||
@@ -438,9 +438,9 @@
|
||||
{
|
||||
"slug": "ghostfolio",
|
||||
"repo": "ghostfolio/ghostfolio",
|
||||
"version": "2.244.0",
|
||||
"version": "2.245.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-28T09:51:45Z"
|
||||
"date": "2026-03-01T09:09:57Z"
|
||||
},
|
||||
{
|
||||
"slug": "gitea",
|
||||
@@ -452,9 +452,9 @@
|
||||
{
|
||||
"slug": "gitea-mirror",
|
||||
"repo": "RayLabsHQ/gitea-mirror",
|
||||
"version": "v3.10.1",
|
||||
"version": "v3.11.0",
|
||||
"pinned": false,
|
||||
"date": "2026-03-01T03:08:07Z"
|
||||
"date": "2026-03-02T10:19:59Z"
|
||||
},
|
||||
{
|
||||
"slug": "glance",
|
||||
@@ -613,9 +613,9 @@
|
||||
{
|
||||
"slug": "jackett",
|
||||
"repo": "Jackett/Jackett",
|
||||
"version": "v0.24.1234",
|
||||
"version": "v0.24.1247",
|
||||
"pinned": false,
|
||||
"date": "2026-03-01T05:55:44Z"
|
||||
"date": "2026-03-02T05:56:37Z"
|
||||
},
|
||||
{
|
||||
"slug": "jellystat",
|
||||
@@ -634,9 +634,9 @@
|
||||
{
|
||||
"slug": "jotty",
|
||||
"repo": "fccview/jotty",
|
||||
"version": "1.20.0",
|
||||
"version": "1.21.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-12T09:23:30Z"
|
||||
"date": "2026-03-02T11:08:54Z"
|
||||
},
|
||||
{
|
||||
"slug": "kapowarr",
|
||||
@@ -669,16 +669,16 @@
|
||||
{
|
||||
"slug": "kima-hub",
|
||||
"repo": "Chevron7Locked/kima-hub",
|
||||
"version": "v1.6.0-rc.1",
|
||||
"version": "v1.6.0",
|
||||
"pinned": false,
|
||||
"date": "2026-03-01T05:38:32Z"
|
||||
"date": "2026-03-02T05:43:31Z"
|
||||
},
|
||||
{
|
||||
"slug": "kimai",
|
||||
"repo": "kimai/kimai",
|
||||
"version": "2.50.0",
|
||||
"version": "2.51.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-25T20:13:51Z"
|
||||
"date": "2026-03-01T15:56:56Z"
|
||||
},
|
||||
{
|
||||
"slug": "kitchenowl",
|
||||
@@ -851,9 +851,9 @@
|
||||
{
|
||||
"slug": "mediamtx",
|
||||
"repo": "bluenviron/mediamtx",
|
||||
"version": "v1.16.2",
|
||||
"version": "v1.16.3",
|
||||
"pinned": false,
|
||||
"date": "2026-02-22T17:31:41Z"
|
||||
"date": "2026-03-01T15:49:12Z"
|
||||
},
|
||||
{
|
||||
"slug": "meilisearch",
|
||||
@@ -942,9 +942,9 @@
|
||||
{
|
||||
"slug": "nightscout",
|
||||
"repo": "nightscout/cgm-remote-monitor",
|
||||
"version": "15.0.4",
|
||||
"version": "v15.0.5",
|
||||
"pinned": false,
|
||||
"date": "2026-02-28T17:07:02Z"
|
||||
"date": "2026-03-01T21:22:37Z"
|
||||
},
|
||||
{
|
||||
"slug": "nocodb",
|
||||
@@ -956,9 +956,9 @@
|
||||
{
|
||||
"slug": "nodebb",
|
||||
"repo": "NodeBB/NodeBB",
|
||||
"version": "v4.9.0",
|
||||
"version": "v4.9.1",
|
||||
"pinned": false,
|
||||
"date": "2026-02-27T19:20:51Z"
|
||||
"date": "2026-03-01T20:52:43Z"
|
||||
},
|
||||
{
|
||||
"slug": "nodecast-tv",
|
||||
@@ -1124,9 +1124,9 @@
|
||||
{
|
||||
"slug": "planka",
|
||||
"repo": "plankanban/planka",
|
||||
"version": "v2.0.2",
|
||||
"version": "v2.0.3",
|
||||
"pinned": false,
|
||||
"date": "2026-02-23T17:47:15Z"
|
||||
"date": "2026-03-01T16:03:23Z"
|
||||
},
|
||||
{
|
||||
"slug": "plant-it",
|
||||
@@ -1156,6 +1156,13 @@
|
||||
"pinned": false,
|
||||
"date": "2025-11-12T07:10:14Z"
|
||||
},
|
||||
{
|
||||
"slug": "profilarr",
|
||||
"repo": "Dictionarry-Hub/profilarr",
|
||||
"version": "v1.1.4",
|
||||
"pinned": false,
|
||||
"date": "2026-01-29T14:57:25Z"
|
||||
},
|
||||
{
|
||||
"slug": "projectsend",
|
||||
"repo": "projectsend/projectsend",
|
||||
@@ -1215,9 +1222,9 @@
|
||||
{
|
||||
"slug": "pulse",
|
||||
"repo": "rcourtman/Pulse",
|
||||
"version": "v5.1.15",
|
||||
"version": "v5.1.16",
|
||||
"pinned": false,
|
||||
"date": "2026-02-27T15:17:24Z"
|
||||
"date": "2026-03-01T23:13:09Z"
|
||||
},
|
||||
{
|
||||
"slug": "pve-scripts-local",
|
||||
@@ -1278,9 +1285,9 @@
|
||||
{
|
||||
"slug": "rdtclient",
|
||||
"repo": "rogerfar/rdt-client",
|
||||
"version": "v2.0.124",
|
||||
"version": "v2.0.125",
|
||||
"pinned": false,
|
||||
"date": "2026-02-24T03:18:03Z"
|
||||
"date": "2026-03-01T18:29:10Z"
|
||||
},
|
||||
{
|
||||
"slug": "reactive-resume",
|
||||
@@ -1418,9 +1425,9 @@
|
||||
{
|
||||
"slug": "snowshare",
|
||||
"repo": "TuroYT/snowshare",
|
||||
"version": "v1.3.7",
|
||||
"version": "v1.3.8",
|
||||
"pinned": false,
|
||||
"date": "2026-02-23T15:51:39Z"
|
||||
"date": "2026-03-02T07:43:42Z"
|
||||
},
|
||||
{
|
||||
"slug": "sonarr",
|
||||
@@ -1579,9 +1586,9 @@
|
||||
{
|
||||
"slug": "trilium",
|
||||
"repo": "TriliumNext/Trilium",
|
||||
"version": "v0.101.3",
|
||||
"version": "v0.102.0",
|
||||
"pinned": false,
|
||||
"date": "2026-01-08T18:05:22Z"
|
||||
"date": "2026-03-01T20:37:40Z"
|
||||
},
|
||||
{
|
||||
"slug": "trip",
|
||||
@@ -1656,9 +1663,9 @@
|
||||
{
|
||||
"slug": "victoriametrics",
|
||||
"repo": "VictoriaMetrics/VictoriaMetrics",
|
||||
"version": "v1.136.0",
|
||||
"version": "v1.137.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-16T13:17:50Z"
|
||||
"date": "2026-03-02T10:09:29Z"
|
||||
},
|
||||
{
|
||||
"slug": "vikunja",
|
||||
@@ -1684,9 +1691,9 @@
|
||||
{
|
||||
"slug": "wanderer",
|
||||
"repo": "meilisearch/meilisearch",
|
||||
"version": "v1.36.0",
|
||||
"version": "v1.37.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-23T08:13:32Z"
|
||||
"date": "2026-03-02T09:16:36Z"
|
||||
},
|
||||
{
|
||||
"slug": "warracker",
|
||||
@@ -1789,9 +1796,9 @@
|
||||
{
|
||||
"slug": "zigbee2mqtt",
|
||||
"repo": "Koenkk/zigbee2mqtt",
|
||||
"version": "2.8.0",
|
||||
"version": "2.9.1",
|
||||
"pinned": false,
|
||||
"date": "2026-02-01T19:27:25Z"
|
||||
"date": "2026-03-02T11:16:46Z"
|
||||
},
|
||||
{
|
||||
"slug": "zipline",
|
||||
@@ -1803,9 +1810,9 @@
|
||||
{
|
||||
"slug": "zitadel",
|
||||
"repo": "zitadel/zitadel",
|
||||
"version": "v4.11.1",
|
||||
"version": "v4.12.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-25T06:13:13Z"
|
||||
"date": "2026-03-02T08:16:10Z"
|
||||
},
|
||||
{
|
||||
"slug": "zoraxy",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
3
|
||||
],
|
||||
"date_created": "2025-01-01",
|
||||
"type": "ct",
|
||||
"type": "addon",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 9120,
|
||||
@@ -17,24 +17,13 @@
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/komodo.sh",
|
||||
"script": "tools/addon/komodo.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 10,
|
||||
"os": "debian",
|
||||
"version": "13"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alpine",
|
||||
"script": "ct/alpine-komodo.sh",
|
||||
"resources": {
|
||||
"cpu": 1,
|
||||
"ram": 1024,
|
||||
"hdd": 10,
|
||||
"os": "alpine",
|
||||
"version": "3.23"
|
||||
"cpu": null,
|
||||
"ram": null,
|
||||
"hdd": null,
|
||||
"os": null,
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -44,7 +33,19 @@
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "For admin username and password type `cat ~/komodo.creds` inside LXC.",
|
||||
"text": "This is an addon script intended to be used on top of an existing Docker container.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Execute within an existing LXC console (Debian / Ubuntu / Alpine supported)",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "For admin username and password, run: cat ~/komodo.creds",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "To update, run the addon script again and select Update, or use: bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh)",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
|
||||
35
frontend/public/json/profilarr.json
Normal file
35
frontend/public/json/profilarr.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "Profilarr",
|
||||
"slug": "profilarr",
|
||||
"categories": [
|
||||
14
|
||||
],
|
||||
"date_created": "2026-03-02",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 6868,
|
||||
"documentation": "https://github.com/Dictionarry-Hub/profilarr#readme",
|
||||
"website": "https://github.com/Dictionarry-Hub/profilarr",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/profilarr.webp",
|
||||
"config_path": "/config",
|
||||
"description": "Profilarr is a configuration management platform for Radarr and Sonarr that simplifies importing, syncing, and managing quality profiles, custom formats, and release profiles.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/profilarr.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": []
|
||||
}
|
||||
@@ -5,25 +5,25 @@
|
||||
2
|
||||
],
|
||||
"date_created": "2024-05-02",
|
||||
"type": "ct",
|
||||
"type": "addon",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 80,
|
||||
"documentation": "https://runtipi.io/docs/introduction",
|
||||
"website": "https://runtipi.io/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/runtipi.webp",
|
||||
"config_path": "opt/runtipi/state/settings.json",
|
||||
"config_path": "/opt/runtipi/state/settings.json",
|
||||
"description": "Runtipi lets you install all your favorite self-hosted apps without the hassle of configuring and managing each service. One-click installs and updates for more than 180 popular apps.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/runtipi.sh",
|
||||
"script": "tools/addon/runtipi.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "debian",
|
||||
"version": "13"
|
||||
"cpu": null,
|
||||
"ram": null,
|
||||
"hdd": null,
|
||||
"os": null,
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -32,9 +32,21 @@
|
||||
"password": null
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "This is an addon script intended to be used on top of an existing Docker container.",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Execute within an existing LXC console (Debian / Ubuntu only)",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.",
|
||||
"type": "warning"
|
||||
},
|
||||
{
|
||||
"text": "To update via CLI, run the addon script again and select Update, or use: bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/runtipi.sh)",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@ export function getDisplayValueFromType(type: string) {
|
||||
case "vm":
|
||||
return "VM";
|
||||
case "pve":
|
||||
return "PVE";
|
||||
case "addon":
|
||||
return "";
|
||||
return "ADDON";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
@@ -36,10 +37,9 @@ export function LatestScripts({
|
||||
onPageChange: (page: number) => void;
|
||||
}) {
|
||||
const latestScripts = useMemo(() => {
|
||||
if (!items)
|
||||
return [];
|
||||
if (!items) return [];
|
||||
|
||||
const scripts = items.flatMap(category => category.scripts || []);
|
||||
const scripts = items.flatMap((category) => category.scripts || []);
|
||||
|
||||
// Filter out duplicates by slug
|
||||
const uniqueScriptsMap = new Map<string, Script>();
|
||||
@@ -97,7 +97,7 @@ export function LatestScripts({
|
||||
</div>
|
||||
)}
|
||||
<div className="min-w flex w-full flex-row flex-wrap gap-4">
|
||||
{latestScripts.slice(startIndex, endIndex).map(script => (
|
||||
{latestScripts.slice(startIndex, endIndex).map((script) => (
|
||||
<Card key={script.slug} className="min-w-[250px] flex-1 flex-grow bg-accent/30">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-3">
|
||||
@@ -108,15 +108,13 @@ export function LatestScripts({
|
||||
height={64}
|
||||
width={64}
|
||||
alt=""
|
||||
onError={e => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
||||
onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
||||
className="h-11 w-11 object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="text-lg line-clamp-1">
|
||||
{script.name}
|
||||
{" "}
|
||||
{getDisplayValueFromType(script.type)}
|
||||
{script.name} {getDisplayValueFromType(script.type)}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground flex items-center gap-1">
|
||||
<CalendarPlus className="h-4 w-4" />
|
||||
@@ -149,7 +147,7 @@ export function LatestScripts({
|
||||
|
||||
export function MostViewedScripts({ items }: { items: Category[] }) {
|
||||
const mostViewedScripts = items.reduce((acc: Script[], category) => {
|
||||
const foundScripts = category.scripts.filter(script => mostPopularScripts.includes(script.slug));
|
||||
const foundScripts = category.scripts.filter((script) => mostPopularScripts.includes(script.slug));
|
||||
return acc.concat(foundScripts);
|
||||
}, []);
|
||||
|
||||
@@ -161,7 +159,7 @@ export function MostViewedScripts({ items }: { items: Category[] }) {
|
||||
</>
|
||||
)}
|
||||
<div className="min-w flex w-full flex-row flex-wrap gap-4">
|
||||
{mostViewedScripts.map(script => (
|
||||
{mostViewedScripts.map((script) => (
|
||||
<Card key={script.slug} className="min-w-[250px] flex-1 flex-grow bg-accent/30">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-3">
|
||||
@@ -172,15 +170,13 @@ export function MostViewedScripts({ items }: { items: Category[] }) {
|
||||
height={64}
|
||||
width={64}
|
||||
alt=""
|
||||
onError={e => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
||||
onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
||||
className="h-11 w-11 object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="line-clamp-1 text-lg">
|
||||
{script.name}
|
||||
{" "}
|
||||
{getDisplayValueFromType(script.type)}
|
||||
{script.name} {getDisplayValueFromType(script.type)}
|
||||
</p>
|
||||
<p className="flex items-center gap-1 text-sm text-muted-foreground">
|
||||
<CalendarPlus className="h-4 w-4" />
|
||||
|
||||
@@ -14,6 +14,7 @@ import { basePath } from "@/config/site-config";
|
||||
import { extractDate } from "@/lib/time";
|
||||
|
||||
import DisableDescription from "./script-items/disable-description";
|
||||
import { formattedBadge } from "@/components/command-menu";
|
||||
import { getDisplayValueFromType } from "./script-info-blocks";
|
||||
import DefaultPassword from "./script-items/default-password";
|
||||
import InstallCommand from "./script-items/install-command";
|
||||
@@ -31,7 +32,7 @@ type ScriptItemProps = {
|
||||
|
||||
function ScriptHeader({ item }: { item: Script }) {
|
||||
const defaultInstallMethod = item.install_methods?.[0];
|
||||
const os = defaultInstallMethod?.resources?.os || "Proxmox Node";
|
||||
const os = defaultInstallMethod?.resources?.os || (item.type === "addon" ? "Existing LXC or Proxmox Node" : "Proxmox Node");
|
||||
const version = defaultInstallMethod?.resources?.version || "";
|
||||
|
||||
return (
|
||||
@@ -55,9 +56,7 @@ function ScriptHeader({ item }: { item: Script }) {
|
||||
<h1 className="text-2xl font-semibold tracking-tight flex items-center gap-2">
|
||||
{item.name}
|
||||
<VersionInfo item={item} />
|
||||
<span className="inline-flex items-center rounded-md bg-accent/30 px-2 py-1 text-sm">
|
||||
{getDisplayValueFromType(item.type)}
|
||||
</span>
|
||||
{formattedBadge(item.type)}
|
||||
</h1>
|
||||
<div className="mt-1 flex items-center gap-3 text-sm text-muted-foreground">
|
||||
<span>
|
||||
|
||||
@@ -36,17 +36,24 @@ const TooltipBadge: React.FC<TooltipProps> = ({ variant, label, content }) => (
|
||||
export default function Tooltips({ item }: { item: Script }) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
{item.privileged && (
|
||||
{item.privileged && item.type !== "addon" && (
|
||||
<TooltipBadge variant="warning" label="Privileged" content="This script will be run in a privileged LXC" />
|
||||
)}
|
||||
{item.updateable && item.type !== "pve" && (
|
||||
{item.updateable && item.type !== "pve" && item.type !== "addon" && (
|
||||
<TooltipBadge
|
||||
variant="success"
|
||||
label="Updateable"
|
||||
content={`To Update ${item.name}, run the command below (or type update) in the LXC Console.`}
|
||||
/>
|
||||
)}
|
||||
{!item.updateable && item.type !== "pve" && <TooltipBadge variant="failure" label="Not Updateable" />}
|
||||
{item.updateable && item.type === "addon" && (
|
||||
<TooltipBadge
|
||||
variant="success"
|
||||
label="Updateable"
|
||||
content={`Run update_${item.slug} to update or use the bash command inside the LXC.`}
|
||||
/>
|
||||
)}
|
||||
{!item.updateable && item.type !== "pve" && item.type !== "addon" && <TooltipBadge variant="failure" label="Not Updateable" />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,11 @@ function ScriptContent() {
|
||||
.flat()
|
||||
.find(script => script.slug === selectedScript);
|
||||
setItem(script);
|
||||
if (script) {
|
||||
document.title = `${script.name} | Proxmox VE Helper-Scripts`;
|
||||
}
|
||||
} else {
|
||||
document.title = "Proxmox VE Helper-Scripts";
|
||||
}
|
||||
}, [selectedScript, links]);
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://komo.do/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apk add --no-cache ca-certificates openssl
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_info "Setup Docker Repository"
|
||||
$STD apk add --no-cache docker docker-cli docker-compose openrc
|
||||
msg_ok "Setup Docker Repository"
|
||||
|
||||
msg_info "Enabling Docker Service"
|
||||
$STD rc-update add docker boot
|
||||
$STD service docker start
|
||||
msg_ok "Enabled Docker Service"
|
||||
|
||||
echo "${TAB3}Choose the database for Komodo installation:"
|
||||
echo "${TAB3}1) MongoDB (recommended)"
|
||||
echo "${TAB3}2) FerretDB"
|
||||
read -rp "${TAB3}Enter your choice (default: 1): " DB_CHOICE
|
||||
DB_CHOICE=${DB_CHOICE:-1}
|
||||
|
||||
case $DB_CHOICE in
|
||||
1)
|
||||
DB_COMPOSE_FILE="mongo.compose.yaml"
|
||||
;;
|
||||
2)
|
||||
DB_COMPOSE_FILE="ferretdb.compose.yaml"
|
||||
;;
|
||||
*)
|
||||
echo "Invalid choice. Defaulting to MongoDB."
|
||||
DB_COMPOSE_FILE="mongo.compose.yaml"
|
||||
;;
|
||||
esac
|
||||
|
||||
mkdir -p /opt/komodo
|
||||
cd /opt/komodo
|
||||
curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/$DB_COMPOSE_FILE" -o "$(basename "$DB_COMPOSE_FILE")"
|
||||
|
||||
msg_info "Setup Komodo Environment"
|
||||
curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env" -o "/opt/komodo/compose.env"
|
||||
DB_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=')
|
||||
PASSKEY=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
WEBHOOK_SECRET=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
JWT_SECRET=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
|
||||
sed -i "s/^KOMODO_DB_USERNAME=.*/KOMODO_DB_USERNAME=komodo_admin/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_DB_PASSWORD=.*/KOMODO_DB_PASSWORD=${DB_PASSWORD}/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_PASSKEY=.*/KOMODO_PASSKEY=${PASSKEY}/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_WEBHOOK_SECRET=.*/KOMODO_WEBHOOK_SECRET=${WEBHOOK_SECRET}/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_JWT_SECRET=.*/KOMODO_JWT_SECRET=${JWT_SECRET}/" /opt/komodo/compose.env
|
||||
msg_ok "Setup Komodo Environment"
|
||||
|
||||
msg_info "Initialize Komodo"
|
||||
$STD docker compose -p komodo -f "/opt/komodo/$DB_COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||
msg_ok "Initialized Komodo"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
|
||||
msg_info "Cleaning up"
|
||||
$STD apk cache clean
|
||||
msg_ok "Cleaned"
|
||||
@@ -14,7 +14,7 @@ network_check
|
||||
update_os
|
||||
|
||||
read -r -p "${TAB3}Enter PostgreSQL version (15/16/17): " ver
|
||||
[[ $ver =~ ^(15|16|17)$ ]] || { echo "Invalid version"; exit 1; }
|
||||
[[ $ver =~ ^(15|16|17)$ ]] || { echo "Invalid version"; exit 64; }
|
||||
|
||||
msg_info "Installing PostgreSQL ${ver}"
|
||||
$STD apk add --no-cache postgresql${ver} postgresql${ver}-contrib postgresql${ver}-openrc sudo
|
||||
|
||||
@@ -25,7 +25,7 @@ case $version in
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid JDK version selected. Please enter 8, 11, 17 or 21."
|
||||
exit 1
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@@ -39,7 +39,7 @@ case $version in
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid JDK version selected. Please enter 11, 17 or 21."
|
||||
exit 1
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@@ -53,13 +53,13 @@ case $version in
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid JDK version selected. Please enter 17 or 21."
|
||||
exit 1
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid Tomcat version selected. Please enter 9, 10.1 or 11."
|
||||
exit 1
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ mkdir -p /opt/booklore/dist
|
||||
JAR_PATH=$(find /opt/booklore/booklore-api/build/libs -maxdepth 1 -type f -name "booklore-api-*.jar" ! -name "*plain*" | head -n1)
|
||||
if [[ -z "$JAR_PATH" ]]; then
|
||||
msg_error "Backend JAR not found"
|
||||
exit 1
|
||||
exit 153
|
||||
fi
|
||||
cp "$JAR_PATH" /opt/booklore/dist/app.jar
|
||||
msg_ok "Built Backend"
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://coolify.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 \
|
||||
git \
|
||||
openssl
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_warn "WARNING: This script will run an external installer from a third-party source (https://coolify.io/)."
|
||||
msg_warn "The following code is NOT maintained or audited by our repository."
|
||||
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
|
||||
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://cdn.coollabs.io/coolify/install.sh"
|
||||
echo
|
||||
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
|
||||
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
||||
msg_error "Aborted by user. No changes have been made."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Coolify (Patience - this installs Docker and pulls containers)"
|
||||
$STD bash <(curl -fsSL https://cdn.coollabs.io/coolify/install.sh)
|
||||
msg_ok "Installed Coolify"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -86,7 +86,7 @@ EOF
|
||||
msg_ok "Docker TCP socket available on $socket"
|
||||
else
|
||||
msg_error "Docker failed to restart. Check journalctl -xeu docker.service"
|
||||
exit 1
|
||||
exit 150
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://dockge.kuma.pet/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
DOCKER_LATEST_VERSION=$(get_latest_github_release "moby/moby")
|
||||
|
||||
msg_info "Installing Docker $DOCKER_LATEST_VERSION (with Compose, Buildx)"
|
||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
||||
mkdir -p $(dirname $DOCKER_CONFIG_PATH)
|
||||
echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json
|
||||
$STD sh <(curl -fsSL https://get.docker.com)
|
||||
msg_ok "Installed Docker $DOCKER_LATEST_VERSION"
|
||||
|
||||
msg_info "Installing Dockge"
|
||||
mkdir -p /opt/{dockge,stacks}
|
||||
curl -fsSL "https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml" -o "/opt/dockge/compose.yaml"
|
||||
cd /opt/dockge
|
||||
$STD docker compose up -d
|
||||
msg_ok "Installed Dockge"
|
||||
|
||||
read -r -p "${TAB3}Would you like to add Immich? <y/N> " prompt
|
||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
|
||||
msg_info "Adding Immich compose.yaml"
|
||||
mkdir -p /opt/stacks/immich
|
||||
curl -fsSL "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml" -o "/opt/stacks/immich/compose.yaml"
|
||||
curl -fsSL "https://github.com/immich-app/immich/releases/latest/download/example.env" -o "/opt/stacks/immich/.env"
|
||||
msg_ok "Added Immich compose.yaml"
|
||||
fi
|
||||
|
||||
read -r -p "${TAB3}Would you like to add Home Assistant? <y/N> " prompt
|
||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
|
||||
msg_info "Adding Home Assistant compose.yaml"
|
||||
mkdir -p /opt/stacks/homeassistant
|
||||
cat <<EOF >/opt/stacks/homeassistant/compose.yaml
|
||||
version: "3"
|
||||
services:
|
||||
homeassistant:
|
||||
container_name: homeassistant
|
||||
image: ghcr.io/home-assistant/home-assistant:stable
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /run/dbus:/run/dbus:ro
|
||||
restart: unless-stopped
|
||||
privileged: true
|
||||
network_mode: host
|
||||
EOF
|
||||
msg_ok "Added Home Assistant compose.yaml"
|
||||
fi
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://dokploy.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 \
|
||||
git \
|
||||
openssl \
|
||||
redis
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_warn "WARNING: This script will run an external installer from a third-party source (https://dokploy.com/)."
|
||||
msg_warn "The following code is NOT maintained or audited by our repository."
|
||||
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
|
||||
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://dokploy.com/install.sh"
|
||||
echo
|
||||
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
|
||||
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
||||
msg_error "Aborted by user. No changes have been made."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Dokploy (Patience - this installs Docker and pulls containers)"
|
||||
$STD bash <(curl -sSL https://dokploy.com/install.sh)
|
||||
msg_ok "Installed Dokploy"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -21,7 +21,7 @@ msg_info "Fetching latest EMQX Enterprise version"
|
||||
LATEST_VERSION=$(curl -fsSL https://www.emqx.com/en/downloads/enterprise | grep -oP '/en/downloads/enterprise/v\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n1)
|
||||
if [[ -z "$LATEST_VERSION" ]]; then
|
||||
msg_error "Failed to determine latest EMQX version"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_ok "Latest version: v$LATEST_VERSION"
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Authors: MickLesk (CanbiZ)
|
||||
# Co-Authors: remz1337
|
||||
# Authors: MickLesk (CanbiZ) | Co-Authors: remz1337
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://frigate.video/ | Github: https://github.com/blakeblackshear/frigate
|
||||
|
||||
@@ -17,7 +16,7 @@ update_os
|
||||
source /etc/os-release
|
||||
if [[ "$VERSION_ID" != "12" ]]; then
|
||||
msg_error "Frigate requires Debian 12 (Bookworm) due to Python 3.11 dependencies"
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
msg_info "Converting APT sources to DEB822 format"
|
||||
@@ -85,6 +84,7 @@ $STD apt install -y \
|
||||
tclsh \
|
||||
libopenblas-dev \
|
||||
liblapack-dev \
|
||||
libgomp1 \
|
||||
make \
|
||||
moreutils
|
||||
msg_ok "Installed Dependencies"
|
||||
@@ -101,9 +101,16 @@ export NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||
export TOKENIZERS_PARALLELISM=true
|
||||
export TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
||||
export OPENCV_FFMPEG_LOGLEVEL=8
|
||||
export PYTHONWARNINGS="ignore:::numpy.core.getlimits"
|
||||
export HAILORT_LOGGER_PATH=NONE
|
||||
export TF_CPP_MIN_LOG_LEVEL=3
|
||||
export TF_CPP_MIN_VLOG_LEVEL=3
|
||||
export TF_ENABLE_ONEDNN_OPTS=0
|
||||
export AUTOGRAPH_VERBOSITY=0
|
||||
export GLOG_minloglevel=3
|
||||
export GLOG_logtostderr=0
|
||||
|
||||
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "v0.16.4" "/opt/frigate"
|
||||
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "v0.17.0" "/opt/frigate"
|
||||
|
||||
msg_info "Building Nginx"
|
||||
$STD bash /opt/frigate/docker/main/build_nginx.sh
|
||||
@@ -138,13 +145,19 @@ install -c -m 644 libusb-1.0.pc /usr/local/lib/pkgconfig
|
||||
ldconfig
|
||||
msg_ok "Built libUSB"
|
||||
|
||||
msg_info "Bootstrapping pip"
|
||||
wget -q https://bootstrap.pypa.io/get-pip.py -O /tmp/get-pip.py
|
||||
sed -i 's/args.append("setuptools")/args.append("setuptools==77.0.3")/' /tmp/get-pip.py
|
||||
$STD python3 /tmp/get-pip.py "pip"
|
||||
rm -f /tmp/get-pip.py
|
||||
msg_ok "Bootstrapped pip"
|
||||
|
||||
msg_info "Installing Python Dependencies"
|
||||
$STD pip3 install -r /opt/frigate/docker/main/requirements.txt
|
||||
msg_ok "Installed Python Dependencies"
|
||||
|
||||
msg_info "Building Python Wheels (Patience)"
|
||||
mkdir -p /wheels
|
||||
sed -i 's|^SQLITE3_VERSION=.*|SQLITE3_VERSION="version-3.46.0"|g' /opt/frigate/docker/main/build_pysqlite3.sh
|
||||
$STD bash /opt/frigate/docker/main/build_pysqlite3.sh
|
||||
for i in {1..3}; do
|
||||
$STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt --default-timeout=300 --retries=3 && break
|
||||
@@ -152,7 +165,7 @@ for i in {1..3}; do
|
||||
done
|
||||
msg_ok "Built Python Wheels"
|
||||
|
||||
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
|
||||
NODE_VERSION="20" setup_nodejs
|
||||
|
||||
msg_info "Downloading Inference Models"
|
||||
mkdir -p /models /openvino-model
|
||||
@@ -183,6 +196,10 @@ $STD pip3 install -U /wheels/*.whl
|
||||
ldconfig
|
||||
msg_ok "Installed HailoRT Runtime"
|
||||
|
||||
msg_info "Installing MemryX Runtime"
|
||||
$STD bash /opt/frigate/docker/main/install_memryx.sh
|
||||
msg_ok "Installed MemryX Runtime"
|
||||
|
||||
msg_info "Installing OpenVino"
|
||||
$STD pip3 install -r /opt/frigate/docker/main/requirements-ov.txt
|
||||
msg_ok "Installed OpenVino"
|
||||
@@ -209,6 +226,8 @@ $STD make version
|
||||
cd /opt/frigate/web
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
mv /opt/frigate/web/dist/BASE_PATH/monacoeditorwork/* /opt/frigate/web/dist/assets/
|
||||
rm -rf /opt/frigate/web/dist/BASE_PATH
|
||||
cp -r /opt/frigate/web/dist/* /opt/frigate/web/
|
||||
sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run
|
||||
msg_ok "Built Frigate Application"
|
||||
@@ -224,6 +243,19 @@ echo "tmpfs /tmp/cache tmpfs defaults 0 0" >>/etc/fstab
|
||||
cat <<EOF >/etc/frigate.env
|
||||
DEFAULT_FFMPEG_VERSION="7.0"
|
||||
INCLUDED_FFMPEG_VERSIONS="7.0:5.0"
|
||||
NVIDIA_VISIBLE_DEVICES=all
|
||||
NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||
TOKENIZERS_PARALLELISM=true
|
||||
TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
||||
OPENCV_FFMPEG_LOGLEVEL=8
|
||||
PYTHONWARNINGS="ignore:::numpy.core.getlimits"
|
||||
HAILORT_LOGGER_PATH=NONE
|
||||
TF_CPP_MIN_LOG_LEVEL=3
|
||||
TF_CPP_MIN_VLOG_LEVEL=3
|
||||
TF_ENABLE_ONEDNN_OPTS=0
|
||||
AUTOGRAPH_VERBOSITY=0
|
||||
GLOG_minloglevel=3
|
||||
GLOG_logtostderr=0
|
||||
EOF
|
||||
|
||||
cat <<EOF >/config/config.yml
|
||||
@@ -237,7 +269,6 @@ cameras:
|
||||
input_args: -re -stream_loop -1 -fflags +genpts
|
||||
roles:
|
||||
- detect
|
||||
- rtmp
|
||||
detect:
|
||||
height: 1080
|
||||
width: 1920
|
||||
@@ -255,6 +286,7 @@ ffmpeg:
|
||||
detectors:
|
||||
detector01:
|
||||
type: openvino
|
||||
device: AUTO
|
||||
model:
|
||||
width: 300
|
||||
height: 300
|
||||
|
||||
@@ -31,7 +31,7 @@ fi
|
||||
|
||||
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
||||
msg_error "Unable to detect latest Kasm release URL."
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_ok "Detected Kasm Workspaces version $KASM_VERSION"
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://komo.do/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Setup Docker Repository"
|
||||
setup_deb822_repo \
|
||||
"docker" \
|
||||
"https://download.docker.com/linux/$(get_os_info id)/gpg" \
|
||||
"https://download.docker.com/linux/$(get_os_info id)" \
|
||||
"$(get_os_info codename)" \
|
||||
"stable" \
|
||||
"$(dpkg --print-architecture)"
|
||||
msg_ok "Setup Docker Repository"
|
||||
|
||||
msg_info "Installing Docker"
|
||||
$STD apt install -y \
|
||||
docker-ce \
|
||||
docker-ce-cli \
|
||||
containerd.io \
|
||||
docker-buildx-plugin \
|
||||
docker-compose-plugin
|
||||
msg_ok "Installed Docker"
|
||||
|
||||
echo "${TAB3}Choose the database for Komodo installation:"
|
||||
echo "${TAB3}1) MongoDB (recommended)"
|
||||
echo "${TAB3}2) FerretDB"
|
||||
read -rp "${TAB3}Enter your choice (default: 1): " DB_CHOICE
|
||||
DB_CHOICE=${DB_CHOICE:-1}
|
||||
|
||||
case $DB_CHOICE in
|
||||
1)
|
||||
DB_COMPOSE_FILE="mongo.compose.yaml"
|
||||
;;
|
||||
2)
|
||||
DB_COMPOSE_FILE="ferretdb.compose.yaml"
|
||||
;;
|
||||
*)
|
||||
echo "Invalid choice. Defaulting to MongoDB."
|
||||
DB_COMPOSE_FILE="mongo.compose.yaml"
|
||||
;;
|
||||
esac
|
||||
mkdir -p /opt/komodo
|
||||
cd /opt/komodo
|
||||
curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/$DB_COMPOSE_FILE" -o "/opt/komodo/$DB_COMPOSE_FILE"
|
||||
|
||||
msg_info "Setup Komodo Environment"
|
||||
curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env" -o "/opt/komodo/compose.env"
|
||||
DB_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=')
|
||||
ADMIN_PASSWORD=$(openssl rand -base64 8 | tr -d '/+=')
|
||||
PASSKEY=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
WEBHOOK_SECRET=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
JWT_SECRET=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
|
||||
sed -i "s/^KOMODO_DB_USERNAME=.*/KOMODO_DB_USERNAME=komodo_admin/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_DB_PASSWORD=.*/KOMODO_DB_PASSWORD=${DB_PASSWORD}/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_INIT_ADMIN_PASSWORD=changeme/KOMODO_INIT_ADMIN_PASSWORD=${ADMIN_PASSWORD}/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_PASSKEY=.*/KOMODO_PASSKEY=${PASSKEY}/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_WEBHOOK_SECRET=.*/KOMODO_WEBHOOK_SECRET=${WEBHOOK_SECRET}/" /opt/komodo/compose.env
|
||||
sed -i "s/^KOMODO_JWT_SECRET=.*/KOMODO_JWT_SECRET=${JWT_SECRET}/" /opt/komodo/compose.env
|
||||
{
|
||||
echo "Komodo Credentials"
|
||||
echo ""
|
||||
echo "Admin User : admin"
|
||||
echo "Admin Password: $ADMIN_PASSWORD"
|
||||
} >>~/komodo.creds
|
||||
msg_ok "Setup Komodo Environment"
|
||||
|
||||
msg_info "Initialize Komodo"
|
||||
$STD docker compose -p komodo -f /opt/komodo/$DB_COMPOSE_FILE --env-file /opt/komodo/compose.env up -d
|
||||
msg_ok "Initialized Komodo"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -28,7 +28,7 @@ $STD apt install -y \
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
POSTGRES_VERSION="16" setup_postgresql
|
||||
PG_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
|
||||
|
||||
@@ -51,7 +51,7 @@ while true; do
|
||||
attempts=$((attempts + 1))
|
||||
if [[ "$attempts" -ge 3 ]]; then
|
||||
msg_error "Maximum attempts reached. Exiting."
|
||||
exit 1
|
||||
exit 254
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -76,11 +76,11 @@ for i in {1..60}; do
|
||||
elif [[ "$STATUS" == "unhealthy" ]]; then
|
||||
msg_error "NPMplus container is unhealthy! Check logs."
|
||||
docker logs "$CONTAINER_ID"
|
||||
exit 1
|
||||
exit 150
|
||||
fi
|
||||
fi
|
||||
sleep 2
|
||||
[[ $i -eq 60 ]] && msg_error "NPMplus container did not become healthy within 120s." && docker logs "$CONTAINER_ID" && exit 1
|
||||
[[ $i -eq 60 ]] && msg_error "NPMplus container did not become healthy within 120s." && docker logs "$CONTAINER_ID" && exit 150
|
||||
done
|
||||
msg_ok "Builded and started NPMplus"
|
||||
|
||||
|
||||
@@ -78,11 +78,11 @@ if curl -fL# -C - -o "$TMP_TAR" "$OLLAMA_URL"; then
|
||||
msg_ok "Installed Ollama ${RELEASE}"
|
||||
else
|
||||
msg_error "Extraction failed – archive corrupt or incomplete"
|
||||
exit 1
|
||||
exit 251
|
||||
fi
|
||||
else
|
||||
msg_error "Download failed – $OLLAMA_URL not reachable"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
|
||||
msg_info "Creating ollama User and Group"
|
||||
|
||||
@@ -59,7 +59,7 @@ EOF
|
||||
else
|
||||
msg_error "Failed to download or verify GPG key from $KEY_URL"
|
||||
[[ -f "$TMP_KEY_CONTENT" ]] && rm -f "$TMP_KEY_CONTENT"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
rm -f "$TMP_KEY_CONTENT"
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ sed -i "s|^DATABASE_URL=.*|DATABASE_URL=\"postgresql://$PG_DB_USER:$PG_DB_PASS@l
|
||||
sed -i "s|^MEILI_HOST=.*|MEILI_HOST=http://localhost:7700|g" /opt/openarchiver/.env
|
||||
sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$MEILISEARCH_MASTER_KEY|g" /opt/openarchiver/.env
|
||||
sed -i "s|^REDIS_HOST=.*|REDIS_HOST=localhost|g" /opt/openarchiver/.env
|
||||
sed -i "s|^REDIS_USER=.*|REDIS_USER=|g" /opt/openarchiver/.env
|
||||
sed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=|g" /opt/openarchiver/.env
|
||||
sed -i "s|^STORAGE_LOCAL_ROOT_PATH=.*|STORAGE_LOCAL_ROOT_PATH=/opt/openarchiver-data|g" /opt/openarchiver/.env
|
||||
sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$JWT_KEY|g" /opt/openarchiver/.env
|
||||
|
||||
@@ -34,7 +34,7 @@ for server in "${servers[@]}"; do
|
||||
done
|
||||
if ((attempt >= MAX_ATTEMPTS)); then
|
||||
msg_error "No more attempts - aborting script!"
|
||||
exit 1
|
||||
exit 254
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ update_os
|
||||
read -r -p "${TAB3}Enter PostgreSQL version (15/16/17/18): " ver
|
||||
[[ $ver =~ ^(15|16|17|18)$ ]] || {
|
||||
echo "Invalid version"
|
||||
exit 1
|
||||
exit 64
|
||||
}
|
||||
PG_VERSION=$ver setup_postgresql
|
||||
|
||||
|
||||
74
install/profilarr-install.sh
Normal file
74
install/profilarr-install.sh
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: michelroegl-brunner
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/Dictionarry-Hub/profilarr
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
build-essential \
|
||||
python3-dev \
|
||||
libffi-dev \
|
||||
libssl-dev \
|
||||
git
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
|
||||
msg_info "Creating directories"
|
||||
mkdir -p /opt/profilarr \
|
||||
/config
|
||||
msg_ok "Created directories"
|
||||
|
||||
fetch_and_deploy_gh_release "profilarr" "Dictionarry-Hub/profilarr" "tarball"
|
||||
|
||||
msg_info "Installing Python Dependencies"
|
||||
cd /opt/profilarr/backend
|
||||
$STD uv venv /opt/profilarr/backend/.venv
|
||||
sed 's/==/>=/g' requirements.txt >requirements-relaxed.txt
|
||||
$STD uv pip install --python /opt/profilarr/backend/.venv/bin/python -r requirements-relaxed.txt
|
||||
rm -f requirements-relaxed.txt
|
||||
msg_ok "Installed Python Dependencies"
|
||||
|
||||
msg_info "Building Frontend"
|
||||
cd /opt/profilarr/frontend
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
cp -r dist /opt/profilarr/backend/app/static
|
||||
msg_ok "Built Frontend"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/profilarr.service
|
||||
[Unit]
|
||||
Description=Profilarr - Configuration Management Platform for Radarr/Sonarr
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/profilarr/backend
|
||||
Environment="PATH=/opt/profilarr/backend/.venv/bin:/usr/local/bin:/usr/bin:/bin"
|
||||
Environment="PYTHONPATH=/opt/profilarr/backend"
|
||||
ExecStart=/opt/profilarr/backend/.venv/bin/gunicorn --bind 0.0.0.0:6868 --timeout 600 app.main:create_app()
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now profilarr
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -25,7 +25,7 @@ if useradd -r -m -d /opt/pulse-home -s /usr/sbin/nologin pulse; then
|
||||
msg_ok "Created User"
|
||||
else
|
||||
msg_error "User creation failed"
|
||||
exit 1
|
||||
exit 71
|
||||
fi
|
||||
|
||||
mkdir -p /etc/pulse
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://runtipi.io/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_warn "WARNING: This script will run an external installer from a third-party source (https://runtipi.io/)."
|
||||
msg_warn "The following code is NOT maintained or audited by our repository."
|
||||
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
|
||||
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh"
|
||||
echo
|
||||
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
|
||||
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
||||
msg_error "Aborted by user. No changes have been made."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Runtipi (Patience)"
|
||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
||||
cd /opt
|
||||
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
|
||||
rm -f /opt/install.sh
|
||||
msg_ok "Installed Runtipi"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -17,12 +17,14 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y nginx
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="25" setup_nodejs
|
||||
PG_VERSION="18" setup_postgresql
|
||||
PG_DB_NAME="sparkyfitness" PG_DB_USER="sparky" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
||||
|
||||
fetch_and_deploy_gh_release sparkyfitness "CodeWithCJ/SparkyFitness" "tarball" "latest"
|
||||
|
||||
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1]' /opt/sparkyfitness/package.json)"
|
||||
NODE_VERSION="25" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
|
||||
|
||||
msg_info "Configuring Sparky Fitness"
|
||||
mkdir -p "/etc/sparkyfitness" "/var/lib/sparkyfitness/uploads" "/var/lib/sparkyfitness/backup" "/var/www/sparkyfitness"
|
||||
cp "/opt/sparkyfitness/docker/.env.example" "/etc/sparkyfitness/.env"
|
||||
@@ -50,8 +52,8 @@ msg_ok "Built Backend"
|
||||
|
||||
msg_info "Building Frontend (Patience)"
|
||||
cd /opt/sparkyfitness/SparkyFitnessFrontend
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
$STD pnpm install
|
||||
$STD pnpm run build
|
||||
cp -a /opt/sparkyfitness/SparkyFitnessFrontend/dist/. /var/www/sparkyfitness/
|
||||
msg_ok "Built Frontend"
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ while true; do
|
||||
[Nn]|[Nn][Oo]|"")
|
||||
msg_error "Terms not accepted. Installation cannot proceed."
|
||||
msg_error "Please review the terms and run the script again if you wish to proceed."
|
||||
exit 1
|
||||
exit 254
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid response. Please enter 'y' for yes or 'n' for no."
|
||||
@@ -47,7 +47,7 @@ DOWNLOAD_URL=$(curl -s "https://www.splunk.com/en_us/download/splunk-enterprise.
|
||||
RELEASE=$(echo "$DOWNLOAD_URL" | sed 's|.*/releases/\([^/]*\)/.*|\1|')
|
||||
$STD curl -fsSL -o "splunk-enterprise.tgz" "$DOWNLOAD_URL" || {
|
||||
msg_error "Failed to download Splunk Enterprise from the provided link."
|
||||
exit 1
|
||||
exit 250
|
||||
}
|
||||
$STD tar -xzf "splunk-enterprise.tgz" -C /opt
|
||||
rm -f "splunk-enterprise.tgz"
|
||||
|
||||
@@ -44,7 +44,20 @@ $STD timescaledb-tune -yes -memory "$ram_for_tsdb"MB
|
||||
$STD systemctl restart postgresql
|
||||
msg_ok "Installed TimescaleDB"
|
||||
|
||||
PG_DB_NAME="tracearr_db" PG_DB_USER="tracearr" PG_DB_EXTENSIONS="timescaledb,timescaledb_toolkit" setup_postgresql_db
|
||||
PG_DB_NAME="tracearr_db" PG_DB_USER="tracearr" PG_DB_EXTENSIONS="timescaledb,timescaledb_toolkit" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
||||
|
||||
msg_info "Installing tailscale"
|
||||
setup_deb822_repo \
|
||||
"tailscale" \
|
||||
"https://pkgs.tailscale.com/stable/$(get_os_info id)/$(get_os_info codename).noarmor.gpg" \
|
||||
"https://pkgs.tailscale.com/stable/$(get_os_info id)/" \
|
||||
"$(get_os_info codename)"
|
||||
$STD apt install -y tailscale
|
||||
# Tracearr runs tailscaled in user mode, disable the service.
|
||||
$STD systemctl disable --now tailscaled
|
||||
$STD systemctl stop tailscaled
|
||||
msg_ok "Installed tailscale"
|
||||
|
||||
fetch_and_deploy_gh_release "tracearr" "connorgallopo/Tracearr" "tarball" "latest" "/opt/tracearr.build"
|
||||
|
||||
msg_info "Building Tracearr"
|
||||
@@ -75,6 +88,7 @@ msg_info "Configuring Tracearr"
|
||||
$STD useradd -r -s /bin/false -U tracearr
|
||||
$STD chown -R tracearr:tracearr /opt/tracearr
|
||||
install -d -m 750 -o tracearr -g tracearr /data/tracearr
|
||||
install -d -m 750 -o tracearr -g tracearr /data/backup
|
||||
export JWT_SECRET=$(openssl rand -hex 32)
|
||||
export COOKIE_SECRET=$(openssl rand -hex 32)
|
||||
cat <<EOF >/data/tracearr/.env
|
||||
@@ -89,7 +103,6 @@ JWT_SECRET=$JWT_SECRET
|
||||
COOKIE_SECRET=$COOKIE_SECRET
|
||||
APP_VERSION=$(cat /root/.tracearr)
|
||||
#CORS_ORIGIN=http://localhost:5173
|
||||
#MOBILE_BETA_MODE=true
|
||||
EOF
|
||||
chmod 600 /data/tracearr/.env
|
||||
chown -R tracearr:tracearr /data/tracearr
|
||||
@@ -140,6 +153,7 @@ if [ -f \$pg_config_file ]; then
|
||||
fi
|
||||
fi
|
||||
systemctl restart postgresql
|
||||
sudo -u postgres psql -c "ALTER USER tracearr WITH SUPERUSER;"
|
||||
EOF
|
||||
chmod +x /data/tracearr/prestart.sh
|
||||
cat <<EOF >/lib/systemd/system/tracearr.service
|
||||
|
||||
@@ -16,13 +16,13 @@ update_os
|
||||
if [[ "${CTTYPE:-1}" != "0" ]]; then
|
||||
msg_error "UniFi OS Server requires a privileged LXC container."
|
||||
msg_error "Recreate the container with unprivileged=0."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
|
||||
if [[ ! -e /dev/net/tun ]]; then
|
||||
msg_error "Missing /dev/net/tun in container."
|
||||
msg_error "Enable TUN/TAP (var_tun=yes) or add /dev/net/tun passthrough."
|
||||
exit 1
|
||||
exit 236
|
||||
fi
|
||||
|
||||
msg_info "Installing dependencies"
|
||||
@@ -48,7 +48,7 @@ TEMP_JSON="$(mktemp)"
|
||||
if ! curl -fsSL "$API_URL" -o "$TEMP_JSON"; then
|
||||
rm -f "$TEMP_JSON"
|
||||
msg_error "Failed to fetch data from Ubiquiti API"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
LATEST=$(jq -r '
|
||||
._embedded.firmware
|
||||
@@ -62,7 +62,7 @@ UOS_URL=$(echo "$LATEST" | jq -r '._links.data.href')
|
||||
rm -f "$TEMP_JSON"
|
||||
if [[ -z "$UOS_URL" || -z "$UOS_VERSION" || "$UOS_URL" == "null" ]]; then
|
||||
msg_error "Failed to parse UniFi OS Server version or download URL"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_ok "Found UniFi OS Server ${UOS_VERSION}"
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ if gpg --verify /tmp/zerotier-install.sh >/dev/null 2>&1; then
|
||||
$STD bash /tmp/zerotier-install.sh
|
||||
else
|
||||
msg_warn "Could not verify signature of Zerotier-One install script. Exiting..."
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_ok "Setup Zerotier-One"
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ setting_up_container() {
|
||||
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then
|
||||
echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}"
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
exit 121
|
||||
fi
|
||||
msg_ok "Set up Container OS"
|
||||
msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
|
||||
@@ -99,7 +99,7 @@ network_check() {
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
exit 122
|
||||
fi
|
||||
fi
|
||||
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
|
||||
@@ -119,12 +119,12 @@ update_os() {
|
||||
local tools_content
|
||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
||||
msg_error "Failed to download tools.func"
|
||||
exit 6
|
||||
exit 115
|
||||
}
|
||||
source /dev/stdin <<<"$tools_content"
|
||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
||||
exit 6
|
||||
exit 115
|
||||
fi
|
||||
msg_ok "Updated Container OS"
|
||||
post_progress_to_api
|
||||
|
||||
@@ -124,6 +124,7 @@ detect_repo_source
|
||||
# * Generic/Shell errors (1-3, 10, 124-132, 134, 137, 139, 141, 143-146)
|
||||
# * curl/wget errors (4-8, 16, 18, 22-28, 30, 32-36, 39, 44-48, 51-52, 55-57, 59, 61, 63, 75, 78-79, 92, 95)
|
||||
# * Package manager errors (APT, DPKG: 100-102, 255)
|
||||
# * Script Validation & Setup (103-123)
|
||||
# * BSD sysexits (64-78)
|
||||
# * Systemd/Service errors (150-154)
|
||||
# * Python/pip/uv errors (160-162)
|
||||
@@ -131,7 +132,9 @@ detect_repo_source
|
||||
# * MySQL/MariaDB errors (180-183)
|
||||
# * MongoDB errors (190-193)
|
||||
# * Proxmox custom codes (200-231)
|
||||
# * Tools & Addon Scripts (232-238)
|
||||
# * Node.js/npm errors (239, 243, 245-249)
|
||||
# * Application Install/Update errors (250-254)
|
||||
# - Returns description string for given exit code
|
||||
# ------------------------------------------------------------------------------
|
||||
explain_exit_code() {
|
||||
@@ -189,6 +192,29 @@ explain_exit_code() {
|
||||
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
|
||||
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
|
||||
|
||||
# --- Script Validation & Setup (103-123) ---
|
||||
103) echo "Validation: Shell is not Bash" ;;
|
||||
104) echo "Validation: Not running as root (or invoked via sudo)" ;;
|
||||
105) echo "Validation: Proxmox VE version not supported" ;;
|
||||
106) echo "Validation: Architecture not supported (ARM / PiMox)" ;;
|
||||
107) echo "Validation: Kernel key parameters unreadable" ;;
|
||||
108) echo "Validation: Kernel key limits exceeded" ;;
|
||||
109) echo "Proxmox: No available container ID after max attempts" ;;
|
||||
110) echo "Proxmox: Failed to apply default.vars" ;;
|
||||
111) echo "Proxmox: App defaults file not available" ;;
|
||||
112) echo "Proxmox: Invalid install menu option" ;;
|
||||
113) echo "LXC: Under-provisioned — user aborted update" ;;
|
||||
114) echo "LXC: Storage too low — user aborted update" ;;
|
||||
115) echo "Download: install.func download failed or incomplete" ;;
|
||||
116) echo "Proxmox: Default bridge vmbr0 not found" ;;
|
||||
117) echo "LXC: Container did not reach running state" ;;
|
||||
118) echo "LXC: No IP assigned to container after timeout" ;;
|
||||
119) echo "Proxmox: No valid storage for rootdir content" ;;
|
||||
120) echo "Proxmox: No valid storage for vztmpl content" ;;
|
||||
121) echo "LXC: Container network not ready (no IP after retries)" ;;
|
||||
122) echo "LXC: No internet connectivity — user declined to continue" ;;
|
||||
123) echo "LXC: Local IP detection failed" ;;
|
||||
|
||||
# --- BSD sysexits.h (64-78) ---
|
||||
64) echo "Usage error (wrong arguments)" ;;
|
||||
65) echo "Data format error (bad input data)" ;;
|
||||
@@ -276,8 +302,18 @@ explain_exit_code() {
|
||||
223) echo "Proxmox: Template not available after download" ;;
|
||||
224) echo "Proxmox: PBS storage is for backups only" ;;
|
||||
225) echo "Proxmox: No template available for OS/Version" ;;
|
||||
226) echo "Proxmox: VM disk import or post-creation setup failed" ;;
|
||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||
|
||||
# --- Tools & Addon Scripts (232-238) ---
|
||||
232) echo "Tools: Wrong execution environment (run on PVE host, not inside LXC)" ;;
|
||||
233) echo "Tools: Application not installed (update prerequisite missing)" ;;
|
||||
234) echo "Tools: No LXC containers found or available" ;;
|
||||
235) echo "Tools: Backup or restore operation failed" ;;
|
||||
236) echo "Tools: Required hardware not detected" ;;
|
||||
237) echo "Tools: Dependency package installation failed" ;;
|
||||
238) echo "Tools: OS or distribution not supported for this addon" ;;
|
||||
|
||||
# --- Node.js / npm / pnpm / yarn (239-249) ---
|
||||
239) echo "npm/Node.js: Unexpected runtime error or dependency failure" ;;
|
||||
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
||||
@@ -287,6 +323,13 @@ explain_exit_code() {
|
||||
248) echo "Node.js: Invalid C++ addon / N-API failure" ;;
|
||||
249) echo "npm/pnpm/yarn: Unknown fatal error" ;;
|
||||
|
||||
# --- Application Install/Update Errors (250-254) ---
|
||||
250) echo "App: Download failed or version not determined" ;;
|
||||
251) echo "App: File extraction failed (corrupt or incomplete archive)" ;;
|
||||
252) echo "App: Required file or resource not found" ;;
|
||||
253) echo "App: Data migration required — update aborted" ;;
|
||||
254) echo "App: User declined prompt or input timed out" ;;
|
||||
|
||||
# --- DPKG ---
|
||||
255) echo "DPKG: Fatal internal error" ;;
|
||||
|
||||
@@ -350,6 +393,11 @@ get_error_text() {
|
||||
logfile="$BUILD_LOG"
|
||||
fi
|
||||
|
||||
# Try SILENT_LOGFILE as last resort (captures $STD command output)
|
||||
if [[ -z "$logfile" || ! -s "$logfile" ]] && [[ -n "${SILENT_LOGFILE:-}" && -s "${SILENT_LOGFILE}" ]]; then
|
||||
logfile="$SILENT_LOGFILE"
|
||||
fi
|
||||
|
||||
if [[ -n "$logfile" && -s "$logfile" ]]; then
|
||||
tail -n 20 "$logfile" 2>/dev/null | sed 's/\r$//' | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'
|
||||
fi
|
||||
@@ -395,6 +443,13 @@ get_full_log() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fall back to SILENT_LOGFILE (captures $STD command output)
|
||||
if [[ -z "$logfile" || ! -s "$logfile" ]]; then
|
||||
if [[ -n "${SILENT_LOGFILE:-}" && -s "${SILENT_LOGFILE}" ]]; then
|
||||
logfile="$SILENT_LOGFILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$logfile" && -s "$logfile" ]]; then
|
||||
# Strip ANSI codes, carriage returns, and anonymize IP addresses (GDPR)
|
||||
sed 's/\r$//' "$logfile" 2>/dev/null |
|
||||
@@ -833,7 +888,7 @@ post_update_to_api() {
|
||||
esac
|
||||
|
||||
# For failed/unknown status, resolve exit code and error description
|
||||
local short_error=""
|
||||
local short_error="" medium_error=""
|
||||
if [[ "$pb_status" == "failed" ]] || [[ "$pb_status" == "unknown" ]]; then
|
||||
if [[ "$raw_exit_code" =~ ^[0-9]+$ ]]; then
|
||||
exit_code="$raw_exit_code"
|
||||
@@ -853,6 +908,18 @@ post_update_to_api() {
|
||||
short_error=$(json_escape "$(explain_exit_code "$exit_code")")
|
||||
error_category=$(categorize_error "$exit_code")
|
||||
[[ -z "$error" ]] && error="Unknown error"
|
||||
|
||||
# Build medium error for attempt 2: explanation + last 100 log lines (≤16KB)
|
||||
# This is the critical middle ground between full 120KB log and generic-only description
|
||||
local medium_log=""
|
||||
medium_log=$(get_full_log 16384) || true # 16KB max
|
||||
if [[ -z "$medium_log" ]]; then
|
||||
medium_log=$(get_error_text) || true
|
||||
fi
|
||||
local medium_full
|
||||
medium_full=$(build_error_string "$exit_code" "$medium_log")
|
||||
medium_error=$(json_escape "$medium_full")
|
||||
[[ -z "$medium_error" ]] && medium_error="$short_error"
|
||||
fi
|
||||
|
||||
# Calculate duration if timer was started
|
||||
@@ -911,7 +978,7 @@ EOF
|
||||
return 0
|
||||
fi
|
||||
|
||||
# ── Attempt 2: Short error text (no full log) ──
|
||||
# ── Attempt 2: Medium error text (truncated log ≤16KB instead of full 120KB) ──
|
||||
sleep 1
|
||||
local RETRY_PAYLOAD
|
||||
RETRY_PAYLOAD=$(
|
||||
@@ -931,7 +998,7 @@ EOF
|
||||
"pve_version": "${pve_version}",
|
||||
"method": "${METHOD:-default}",
|
||||
"exit_code": ${exit_code},
|
||||
"error": "${short_error}",
|
||||
"error": "${medium_error}",
|
||||
"error_category": "${error_category}",
|
||||
"install_duration": ${duration},
|
||||
"cpu_vendor": "${cpu_vendor}",
|
||||
@@ -954,7 +1021,7 @@ EOF
|
||||
return 0
|
||||
fi
|
||||
|
||||
# ── Attempt 3: Minimal payload (bare minimum to set status) ──
|
||||
# ── Attempt 3: Minimal payload with medium error (bare minimum to set status) ──
|
||||
sleep 2
|
||||
local MINIMAL_PAYLOAD
|
||||
MINIMAL_PAYLOAD=$(
|
||||
@@ -966,7 +1033,7 @@ EOF
|
||||
"nsapp": "${NSAPP:-unknown}",
|
||||
"status": "${pb_status}",
|
||||
"exit_code": ${exit_code},
|
||||
"error": "${short_error}",
|
||||
"error": "${medium_error}",
|
||||
"error_category": "${error_category}",
|
||||
"install_duration": ${duration}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ maxkeys_check() {
|
||||
# Exit if kernel parameters are unavailable
|
||||
if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then
|
||||
msg_error "Unable to read kernel key parameters. Ensure proper permissions."
|
||||
exit 1
|
||||
exit 107
|
||||
fi
|
||||
|
||||
# Fetch key usage for user ID 100000 (typical for containers)
|
||||
@@ -148,7 +148,7 @@ maxkeys_check() {
|
||||
# Provide next steps if issues are detected
|
||||
if [[ "$failure" -eq 1 ]]; then
|
||||
msg_error "Kernel key limits exceeded - see suggestions above"
|
||||
exit 1
|
||||
exit 108
|
||||
fi
|
||||
|
||||
# Silent success - only show errors if they exist
|
||||
@@ -355,7 +355,7 @@ get_valid_container_id() {
|
||||
attempts=$((attempts + 1))
|
||||
if [[ $attempts -ge $max_attempts ]]; then
|
||||
msg_error "Could not find available container ID after $max_attempts attempts"
|
||||
exit 1
|
||||
exit 109
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -2035,7 +2035,7 @@ advanced_settings() {
|
||||
else
|
||||
whiptail --msgbox "Default bridge 'vmbr0' not found!\n\nPlease configure a network bridge in Proxmox first." 10 58
|
||||
msg_error "Default bridge 'vmbr0' not found"
|
||||
exit 1
|
||||
exit 116
|
||||
fi
|
||||
else
|
||||
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
@@ -3023,7 +3023,7 @@ install_script() {
|
||||
3 | mydefaults | MYDEFAULTS | userdefaults | USERDEFAULTS)
|
||||
default_var_settings || {
|
||||
msg_error "Failed to apply default.vars"
|
||||
exit 1
|
||||
exit 110
|
||||
}
|
||||
defaults_target="/usr/local/community-scripts/default.vars"
|
||||
break
|
||||
@@ -3040,7 +3040,7 @@ install_script() {
|
||||
break
|
||||
else
|
||||
msg_error "No App Defaults available for ${APP}"
|
||||
exit 1
|
||||
exit 111
|
||||
fi
|
||||
;;
|
||||
"$SETTINGS_OPTION" | settings | SETTINGS)
|
||||
@@ -3051,7 +3051,7 @@ install_script() {
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid option: $CHOICE"
|
||||
exit 1
|
||||
exit 112
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -3135,7 +3135,7 @@ check_container_resources() {
|
||||
read -r prompt </dev/tty
|
||||
if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then
|
||||
msg_error "Aborted: under-provisioned LXC (${current_cpu} CPU/${current_ram}MB RAM < ${var_cpu} CPU/${var_ram}MB RAM)"
|
||||
exit 1
|
||||
exit 113
|
||||
fi
|
||||
else
|
||||
echo -e ""
|
||||
@@ -3158,7 +3158,7 @@ check_container_storage() {
|
||||
read -r prompt </dev/tty
|
||||
if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Aborted: storage too low (${usage}% used)"
|
||||
exit 1
|
||||
exit 114
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -3446,7 +3446,7 @@ start() {
|
||||
3)
|
||||
clear
|
||||
exit_script
|
||||
exit
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
ensure_profile_loaded
|
||||
@@ -3556,7 +3556,7 @@ build_container() {
|
||||
export FUNCTIONS_FILE_PATH="$(curl -fsSL "$_func_url")"
|
||||
if [[ -z "$FUNCTIONS_FILE_PATH" || ${#FUNCTIONS_FILE_PATH} -lt 100 ]]; then
|
||||
msg_error "Failed to download install functions from: $_func_url"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
# Core exports for install.func
|
||||
@@ -3938,7 +3938,7 @@ EOF
|
||||
local ct_status
|
||||
ct_status=$(pct status "$CTID" 2>/dev/null || echo "unknown")
|
||||
msg_error "LXC Container did not reach running state (status: ${ct_status})"
|
||||
exit 1
|
||||
exit 117
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -3967,7 +3967,7 @@ EOF
|
||||
echo " • Verify static IP configuration (if using static IP)"
|
||||
echo " • Check Proxmox firewall rules"
|
||||
echo " • If using Tailscale: Disable MagicDNS temporarily"
|
||||
exit 1
|
||||
exit 118
|
||||
fi
|
||||
|
||||
# Verify basic connectivity (ping test)
|
||||
@@ -4094,15 +4094,8 @@ EOF'
|
||||
# that sends "configuring" status AFTER the host already reported "failed"
|
||||
export CONTAINER_INSTALLING=true
|
||||
|
||||
# Capture lxc-attach terminal output to host-side log via tee.
|
||||
# This is the ONLY reliable way to get install output when:
|
||||
# - install.func fails to load (DNS error) → no container-side logging
|
||||
# - install script crashes before logging starts
|
||||
# - $STD/silent() not used for some commands
|
||||
# PIPESTATUS[0] gets the real exit code from lxc-attach (not from tee).
|
||||
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)" 2>&1 | tee "$_LXC_CAPTURE_LOG"
|
||||
local lxc_exit=${PIPESTATUS[0]}
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"
|
||||
local lxc_exit=$?
|
||||
|
||||
unset CONTAINER_INSTALLING
|
||||
|
||||
@@ -4164,19 +4157,9 @@ EOF'
|
||||
build_log_copied=true
|
||||
fi
|
||||
|
||||
# Copy and append INSTALL_LOG from container (with timeout to prevent hangs)
|
||||
# Copy and append INSTALL_LOG from container
|
||||
local temp_install_log="/tmp/.install-temp-${SESSION_ID}.log"
|
||||
local container_log_ok=false
|
||||
if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_install_log" 2>/dev/null; then
|
||||
# Only use container log if it has meaningful content (>100 bytes)
|
||||
if [[ -s "$temp_install_log" ]] && [[ $(stat -c%s "$temp_install_log" 2>/dev/null || echo 0) -gt 100 ]]; then
|
||||
container_log_ok=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# PHASE 2: Use container-side log if available, otherwise use host-captured tee output
|
||||
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
|
||||
if [[ "$container_log_ok" == true ]]; then
|
||||
if pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_install_log" 2>/dev/null; then
|
||||
{
|
||||
echo "================================================================================"
|
||||
echo "PHASE 2: APPLICATION INSTALLATION (Container)"
|
||||
@@ -4184,24 +4167,8 @@ EOF'
|
||||
cat "$temp_install_log"
|
||||
echo ""
|
||||
} >>"$combined_log"
|
||||
rm -f "$temp_install_log"
|
||||
install_log_copied=true
|
||||
elif [[ -s "$_LXC_CAPTURE_LOG" ]]; then
|
||||
# Fallback: host-captured terminal output from lxc-attach
|
||||
# This captures everything the user saw, including errors when install.func
|
||||
# failed to load (DNS issues, etc.) and no container-side logging was set up.
|
||||
{
|
||||
echo "================================================================================"
|
||||
echo "PHASE 2: APPLICATION INSTALLATION (Container - captured from terminal)"
|
||||
echo "================================================================================"
|
||||
# Strip ANSI escape codes from terminal capture
|
||||
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' "$_LXC_CAPTURE_LOG" | sed 's/\r$//'
|
||||
echo ""
|
||||
} >>"$combined_log"
|
||||
install_log_copied=true
|
||||
fi
|
||||
rm -f "$temp_install_log"
|
||||
|
||||
if [[ "$install_log_copied" == true ]]; then
|
||||
# Point INSTALL_LOG to combined log so get_full_log() finds it
|
||||
INSTALL_LOG="$combined_log"
|
||||
fi
|
||||
@@ -4387,7 +4354,8 @@ EOF'
|
||||
echo ""
|
||||
echo -en "${YW}Select option [1-${max_option}] (default: 1, auto-remove in 60s): ${CL}"
|
||||
|
||||
if read -t 60 -r response </dev/tty; then
|
||||
local response=""
|
||||
if read -t 60 -r response; then
|
||||
case "${response:-1}" in
|
||||
1)
|
||||
# Remove container
|
||||
@@ -4474,9 +4442,8 @@ EOF'
|
||||
# Re-run install script in existing container (don't destroy/recreate)
|
||||
set +Eeuo pipefail
|
||||
trap - ERR
|
||||
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)" 2>&1 | tee "$_LXC_CAPTURE_LOG"
|
||||
local apt_retry_exit=${PIPESTATUS[0]}
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"
|
||||
local apt_retry_exit=$?
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
|
||||
@@ -4586,9 +4553,6 @@ EOF'
|
||||
exit $install_exit_code
|
||||
fi
|
||||
|
||||
# Clean up host-side capture log (not needed on success, already in combined_log on failure)
|
||||
rm -f "/tmp/.install-capture-${SESSION_ID}.log" 2>/dev/null
|
||||
|
||||
# Re-enable error handling after successful install or recovery menu completion
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
@@ -5004,11 +4968,11 @@ create_lxc_container() {
|
||||
# Storage capability check
|
||||
check_storage_support "rootdir" || {
|
||||
msg_error "No valid storage found for 'rootdir' [Container]"
|
||||
exit 1
|
||||
exit 119
|
||||
}
|
||||
check_storage_support "vztmpl" || {
|
||||
msg_error "No valid storage found for 'vztmpl' [Template]"
|
||||
exit 1
|
||||
exit 120
|
||||
}
|
||||
|
||||
# Template storage selection
|
||||
@@ -5286,7 +5250,7 @@ create_lxc_container() {
|
||||
}
|
||||
else
|
||||
msg_custom "🚫" "${YW}" "Installation cancelled"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
msg_error "No ${PCT_OSTYPE} templates available"
|
||||
|
||||
@@ -276,7 +276,7 @@ shell_check() {
|
||||
msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit 1
|
||||
exit 103
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ root_check() {
|
||||
msg_error "Please run this script as root."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit 1
|
||||
exit 104
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -325,7 +325,7 @@ pve_check() {
|
||||
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 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -333,7 +333,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.9 or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -348,7 +348,7 @@ arch_check() {
|
||||
msg_error "This script will not work with PiMox (ARM architecture detected)."
|
||||
msg_warn "Visit https://github.com/asylumexp/Proxmox for ARM64 support."
|
||||
sleep 2
|
||||
exit 1
|
||||
exit 106
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -848,7 +848,9 @@ exit_script() {
|
||||
get_header() {
|
||||
local app_name=$(echo "${APP,,}" | tr -d ' ')
|
||||
local app_type=${APP_TYPE:-ct} # Default to 'ct' if not set
|
||||
local header_url="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/${app_type}/headers/${app_name}"
|
||||
local header_dir="${app_type}"
|
||||
[[ "$app_type" == "addon" ]] && header_dir="tools"
|
||||
local header_url="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/${header_dir}/headers/${app_name}"
|
||||
local local_header_path="/usr/local/community-scripts/headers/${app_type}/${app_name}"
|
||||
|
||||
mkdir -p "$(dirname "$local_header_path")"
|
||||
@@ -930,18 +932,13 @@ is_alpine() {
|
||||
#
|
||||
# - Determines if script should run in verbose mode
|
||||
# - Checks VERBOSE and var_verbose variables
|
||||
# - Also returns true if not running in TTY (pipe/redirect scenario)
|
||||
# - Used by msg_info() to decide between spinner and static output
|
||||
# - Note: Non-TTY (pipe) scenarios are handled separately in msg_info()
|
||||
# to allow spinner output to pass through pipes (e.g. lxc-attach | tee)
|
||||
# ------------------------------------------------------------------------------
|
||||
is_verbose_mode() {
|
||||
local verbose="${VERBOSE:-${var_verbose:-no}}"
|
||||
local tty_status
|
||||
if [[ -t 2 ]]; then
|
||||
tty_status="interactive"
|
||||
else
|
||||
tty_status="not-a-tty"
|
||||
fi
|
||||
[[ "$verbose" != "no" || ! -t 2 ]]
|
||||
[[ "$verbose" != "no" ]]
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
@@ -94,6 +94,29 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
||||
100) echo "APT: Package manager error (broken packages / dependency problems)" ;;
|
||||
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
|
||||
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
|
||||
|
||||
# --- Script Validation & Setup (103-123) ---
|
||||
103) echo "Validation: Shell is not Bash" ;;
|
||||
104) echo "Validation: Not running as root (or invoked via sudo)" ;;
|
||||
105) echo "Validation: Proxmox VE version not supported" ;;
|
||||
106) echo "Validation: Architecture not supported (ARM / PiMox)" ;;
|
||||
107) echo "Validation: Kernel key parameters unreadable" ;;
|
||||
108) echo "Validation: Kernel key limits exceeded" ;;
|
||||
109) echo "Proxmox: No available container ID after max attempts" ;;
|
||||
110) echo "Proxmox: Failed to apply default.vars" ;;
|
||||
111) echo "Proxmox: App defaults file not available" ;;
|
||||
112) echo "Proxmox: Invalid install menu option" ;;
|
||||
113) echo "LXC: Under-provisioned — user aborted update" ;;
|
||||
114) echo "LXC: Storage too low — user aborted update" ;;
|
||||
115) echo "Download: install.func download failed or incomplete" ;;
|
||||
116) echo "Proxmox: Default bridge vmbr0 not found" ;;
|
||||
117) echo "LXC: Container did not reach running state" ;;
|
||||
118) echo "LXC: No IP assigned to container after timeout" ;;
|
||||
119) echo "Proxmox: No valid storage for rootdir content" ;;
|
||||
120) echo "Proxmox: No valid storage for vztmpl content" ;;
|
||||
121) echo "LXC: Container network not ready (no IP after retries)" ;;
|
||||
122) echo "LXC: No internet connectivity — user declined to continue" ;;
|
||||
123) echo "LXC: Local IP detection failed" ;;
|
||||
124) echo "Command timed out (timeout command)" ;;
|
||||
125) echo "Command failed to start (Docker daemon or execution error)" ;;
|
||||
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
||||
@@ -155,6 +178,16 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
||||
224) echo "Proxmox: PBS storage is for backups only" ;;
|
||||
225) echo "Proxmox: No template available for OS/Version" ;;
|
||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||
|
||||
# --- Tools & Addon Scripts (232-238) ---
|
||||
232) echo "Tools: Wrong execution environment (run on PVE host, not inside LXC)" ;;
|
||||
233) echo "Tools: Application not installed (update prerequisite missing)" ;;
|
||||
234) echo "Tools: No LXC containers found or available" ;;
|
||||
235) echo "Tools: Backup or restore operation failed" ;;
|
||||
236) echo "Tools: Required hardware not detected" ;;
|
||||
237) echo "Tools: Dependency package installation failed" ;;
|
||||
238) echo "Tools: OS or distribution not supported for this addon" ;;
|
||||
|
||||
239) echo "npm/Node.js: Unexpected runtime error or dependency failure" ;;
|
||||
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
||||
245) echo "Node.js: Invalid command-line option" ;;
|
||||
@@ -162,6 +195,14 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
||||
247) echo "Node.js: Fatal internal error" ;;
|
||||
248) echo "Node.js: Invalid C++ addon / N-API failure" ;;
|
||||
249) echo "npm/pnpm/yarn: Unknown fatal error" ;;
|
||||
|
||||
# --- Application Install/Update Errors (250-254) ---
|
||||
250) echo "App: Download failed or version not determined" ;;
|
||||
251) echo "App: File extraction failed (corrupt or incomplete archive)" ;;
|
||||
252) echo "App: Required file or resource not found" ;;
|
||||
253) echo "App: Data migration required — update aborted" ;;
|
||||
254) echo "App: User declined prompt or input timed out" ;;
|
||||
|
||||
255) echo "DPKG: Fatal internal error" ;;
|
||||
*) echo "Unknown error" ;;
|
||||
esac
|
||||
@@ -286,7 +327,9 @@ error_handler() {
|
||||
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
||||
fi
|
||||
|
||||
if read -t 60 -r response </dev/tty; then
|
||||
# Read user response
|
||||
local response=""
|
||||
if read -t 60 -r response; then
|
||||
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
if declare -f msg_info >/dev/null 2>&1; then
|
||||
@@ -365,10 +408,29 @@ _send_abort_telemetry() {
|
||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
||||
|
||||
# Collect last 20 log lines for error diagnosis (best-effort)
|
||||
# Collect last 200 log lines for error diagnosis (best-effort)
|
||||
# Container context has no get_full_log(), so we gather as much as possible
|
||||
local error_text=""
|
||||
local logfile=""
|
||||
if [[ -n "${INSTALL_LOG:-}" && -s "${INSTALL_LOG}" ]]; then
|
||||
error_text=$(tail -n 20 "$INSTALL_LOG" 2>/dev/null | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\\/\\\\/g; s/"/\\"/g; s/\r//g' | tr '\n' '|' | sed 's/|$//' | tr -d '\000-\010\013\014\016-\037\177') || true
|
||||
logfile="${INSTALL_LOG}"
|
||||
elif [[ -n "${SILENT_LOGFILE:-}" && -s "${SILENT_LOGFILE}" ]]; then
|
||||
logfile="${SILENT_LOGFILE}"
|
||||
fi
|
||||
|
||||
if [[ -n "$logfile" ]]; then
|
||||
error_text=$(tail -n 200 "$logfile" 2>/dev/null | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\\/\\\\/g; s/"/\\"/g; s/\r//g' | tr '\n' '|' | sed 's/|$//' | head -c 16384 | tr -d '\000-\010\013\014\016-\037\177') || true
|
||||
fi
|
||||
|
||||
# Prepend exit code explanation header (like build_error_string does on host)
|
||||
local explanation=""
|
||||
if declare -f explain_exit_code &>/dev/null; then
|
||||
explanation=$(explain_exit_code "$exit_code" 2>/dev/null) || true
|
||||
fi
|
||||
if [[ -n "$explanation" && -n "$error_text" ]]; then
|
||||
error_text="exit_code=${exit_code} | ${explanation}|---|${error_text}"
|
||||
elif [[ -n "$explanation" && -z "$error_text" ]]; then
|
||||
error_text="exit_code=${exit_code} | ${explanation}"
|
||||
fi
|
||||
|
||||
# Calculate duration if start time is available
|
||||
@@ -377,10 +439,17 @@ _send_abort_telemetry() {
|
||||
duration=$(($(date +%s) - DIAGNOSTICS_START_TIME))
|
||||
fi
|
||||
|
||||
# Categorize error if function is available (may not be in minimal container context)
|
||||
local error_category=""
|
||||
if declare -f categorize_error &>/dev/null; then
|
||||
error_category=$(categorize_error "$exit_code" 2>/dev/null) || true
|
||||
fi
|
||||
|
||||
# Build JSON payload with error context
|
||||
local payload
|
||||
payload="{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${TELEMETRY_TYPE:-lxc}\",\"nsapp\":\"${NSAPP:-${app:-unknown}}\",\"status\":\"failed\",\"exit_code\":${exit_code}"
|
||||
[[ -n "$error_text" ]] && payload="${payload},\"error\":\"${error_text}\""
|
||||
[[ -n "$error_category" ]] && payload="${payload},\"error_category\":\"${error_category}\""
|
||||
[[ -n "$duration" ]] && payload="${payload},\"duration\":${duration}"
|
||||
payload="${payload}}"
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ setting_up_container() {
|
||||
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
|
||||
exit 121
|
||||
fi
|
||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||
systemctl disable -q --now systemd-networkd-wait-online.service
|
||||
@@ -177,7 +177,7 @@ network_check() {
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
exit 122
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -242,12 +242,12 @@ EOF
|
||||
local tools_content
|
||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
||||
msg_error "Failed to download tools.func"
|
||||
exit 6
|
||||
exit 115
|
||||
}
|
||||
source /dev/stdin <<<"$tools_content"
|
||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
||||
exit 6
|
||||
exit 115
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
1029
misc/tools.func
1029
misc/tools.func
File diff suppressed because it is too large
Load Diff
@@ -244,7 +244,7 @@ curl_handler() {
|
||||
|
||||
if [[ -z "$url" ]]; then
|
||||
msg_error "no valid url or option entered for curl_handler"
|
||||
exit 1
|
||||
exit 64
|
||||
fi
|
||||
|
||||
$STD msg_info "Fetching: $url"
|
||||
@@ -273,7 +273,7 @@ curl_handler() {
|
||||
rm -f /tmp/curl_error.log
|
||||
fi
|
||||
__curl_err_handler "$exit_code" "$url" "$curl_stderr"
|
||||
exit 1 # hard exit if exit_code is not 0
|
||||
exit "$exit_code"
|
||||
fi
|
||||
|
||||
$STD printf "\r\033[K${INFO}${YW}Retry $attempt/$max_retries in ${delay}s...${CL}" >&2
|
||||
@@ -316,7 +316,7 @@ __curl_err_handler() {
|
||||
esac
|
||||
|
||||
[[ -n "$curl_msg" ]] && printf "%s\n" "$curl_msg" >&2
|
||||
exit 1
|
||||
exit "$exit_code"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -331,7 +331,7 @@ shell_check() {
|
||||
msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit
|
||||
exit 103
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -352,11 +352,11 @@ clear_line() {
|
||||
#
|
||||
# - Determines if script should run in verbose mode
|
||||
# - Checks VERBOSE and var_verbose variables
|
||||
# - Also returns true if not running in TTY (pipe/redirect scenario)
|
||||
# - Note: Non-TTY (pipe) scenarios are handled separately in msg_info()
|
||||
# ------------------------------------------------------------------------------
|
||||
is_verbose_mode() {
|
||||
local verbose="${VERBOSE:-${var_verbose:-no}}"
|
||||
[[ "$verbose" != "no" || ! -t 2 ]]
|
||||
[[ "$verbose" != "no" ]]
|
||||
}
|
||||
|
||||
### dev spinner ###
|
||||
@@ -552,7 +552,7 @@ check_root() {
|
||||
msg_error "Please run this script as root."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit
|
||||
exit 104
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -562,7 +562,7 @@ pve_check() {
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
|
||||
echo -e "Exiting..."
|
||||
sleep 2
|
||||
exit
|
||||
exit 105
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -572,21 +572,21 @@ arch_check() {
|
||||
echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
|
||||
echo -e "Exiting..."
|
||||
sleep 2
|
||||
exit
|
||||
exit 106
|
||||
fi
|
||||
}
|
||||
|
||||
exit_script() {
|
||||
clear
|
||||
echo -e "\n${CROSS}${RD}User exited script${CL}\n"
|
||||
exit
|
||||
exit 0
|
||||
}
|
||||
|
||||
check_hostname_conflict() {
|
||||
local hostname="$1"
|
||||
if qm list | awk '{print $2}' | grep -qx "$hostname"; then
|
||||
msg_error "Hostname $hostname already in use by another VM."
|
||||
exit 1
|
||||
exit 206
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ fi
|
||||
DISTRO=$(pct exec "$CTID" -- cat /etc/os-release | grep -w "ID" | cut -d'=' -f2 | tr -d '"')
|
||||
if [[ "$DISTRO" != "debian" && "$DISTRO" != "ubuntu" ]]; then
|
||||
msg "\e[1;31m Error: This script only supports Debian or Ubuntu LXC containers. Detected: $DISTRO. Aborting...\e[0m"
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf
|
||||
|
||||
@@ -32,7 +32,7 @@ header_info
|
||||
|
||||
if ! command -v pveversion &>/dev/null; then
|
||||
msg_error "This script must be run on the Proxmox VE host (not inside an LXC container)"
|
||||
exit 1
|
||||
exit 232
|
||||
fi
|
||||
|
||||
while true; do
|
||||
@@ -64,7 +64,7 @@ while [[ -z "${CTID}" ]]; do
|
||||
CTID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --radiolist \
|
||||
"\nSelect a container to add Tailscale to:\n" \
|
||||
16 $((MSG_MAX_LENGTH + 23)) 6 \
|
||||
"${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit 1
|
||||
"${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit 0
|
||||
done
|
||||
|
||||
CTID_CONFIG_PATH="/etc/pve/lxc/${CTID}.conf"
|
||||
|
||||
@@ -69,7 +69,7 @@ elif [[ -f "/etc/debian_version" ]]; then
|
||||
SERVICE_PATH="/etc/systemd/system/adguardhome-sync.service"
|
||||
else
|
||||
msg_error "Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -312,7 +312,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -87,11 +87,11 @@ function update() {
|
||||
function check_docker() {
|
||||
if ! command -v docker &>/dev/null; then
|
||||
msg_error "Docker is not installed. This script requires an existing Docker LXC. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
if ! docker compose version &>/dev/null; then
|
||||
msg_error "Docker Compose plugin is not available. Please install it before running this script. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available"
|
||||
}
|
||||
@@ -171,7 +171,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
215
tools/addon/coolify.sh
Normal file
215
tools/addon/coolify.sh
Normal file
@@ -0,0 +1,215 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://coolify.io/ | Github: https://github.com/coollabsio/coolify
|
||||
if ! command -v curl &>/dev/null; then
|
||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
apk update >/dev/null 2>&1
|
||||
apk add --no-cache curl >/dev/null 2>&1
|
||||
else
|
||||
apt-get update >/dev/null 2>&1
|
||||
apt-get install -y curl >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
||||
|
||||
# Enable error handling
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
|
||||
# ==============================================================================
|
||||
# CONFIGURATION
|
||||
# ==============================================================================
|
||||
APP="Coolify"
|
||||
APP_TYPE="addon"
|
||||
INSTALL_PATH="/data/coolify"
|
||||
DEFAULT_PORT=8000
|
||||
|
||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||
load_functions
|
||||
|
||||
# ==============================================================================
|
||||
# UNINSTALL
|
||||
# ==============================================================================
|
||||
function uninstall() {
|
||||
msg_info "Uninstalling ${APP}"
|
||||
|
||||
if command -v docker &>/dev/null; then
|
||||
msg_info "Stopping and removing Docker containers"
|
||||
cd /data/coolify/source 2>/dev/null && docker compose down --remove-orphans 2>/dev/null || true
|
||||
$STD docker stop $(docker ps -aq) 2>/dev/null || true
|
||||
$STD docker rm $(docker ps -aq) 2>/dev/null || true
|
||||
$STD docker network prune -f 2>/dev/null || true
|
||||
msg_ok "Stopped and removed Docker containers"
|
||||
fi
|
||||
|
||||
rm -rf "$INSTALL_PATH"
|
||||
msg_ok "${APP} has been uninstalled"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UPDATE
|
||||
# ==============================================================================
|
||||
function update() {
|
||||
msg_info "Updating ${APP}"
|
||||
$STD bash <(curl -fsSL https://cdn.coollabs.io/coolify/install.sh)
|
||||
msg_ok "Updated ${APP}"
|
||||
|
||||
msg_ok "Updated successfully"
|
||||
exit
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# PROXMOX HOST CHECK
|
||||
# ==============================================================================
|
||||
function check_proxmox_host() {
|
||||
if command -v pveversion &>/dev/null; then
|
||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
||||
msg_error "This should be executed inside an LXC container."
|
||||
echo ""
|
||||
echo -n "${TAB}Continue anyway? (y/N): "
|
||||
read -r confirm
|
||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Aborted. Please run this inside an LXC container."
|
||||
exit 0
|
||||
fi
|
||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# CHECK / INSTALL DOCKER
|
||||
# ==============================================================================
|
||||
function check_or_install_docker() {
|
||||
if command -v docker &>/dev/null; then
|
||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
||||
if docker compose version &>/dev/null; then
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
msg_warn "Docker is not installed."
|
||||
echo -n "${TAB}Install Docker now? (y/N): "
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
$STD apk add docker docker-cli-compose
|
||||
$STD rc-service docker start
|
||||
$STD rc-update add docker default
|
||||
else
|
||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
||||
$STD sh <(curl -fsSL https://get.docker.com)
|
||||
fi
|
||||
msg_ok "Installed Docker"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# INSTALL
|
||||
# ==============================================================================
|
||||
function install() {
|
||||
check_or_install_docker
|
||||
|
||||
msg_info "Installing dependencies"
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
$STD apk add --no-cache git openssl
|
||||
else
|
||||
$STD apt-get update
|
||||
$STD apt-get install -y git openssl
|
||||
fi
|
||||
msg_ok "Installed dependencies"
|
||||
|
||||
msg_warn "WARNING: This will run an external installer from https://coolify.io/"
|
||||
msg_warn "The following code is NOT maintained or audited by our repository."
|
||||
msg_warn "Review: https://cdn.coollabs.io/coolify/install.sh"
|
||||
echo ""
|
||||
echo -n "${TAB}Do you want to continue? (y/N): "
|
||||
read -r confirm
|
||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_info "Installing ${APP} (this installs Docker and pulls containers)"
|
||||
$STD bash <(curl -fsSL https://cdn.coollabs.io/coolify/install.sh)
|
||||
msg_ok "Installed ${APP}"
|
||||
|
||||
echo ""
|
||||
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# MAIN
|
||||
# ==============================================================================
|
||||
|
||||
# Handle type=update (called from update script)
|
||||
if [[ "${type:-}" == "update" ]]; then
|
||||
header_info
|
||||
if [[ -d "$INSTALL_PATH" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
header_info
|
||||
check_proxmox_host
|
||||
get_lxc_ip
|
||||
|
||||
# Check if already installed
|
||||
if [[ -d "$INSTALL_PATH" ]]; then
|
||||
msg_warn "${APP} is already installed."
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
||||
read -r uninstall_prompt
|
||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
uninstall
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -n "${TAB}Update ${APP}? (y/N): "
|
||||
read -r update_prompt
|
||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
update
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_warn "No action selected. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fresh installation
|
||||
msg_warn "${APP} is not installed."
|
||||
echo ""
|
||||
echo -e "${TAB}${INFO} This will install:"
|
||||
echo -e "${TAB} - Coolify (via external installer)"
|
||||
echo -e "${TAB} - Docker (if not already installed)"
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Install ${APP}? (y/N): "
|
||||
read -r install_prompt
|
||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
install
|
||||
else
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
@@ -49,7 +49,7 @@ elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
||||
SERVICE_PATH="/etc/systemd/system/copyparty.service"
|
||||
else
|
||||
msg_error "Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -318,7 +318,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -51,7 +51,7 @@ EOF
|
||||
# ==============================================================================
|
||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -183,7 +183,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
209
tools/addon/dockge.sh
Normal file
209
tools/addon/dockge.sh
Normal file
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: tteck (tteckster) | Addon: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://dockge.kuma.pet/ | Github: https://github.com/louislam/dockge
|
||||
if ! command -v curl &>/dev/null; then
|
||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
apk update >/dev/null 2>&1
|
||||
apk add --no-cache curl >/dev/null 2>&1
|
||||
else
|
||||
apt-get update >/dev/null 2>&1
|
||||
apt-get install -y curl >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
||||
|
||||
# Enable error handling
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
|
||||
# ==============================================================================
|
||||
# CONFIGURATION
|
||||
# ==============================================================================
|
||||
APP="Dockge"
|
||||
APP_TYPE="addon"
|
||||
INSTALL_PATH="/opt/dockge"
|
||||
STACKS_PATH="/opt/stacks"
|
||||
COMPOSE_FILE="${INSTALL_PATH}/compose.yaml"
|
||||
DEFAULT_PORT=5001
|
||||
|
||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||
load_functions
|
||||
|
||||
# ==============================================================================
|
||||
# UNINSTALL
|
||||
# ==============================================================================
|
||||
function uninstall() {
|
||||
msg_info "Uninstalling ${APP}"
|
||||
|
||||
if [[ -f "$COMPOSE_FILE" ]]; then
|
||||
msg_info "Stopping and removing Docker containers"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD docker compose down --remove-orphans
|
||||
msg_ok "Stopped and removed Docker containers"
|
||||
fi
|
||||
|
||||
rm -rf "$INSTALL_PATH"
|
||||
msg_ok "${APP} has been uninstalled"
|
||||
msg_warn "Stacks directory ${STACKS_PATH} was NOT removed. Delete manually if no longer needed."
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UPDATE
|
||||
# ==============================================================================
|
||||
function update() {
|
||||
msg_info "Pulling latest ${APP} image"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD docker compose pull
|
||||
msg_ok "Pulled latest image"
|
||||
|
||||
msg_info "Restarting ${APP}"
|
||||
$STD docker compose up -d --remove-orphans
|
||||
msg_ok "Restarted ${APP}"
|
||||
|
||||
msg_ok "Updated successfully"
|
||||
exit
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# PROXMOX HOST CHECK
|
||||
# ==============================================================================
|
||||
function check_proxmox_host() {
|
||||
if command -v pveversion &>/dev/null; then
|
||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
||||
msg_error "This should be executed inside an LXC container."
|
||||
echo ""
|
||||
echo -n "${TAB}Continue anyway? (y/N): "
|
||||
read -r confirm
|
||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Aborted. Please run this inside an LXC container."
|
||||
exit 0
|
||||
fi
|
||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# CHECK / INSTALL DOCKER
|
||||
# ==============================================================================
|
||||
function check_or_install_docker() {
|
||||
if command -v docker &>/dev/null; then
|
||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
||||
if docker compose version &>/dev/null; then
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
msg_warn "Docker is not installed."
|
||||
echo -n "${TAB}Install Docker now? (y/N): "
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
$STD apk add docker docker-cli-compose
|
||||
$STD rc-service docker start
|
||||
$STD rc-update add docker default
|
||||
else
|
||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
||||
$STD sh <(curl -fsSL https://get.docker.com)
|
||||
fi
|
||||
msg_ok "Installed Docker"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# INSTALL
|
||||
# ==============================================================================
|
||||
function install() {
|
||||
check_or_install_docker
|
||||
|
||||
msg_info "Creating install directories"
|
||||
mkdir -p "$INSTALL_PATH" "$STACKS_PATH"
|
||||
msg_ok "Created ${INSTALL_PATH} and ${STACKS_PATH}"
|
||||
|
||||
msg_info "Downloading Docker Compose file"
|
||||
curl -fsSL "https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml" -o "$COMPOSE_FILE"
|
||||
msg_ok "Downloaded Docker Compose file"
|
||||
|
||||
msg_info "Starting ${APP}"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD docker compose up -d
|
||||
msg_ok "Started ${APP}"
|
||||
|
||||
echo ""
|
||||
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# MAIN
|
||||
# ==============================================================================
|
||||
|
||||
# Handle type=update (called from update script)
|
||||
if [[ "${type:-}" == "update" ]]; then
|
||||
header_info
|
||||
if [[ -f "$COMPOSE_FILE" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
header_info
|
||||
check_proxmox_host
|
||||
get_lxc_ip
|
||||
|
||||
# Check if already installed
|
||||
if [[ -f "$COMPOSE_FILE" ]]; then
|
||||
msg_warn "${APP} is already installed."
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
||||
read -r uninstall_prompt
|
||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
uninstall
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -n "${TAB}Update ${APP}? (y/N): "
|
||||
read -r update_prompt
|
||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
update
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_warn "No action selected. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fresh installation
|
||||
msg_warn "${APP} is not installed."
|
||||
echo ""
|
||||
echo -e "${TAB}${INFO} This will install:"
|
||||
echo -e "${TAB} - Dockge (via Docker Compose)"
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Install ${APP}? (y/N): "
|
||||
read -r install_prompt
|
||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
install
|
||||
else
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
214
tools/addon/dokploy.sh
Normal file
214
tools/addon/dokploy.sh
Normal file
@@ -0,0 +1,214 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://dokploy.com/ | Github: https://github.com/Dokploy/dokploy
|
||||
if ! command -v curl &>/dev/null; then
|
||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
apk update >/dev/null 2>&1
|
||||
apk add --no-cache curl >/dev/null 2>&1
|
||||
else
|
||||
apt-get update >/dev/null 2>&1
|
||||
apt-get install -y curl >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
||||
|
||||
# Enable error handling
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
|
||||
# ==============================================================================
|
||||
# CONFIGURATION
|
||||
# ==============================================================================
|
||||
APP="Dokploy"
|
||||
APP_TYPE="addon"
|
||||
INSTALL_PATH="/etc/dokploy"
|
||||
DEFAULT_PORT=3000
|
||||
|
||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||
load_functions
|
||||
|
||||
# ==============================================================================
|
||||
# UNINSTALL
|
||||
# ==============================================================================
|
||||
function uninstall() {
|
||||
msg_info "Uninstalling ${APP}"
|
||||
|
||||
if command -v docker &>/dev/null; then
|
||||
msg_info "Stopping and removing Docker containers"
|
||||
$STD docker stop $(docker ps -aq) 2>/dev/null || true
|
||||
$STD docker rm $(docker ps -aq) 2>/dev/null || true
|
||||
$STD docker network prune -f 2>/dev/null || true
|
||||
msg_ok "Stopped and removed Docker containers"
|
||||
fi
|
||||
|
||||
rm -rf "$INSTALL_PATH"
|
||||
msg_ok "${APP} has been uninstalled"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UPDATE
|
||||
# ==============================================================================
|
||||
function update() {
|
||||
msg_info "Updating ${APP}"
|
||||
$STD curl -sSL https://dokploy.com/install.sh | bash -s update
|
||||
msg_ok "Updated ${APP}"
|
||||
|
||||
msg_ok "Updated successfully"
|
||||
exit
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# PROXMOX HOST CHECK
|
||||
# ==============================================================================
|
||||
function check_proxmox_host() {
|
||||
if command -v pveversion &>/dev/null; then
|
||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
||||
msg_error "This should be executed inside an LXC container."
|
||||
echo ""
|
||||
echo -n "${TAB}Continue anyway? (y/N): "
|
||||
read -r confirm
|
||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Aborted. Please run this inside an LXC container."
|
||||
exit 0
|
||||
fi
|
||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# CHECK / INSTALL DOCKER
|
||||
# ==============================================================================
|
||||
function check_or_install_docker() {
|
||||
if command -v docker &>/dev/null; then
|
||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
||||
if docker compose version &>/dev/null; then
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
msg_warn "Docker is not installed."
|
||||
echo -n "${TAB}Install Docker now? (y/N): "
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
$STD apk add docker docker-cli-compose
|
||||
$STD rc-service docker start
|
||||
$STD rc-update add docker default
|
||||
else
|
||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
||||
$STD sh <(curl -fsSL https://get.docker.com)
|
||||
fi
|
||||
msg_ok "Installed Docker"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# INSTALL
|
||||
# ==============================================================================
|
||||
function install() {
|
||||
check_or_install_docker
|
||||
|
||||
msg_info "Installing dependencies"
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
$STD apk add --no-cache git openssl
|
||||
else
|
||||
$STD apt-get update
|
||||
$STD apt-get install -y git openssl redis
|
||||
fi
|
||||
msg_ok "Installed dependencies"
|
||||
|
||||
msg_warn "WARNING: This will run an external installer from https://dokploy.com/"
|
||||
msg_warn "The following code is NOT maintained or audited by our repository."
|
||||
echo ""
|
||||
echo -n "${TAB}Do you want to continue? (y/N): "
|
||||
read -r confirm
|
||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_info "Installing ${APP} (this installs Docker and pulls containers)"
|
||||
$STD bash <(curl -sSL https://dokploy.com/install.sh)
|
||||
msg_ok "Installed ${APP}"
|
||||
|
||||
echo ""
|
||||
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# MAIN
|
||||
# ==============================================================================
|
||||
|
||||
# Handle type=update (called from update script)
|
||||
if [[ "${type:-}" == "update" ]]; then
|
||||
header_info
|
||||
if [[ -d "$INSTALL_PATH" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
header_info
|
||||
check_proxmox_host
|
||||
get_lxc_ip
|
||||
|
||||
# Check if already installed
|
||||
if [[ -d "$INSTALL_PATH" ]]; then
|
||||
msg_warn "${APP} is already installed."
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
||||
read -r uninstall_prompt
|
||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
uninstall
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -n "${TAB}Update ${APP}? (y/N): "
|
||||
read -r update_prompt
|
||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
update
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_warn "No action selected. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fresh installation
|
||||
msg_warn "${APP} is not installed."
|
||||
echo ""
|
||||
echo -e "${TAB}${INFO} This will install:"
|
||||
echo -e "${TAB} - Dokploy (via external installer)"
|
||||
echo -e "${TAB} - Docker (if not already installed)"
|
||||
echo -e "${TAB} - Redis"
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Install ${APP}? (y/N): "
|
||||
read -r install_prompt
|
||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
install
|
||||
else
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
@@ -54,7 +54,7 @@ elif [[ -f "/etc/debian_version" ]]; then
|
||||
PKG_MANAGER="apt-get install -y"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
header_info
|
||||
|
||||
@@ -52,7 +52,7 @@ elif [[ -f "/etc/debian_version" ]]; then
|
||||
PKG_MANAGER="apt-get install -y"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
header_info
|
||||
|
||||
@@ -93,7 +93,7 @@ EOF
|
||||
update_glances_debian() {
|
||||
if [[ ! -d /opt/glances/.venv ]]; then
|
||||
msg_error "$APP is not installed"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
msg_info "Updating $APP"
|
||||
cd /opt/glances
|
||||
@@ -160,7 +160,7 @@ EOF
|
||||
update_glances_alpine() {
|
||||
if [[ ! -d /opt/glances/.venv ]]; then
|
||||
msg_error "$APP is not installed"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
msg_info "Updating $APP"
|
||||
cd /opt/glances
|
||||
|
||||
@@ -52,13 +52,13 @@ EOF
|
||||
# ==============================================================================
|
||||
if [[ -f "/etc/alpine-release" ]]; then
|
||||
msg_error "Alpine is not supported for ${APP}. Use Debian."
|
||||
exit 1
|
||||
exit 238
|
||||
elif [[ -f "/etc/debian_version" ]]; then
|
||||
OS="Debian"
|
||||
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -231,7 +231,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -52,13 +52,13 @@ EOF
|
||||
# ==============================================================================
|
||||
if [[ -f "/etc/alpine-release" ]]; then
|
||||
msg_error "Alpine is not supported for ${APP}. Use Debian/Ubuntu."
|
||||
exit 1
|
||||
exit 238
|
||||
elif [[ -f "/etc/debian_version" ]]; then
|
||||
OS="Debian"
|
||||
SERVICE_PATH="/etc/systemd/system/jellystat.service"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -326,7 +326,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
293
tools/addon/komodo.sh
Normal file
293
tools/addon/komodo.sh
Normal file
@@ -0,0 +1,293 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://komo.do/ | Github: https://github.com/mbecker20/komodo
|
||||
if ! command -v curl &>/dev/null; then
|
||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||
apt-get update >/dev/null 2>&1 || apk update >/dev/null 2>&1
|
||||
apt-get install -y curl >/dev/null 2>&1 || apk add --no-cache curl >/dev/null 2>&1
|
||||
fi
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
||||
|
||||
# Enable error handling
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
|
||||
# ==============================================================================
|
||||
# CONFIGURATION
|
||||
# ==============================================================================
|
||||
APP="Komodo"
|
||||
APP_TYPE="addon"
|
||||
INSTALL_PATH="/opt/komodo"
|
||||
COMPOSE_ENV="${INSTALL_PATH}/compose.env"
|
||||
DEFAULT_PORT=9120
|
||||
|
||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||
load_functions
|
||||
|
||||
# ==============================================================================
|
||||
# HELPERS
|
||||
# ==============================================================================
|
||||
function find_compose_file() {
|
||||
COMPOSE_FILE=$(find "$INSTALL_PATH" -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||
if [[ -z "${COMPOSE_FILE:-}" ]]; then
|
||||
msg_error "No valid compose file found in ${INSTALL_PATH}!"
|
||||
exit 233
|
||||
fi
|
||||
COMPOSE_BASENAME=$(basename "$COMPOSE_FILE")
|
||||
}
|
||||
|
||||
function check_legacy_db() {
|
||||
if [[ "$COMPOSE_BASENAME" == "sqlite.compose.yaml" || "$COMPOSE_BASENAME" == "postgres.compose.yaml" ]]; then
|
||||
msg_error "Detected outdated Komodo setup using SQLite or PostgreSQL (FerretDB v1)."
|
||||
echo -e "${YW}This configuration is no longer supported since Komodo v1.18.0.${CL}"
|
||||
echo -e "${YW}Please follow the migration guide:${CL}"
|
||||
echo -e "${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/5689${CL}\n"
|
||||
exit 238
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UNINSTALL
|
||||
# ==============================================================================
|
||||
function uninstall() {
|
||||
msg_info "Uninstalling ${APP}"
|
||||
|
||||
find_compose_file
|
||||
msg_info "Stopping and removing Docker containers"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file "$COMPOSE_ENV" down --volumes --remove-orphans
|
||||
msg_ok "Stopped and removed Docker containers"
|
||||
|
||||
rm -rf "$INSTALL_PATH"
|
||||
msg_ok "${APP} has been uninstalled"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UPDATE
|
||||
# ==============================================================================
|
||||
function update() {
|
||||
find_compose_file
|
||||
check_legacy_db
|
||||
|
||||
msg_info "Updating ${APP}"
|
||||
BACKUP_FILE="${INSTALL_PATH}/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$COMPOSE_FILE" "$BACKUP_FILE" || {
|
||||
msg_error "Failed to create backup of ${COMPOSE_BASENAME}!"
|
||||
exit 235
|
||||
}
|
||||
|
||||
GITHUB_URL="https://raw.githubusercontent.com/moghtech/komodo/main/compose/${COMPOSE_BASENAME}"
|
||||
if ! curl -fsSL "$GITHUB_URL" -o "$COMPOSE_FILE"; then
|
||||
msg_error "Failed to download ${COMPOSE_BASENAME} from GitHub!"
|
||||
mv "$BACKUP_FILE" "$COMPOSE_FILE"
|
||||
exit 115
|
||||
fi
|
||||
|
||||
if ! grep -qxF 'COMPOSE_KOMODO_BACKUPS_PATH=/etc/komodo/backups' "$COMPOSE_ENV"; then
|
||||
sed -i '/^COMPOSE_KOMODO_IMAGE_TAG=latest$/a COMPOSE_KOMODO_BACKUPS_PATH=/etc/komodo/backups' "$COMPOSE_ENV"
|
||||
fi
|
||||
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file "$COMPOSE_ENV" pull
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file "$COMPOSE_ENV" up -d
|
||||
msg_ok "Updated ${APP}"
|
||||
|
||||
msg_ok "Updated successfully"
|
||||
exit
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# PROXMOX HOST CHECK
|
||||
# ==============================================================================
|
||||
function check_proxmox_host() {
|
||||
if command -v pveversion &>/dev/null; then
|
||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
||||
msg_error "This should be executed inside an LXC container."
|
||||
echo ""
|
||||
echo -n "${TAB}Continue anyway? (y/N): "
|
||||
read -r confirm
|
||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Aborted. Please run this inside an LXC container."
|
||||
exit 0
|
||||
fi
|
||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# CHECK / INSTALL DOCKER
|
||||
# ==============================================================================
|
||||
function check_or_install_docker() {
|
||||
if command -v docker &>/dev/null; then
|
||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
||||
if docker compose version &>/dev/null; then
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
msg_warn "Docker is not installed."
|
||||
echo -n "${TAB}Install Docker now? (y/N): "
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
$STD apk add docker docker-cli-compose
|
||||
$STD rc-service docker start
|
||||
$STD rc-update add docker default
|
||||
else
|
||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
||||
$STD sh <(curl -fsSL https://get.docker.com)
|
||||
fi
|
||||
msg_ok "Installed Docker"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# INSTALL
|
||||
# ==============================================================================
|
||||
function install() {
|
||||
check_or_install_docker
|
||||
|
||||
echo -e "${TAB}Choose the database for Komodo:"
|
||||
echo -e "${TAB} 1) MongoDB (recommended)"
|
||||
echo -e "${TAB} 2) FerretDB"
|
||||
echo -n "${TAB}Enter your choice (default: 1): "
|
||||
read -r DB_CHOICE
|
||||
DB_CHOICE=${DB_CHOICE:-1}
|
||||
|
||||
case $DB_CHOICE in
|
||||
1) DB_COMPOSE_FILE="mongo.compose.yaml" ;;
|
||||
2) DB_COMPOSE_FILE="ferretdb.compose.yaml" ;;
|
||||
*)
|
||||
msg_warn "Invalid choice. Defaulting to MongoDB."
|
||||
DB_COMPOSE_FILE="mongo.compose.yaml"
|
||||
;;
|
||||
esac
|
||||
|
||||
msg_info "Creating install directory"
|
||||
mkdir -p "$INSTALL_PATH"
|
||||
msg_ok "Created ${INSTALL_PATH}"
|
||||
|
||||
msg_info "Downloading Docker Compose file"
|
||||
curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/$DB_COMPOSE_FILE" -o "${INSTALL_PATH}/${DB_COMPOSE_FILE}"
|
||||
msg_ok "Downloaded ${DB_COMPOSE_FILE}"
|
||||
|
||||
msg_info "Configuring environment"
|
||||
curl -fsSL "https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env" -o "$COMPOSE_ENV"
|
||||
|
||||
DB_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=')
|
||||
ADMIN_PASSWORD=$(openssl rand -base64 8 | tr -d '/+=')
|
||||
PASSKEY=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
WEBHOOK_SECRET=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
JWT_SECRET=$(openssl rand -base64 24 | tr -d '/+=')
|
||||
|
||||
sed -i "s/^KOMODO_DB_USERNAME=.*/KOMODO_DB_USERNAME=komodo_admin/" "$COMPOSE_ENV"
|
||||
sed -i "s/^KOMODO_DB_PASSWORD=.*/KOMODO_DB_PASSWORD=${DB_PASSWORD}/" "$COMPOSE_ENV"
|
||||
sed -i "s/^KOMODO_INIT_ADMIN_PASSWORD=changeme/KOMODO_INIT_ADMIN_PASSWORD=${ADMIN_PASSWORD}/" "$COMPOSE_ENV"
|
||||
sed -i "s/^KOMODO_PASSKEY=.*/KOMODO_PASSKEY=${PASSKEY}/" "$COMPOSE_ENV"
|
||||
sed -i "s/^KOMODO_WEBHOOK_SECRET=.*/KOMODO_WEBHOOK_SECRET=${WEBHOOK_SECRET}/" "$COMPOSE_ENV"
|
||||
sed -i "s/^KOMODO_JWT_SECRET=.*/KOMODO_JWT_SECRET=${JWT_SECRET}/" "$COMPOSE_ENV"
|
||||
msg_ok "Configured environment"
|
||||
|
||||
msg_info "Starting ${APP}"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD docker compose -p komodo -f "${INSTALL_PATH}/${DB_COMPOSE_FILE}" --env-file "$COMPOSE_ENV" up -d
|
||||
msg_ok "Started ${APP}"
|
||||
|
||||
{
|
||||
echo "Komodo Credentials"
|
||||
echo ""
|
||||
echo "Admin User : admin"
|
||||
echo "Admin Password: $ADMIN_PASSWORD"
|
||||
} >>~/komodo.creds
|
||||
|
||||
echo ""
|
||||
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
|
||||
echo ""
|
||||
echo -e " Komodo Credentials"
|
||||
echo -e " =================="
|
||||
echo -e " User : admin"
|
||||
echo -e " Password: ${ADMIN_PASSWORD}"
|
||||
echo ""
|
||||
msg_info "Credentials saved to ~/komodo.creds"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# MAIN
|
||||
# ==============================================================================
|
||||
|
||||
# Handle type=update (called from update script)
|
||||
if [[ "${type:-}" == "update" ]]; then
|
||||
header_info
|
||||
COMPOSE_FILE=""
|
||||
COMPOSE_BASENAME=""
|
||||
if [[ -d "$INSTALL_PATH" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
header_info
|
||||
check_proxmox_host
|
||||
get_lxc_ip
|
||||
|
||||
# Declare variables used by find_compose_file
|
||||
COMPOSE_FILE=""
|
||||
COMPOSE_BASENAME=""
|
||||
|
||||
# Check if already installed
|
||||
if [[ -d "$INSTALL_PATH" ]]; then
|
||||
msg_warn "${APP} is already installed."
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
||||
read -r uninstall_prompt
|
||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
uninstall
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -n "${TAB}Update ${APP}? (y/N): "
|
||||
read -r update_prompt
|
||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
update
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_warn "No action selected. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fresh installation
|
||||
msg_warn "${APP} is not installed."
|
||||
echo ""
|
||||
echo -e "${TAB}${INFO} This will install:"
|
||||
echo -e "${TAB} - Komodo (via Docker Compose)"
|
||||
echo -e "${TAB} - MongoDB or FerretDB (your choice)"
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Install ${APP}? (y/N): "
|
||||
read -r install_prompt
|
||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
install
|
||||
else
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
@@ -58,7 +58,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -69,7 +69,7 @@ pve_check() {
|
||||
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–9.1.x"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -77,19 +77,19 @@ 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.9 or 9.0–9.1.x"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
detect_codename() {
|
||||
source /etc/os-release
|
||||
if [[ "$ID" != "debian" ]]; then
|
||||
msg_error "Unsupported base OS: $ID (only Proxmox VE / Debian supported)."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
CODENAME="${VERSION_CODENAME:-}"
|
||||
if [[ -z "$CODENAME" ]]; then
|
||||
msg_error "Could not detect Debian codename."
|
||||
exit 1
|
||||
exit 71
|
||||
fi
|
||||
echo "$CODENAME"
|
||||
}
|
||||
@@ -124,7 +124,7 @@ install() {
|
||||
PKG=$(get_latest_repo_pkg "$REPO_URL")
|
||||
if [[ -z "$PKG" ]]; then
|
||||
msg_error "Could not find netdata-repo package for Debian $CODENAME"
|
||||
exit 1
|
||||
exit 237
|
||||
fi
|
||||
curl -fsSL "${REPO_URL}${PKG}" -o "$PKG"
|
||||
$STD dpkg -i "$PKG"
|
||||
|
||||
@@ -36,7 +36,7 @@ SERVICE_PATH="/etc/systemd/system/nextcloud-exporter.service"
|
||||
# ==============================================================================
|
||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -170,7 +170,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "Nextcloud-Exporter is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -52,7 +52,7 @@ elif [[ -f "/etc/debian_version" ]]; then
|
||||
INSTALL_DIR="$INSTALL_DIR_DEBIAN"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
header_info
|
||||
@@ -72,7 +72,7 @@ function check_internet() {
|
||||
msg_ok "Internet connectivity OK"
|
||||
else
|
||||
msg_error "Internet connectivity or GitHub unreachable (Status $HTTP_CODE). Exiting."
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ function install_php_and_modules() {
|
||||
msg_info "Installing missing PHP packages: ${MISSING_PACKAGES[*]}"
|
||||
if ! apt-get update &>/dev/null || ! apt-get install -y "${MISSING_PACKAGES[@]}" &>/dev/null; then
|
||||
msg_error "Failed to install required PHP modules. Exiting."
|
||||
exit 1
|
||||
exit 237
|
||||
fi
|
||||
msg_ok "Installed missing PHP packages"
|
||||
else
|
||||
@@ -132,7 +132,7 @@ function install_phpmyadmin() {
|
||||
msg_info "Downloading ${TARBALL_URL}"
|
||||
if ! curl -fsSL "$TARBALL_URL" -o /tmp/phpmyadmin.tar.gz; then
|
||||
msg_error "Download failed: $TARBALL_URL"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
@@ -188,7 +188,7 @@ EOF
|
||||
msg_ok "Started PHP-FPM service: $PHP_FPM_SERVICE"
|
||||
else
|
||||
msg_error "Failed to start PHP-FPM service: $PHP_FPM_SERVICE"
|
||||
exit 1
|
||||
exit 150
|
||||
fi
|
||||
|
||||
$STD rc-service lighttpd start
|
||||
@@ -237,7 +237,7 @@ function update_phpmyadmin() {
|
||||
|
||||
if ! curl -fsSL "$TARBALL_URL" -o /tmp/phpmyadmin.tar.gz; then
|
||||
msg_error "Download failed: $TARBALL_URL"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
BACKUP_DIR="/tmp/phpmyadmin-backup-$(date +%Y%m%d-%H%M%S)"
|
||||
@@ -280,7 +280,7 @@ if is_phpmyadmin_installed; then
|
||||
;;
|
||||
*)
|
||||
echo -e "${YW}⚠️ Invalid input. Exiting.${CL}"
|
||||
exit 1
|
||||
exit 112
|
||||
;;
|
||||
esac
|
||||
else
|
||||
|
||||
@@ -41,7 +41,7 @@ elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
||||
SERVICE_PATH="/etc/systemd/system/pihole-exporter.service"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -207,7 +207,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "Pihole-Exporter is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -32,7 +32,7 @@ AUTH_TOKEN_FILE="/etc/prometheus-paperless-ngx-exporter/paperless_auth_token_fil
|
||||
# ==============================================================================
|
||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -144,7 +144,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "Prometheus-Paperless-NGX-Exporter is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -41,7 +41,7 @@ elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
||||
SERVICE_PATH="/etc/systemd/system/qbittorrent-exporter.service"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -200,7 +200,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "qBittorrent-Exporter is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
223
tools/addon/runtipi.sh
Normal file
223
tools/addon/runtipi.sh
Normal file
@@ -0,0 +1,223 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://runtipi.io/ | Github: https://github.com/runtipi/runtipi
|
||||
if ! command -v curl &>/dev/null; then
|
||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
apk update >/dev/null 2>&1
|
||||
apk add --no-cache curl >/dev/null 2>&1
|
||||
else
|
||||
apt-get update >/dev/null 2>&1
|
||||
apt-get install -y curl >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
||||
|
||||
# Enable error handling
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
|
||||
# ==============================================================================
|
||||
# CONFIGURATION
|
||||
# ==============================================================================
|
||||
APP="Runtipi"
|
||||
APP_TYPE="addon"
|
||||
INSTALL_PATH="/opt/runtipi"
|
||||
DEFAULT_PORT=80
|
||||
|
||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||
load_functions
|
||||
|
||||
# ==============================================================================
|
||||
# PROXMOX HOST CHECK
|
||||
# ==============================================================================
|
||||
function check_proxmox_host() {
|
||||
if command -v pveversion &>/dev/null; then
|
||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
||||
msg_error "This should be executed inside an LXC container."
|
||||
echo ""
|
||||
echo -n "${TAB}Continue anyway? (y/N): "
|
||||
read -r confirm
|
||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Aborted. Please run this inside an LXC container."
|
||||
exit 0
|
||||
fi
|
||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# CHECK / INSTALL DOCKER
|
||||
# ==============================================================================
|
||||
function check_or_install_docker() {
|
||||
if command -v docker &>/dev/null; then
|
||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
||||
if docker compose version &>/dev/null; then
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
msg_warn "Docker is not installed."
|
||||
echo -n "${TAB}Install Docker now? (y/N): "
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
||||
$STD sh <(curl -fsSL https://get.docker.com)
|
||||
msg_ok "Installed Docker"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UNINSTALL
|
||||
# ==============================================================================
|
||||
function uninstall() {
|
||||
msg_info "Uninstalling ${APP}"
|
||||
|
||||
if [[ -f "${INSTALL_PATH}/runtipi-cli" ]]; then
|
||||
msg_info "Stopping ${APP}"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD ./runtipi-cli stop 2>/dev/null || true
|
||||
msg_ok "Stopped ${APP}"
|
||||
fi
|
||||
|
||||
if command -v docker &>/dev/null; then
|
||||
msg_info "Removing Docker containers"
|
||||
cd "$INSTALL_PATH" 2>/dev/null && $STD docker compose down --remove-orphans 2>/dev/null || true
|
||||
msg_ok "Removed Docker containers"
|
||||
fi
|
||||
|
||||
rm -rf "$INSTALL_PATH"
|
||||
msg_ok "${APP} has been uninstalled"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# UPDATE
|
||||
# ==============================================================================
|
||||
function update() {
|
||||
msg_info "Updating ${APP}"
|
||||
cd "$INSTALL_PATH"
|
||||
$STD ./runtipi-cli update latest
|
||||
msg_ok "Updated ${APP}"
|
||||
|
||||
msg_ok "Updated successfully"
|
||||
exit
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# INSTALL
|
||||
# ==============================================================================
|
||||
function install() {
|
||||
check_or_install_docker
|
||||
|
||||
msg_info "Installing dependencies"
|
||||
$STD apt-get update
|
||||
$STD apt-get install -y openssl
|
||||
msg_ok "Installed dependencies"
|
||||
|
||||
msg_warn "WARNING: This will run an external installer from https://runtipi.io/"
|
||||
msg_warn "The following code is NOT maintained or audited by our repository."
|
||||
msg_warn "Review: https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh"
|
||||
echo ""
|
||||
echo -n "${TAB}Do you want to continue? (y/N): "
|
||||
read -r confirm
|
||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_info "Installing ${APP} (this pulls Docker containers)"
|
||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
||||
[[ ! -f "$DOCKER_CONFIG_PATH" ]] && echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
||||
cd /opt
|
||||
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
|
||||
rm -f /opt/install.sh
|
||||
msg_ok "Installed ${APP}"
|
||||
|
||||
echo ""
|
||||
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# MAIN
|
||||
# ==============================================================================
|
||||
|
||||
# Handle type=update (called from update script)
|
||||
if [[ "${type:-}" == "update" ]]; then
|
||||
header_info
|
||||
if [[ -d "$INSTALL_PATH" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
msg_error "${APP} does not support Alpine Linux. Please use a Debian or Ubuntu based LXC."
|
||||
exit 238
|
||||
fi
|
||||
|
||||
header_info
|
||||
check_proxmox_host
|
||||
get_lxc_ip
|
||||
|
||||
# Check if already installed
|
||||
if [[ -d "$INSTALL_PATH" ]]; then
|
||||
msg_warn "${APP} is already installed."
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
||||
read -r uninstall_prompt
|
||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
uninstall
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -n "${TAB}Update ${APP}? (y/N): "
|
||||
read -r update_prompt
|
||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
update
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_warn "No action selected. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fresh installation
|
||||
msg_warn "${APP} is not installed."
|
||||
echo ""
|
||||
echo -e "${TAB}${INFO} This will install:"
|
||||
echo -e "${TAB} - Runtipi (via external installer)"
|
||||
echo -e "${TAB} - Docker (if not already installed)"
|
||||
echo ""
|
||||
|
||||
echo -n "${TAB}Install ${APP}? (y/N): "
|
||||
read -r install_prompt
|
||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
install
|
||||
else
|
||||
msg_warn "Installation cancelled. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
6
tools/headers/coolify
Normal file
6
tools/headers/coolify
Normal file
@@ -0,0 +1,6 @@
|
||||
______ ___ ____
|
||||
/ ____/___ ____ / (_) __/_ __
|
||||
/ / / __ \/ __ \/ / / /_/ / / /
|
||||
/ /___/ /_/ / /_/ / / / __/ /_/ /
|
||||
\____/\____/\____/_/_/_/ \__, /
|
||||
/____/
|
||||
6
tools/headers/dockge
Normal file
6
tools/headers/dockge
Normal file
@@ -0,0 +1,6 @@
|
||||
____ __
|
||||
/ __ \____ _____/ /______ ____
|
||||
/ / / / __ \/ ___/ //_/ __ `/ _ \
|
||||
/ /_/ / /_/ / /__/ ,< / /_/ / __/
|
||||
/_____/\____/\___/_/|_|\__, /\___/
|
||||
/____/
|
||||
6
tools/headers/dokploy
Normal file
6
tools/headers/dokploy
Normal file
@@ -0,0 +1,6 @@
|
||||
____ __ __
|
||||
/ __ \____ / /______ / /___ __ __
|
||||
/ / / / __ \/ //_/ __ \/ / __ \/ / / /
|
||||
/ /_/ / /_/ / ,< / /_/ / / /_/ / /_/ /
|
||||
/_____/\____/_/|_/ .___/_/\____/\__, /
|
||||
/_/ /____/
|
||||
6
tools/headers/komodo
Normal file
6
tools/headers/komodo
Normal file
@@ -0,0 +1,6 @@
|
||||
__ __ __
|
||||
/ //_/___ ____ ___ ____ ____/ /___
|
||||
/ ,< / __ \/ __ `__ \/ __ \/ __ / __ \
|
||||
/ /| / /_/ / / / / / / /_/ / /_/ / /_/ /
|
||||
/_/ |_\____/_/ /_/ /_/\____/\__,_/\____/
|
||||
|
||||
6
tools/headers/runtipi
Normal file
6
tools/headers/runtipi
Normal file
@@ -0,0 +1,6 @@
|
||||
____ __ _ _
|
||||
/ __ \__ ______ / /_(_)___ (_)
|
||||
/ /_/ / / / / __ \/ __/ / __ \/ /
|
||||
/ _, _/ /_/ / / / / /_/ / /_/ / /
|
||||
/_/ |_|\__,_/_/ /_/\__/_/ .___/_/
|
||||
/_/
|
||||
@@ -62,7 +62,7 @@ function msg_error() {
|
||||
}
|
||||
if [ -z "$(ls -A /var/lib/docker/volumes/hass_config/_data/backups/)" ]; then
|
||||
msg_error "No backups found! \n"
|
||||
exit 1
|
||||
exit 235
|
||||
fi
|
||||
DIR=/var/lib/docker/volumes/hass_config/_data/restore
|
||||
if [ -d "$DIR" ]; then
|
||||
|
||||
@@ -62,7 +62,7 @@ function msg_error() {
|
||||
}
|
||||
if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then
|
||||
msg_error "No backups found! \n"
|
||||
exit 1
|
||||
exit 235
|
||||
fi
|
||||
DIR=/root/.homeassistant/restore
|
||||
if [ -d "$DIR" ]; then
|
||||
|
||||
@@ -39,7 +39,7 @@ ROOT_FS=$(df -Th "/" | awk 'NR==2 {print $2}')
|
||||
if [ "$ROOT_FS" != "ext4" ]; then
|
||||
whiptail --backtitle "Proxmox VE Helper Scripts" \
|
||||
--title "Warning" \
|
||||
--yesno "Root filesystem is not ext4 ($ROOT_FS).\nContinue anyway?" 12 80 || exit 1
|
||||
--yesno "Root filesystem is not ext4 ($ROOT_FS).\nContinue anyway?" 12 80 || exit 0
|
||||
fi
|
||||
|
||||
NODE=$(hostname)
|
||||
|
||||
@@ -57,7 +57,7 @@ done
|
||||
|
||||
if [ ${#kernels_to_remove[@]} -eq 0 ]; then
|
||||
echo -e "${RD}No valid selection made. Exiting.${CL}"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Confirm removal
|
||||
@@ -66,7 +66,7 @@ printf "%s\n" "${kernels_to_remove[@]}"
|
||||
read -rp "Proceed with removal? (y/n): " confirm
|
||||
if [[ "$confirm" != "y" ]]; then
|
||||
echo -e "${RD}Aborted.${CL}"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Remove kernels
|
||||
|
||||
@@ -51,7 +51,7 @@ containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}')
|
||||
|
||||
if [ -z "$containers" ]; then
|
||||
whiptail --title "LXC Container Delete" --msgbox "No LXC containers available!" 10 60
|
||||
exit 1
|
||||
exit 234
|
||||
fi
|
||||
|
||||
menu_items=("ALL" "Delete ALL containers" "OFF") # Add as first option
|
||||
@@ -72,7 +72,7 @@ CHOICES=$(whiptail --title "LXC Container Delete" \
|
||||
if [ -z "$CHOICES" ]; then
|
||||
whiptail --title "LXC Container Delete" \
|
||||
--msgbox "No containers selected!" 10 60
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
read -p "Delete containers manually or automatically? (Default: manual) m/a: " DELETE_MODE
|
||||
|
||||
@@ -47,7 +47,7 @@ function msg_warn() { echo -e "${WARN} ${YWB}${1}"; }
|
||||
# Check for root privileges
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
msg_error "Error: This script must be run as root."
|
||||
exit 1
|
||||
exit 104
|
||||
fi
|
||||
|
||||
if ! command -v ethtool >/dev/null 2>&1; then
|
||||
@@ -55,7 +55,7 @@ if ! command -v ethtool >/dev/null 2>&1; then
|
||||
apt-get update &>/dev/null
|
||||
apt-get install -y ethtool &>/dev/null || {
|
||||
msg_error "Failed to install ethtool. Exiting."
|
||||
exit 1
|
||||
exit 237
|
||||
}
|
||||
msg_ok "ethtool installed successfully"
|
||||
fi
|
||||
@@ -86,7 +86,7 @@ done
|
||||
if [ ${#INTERFACES[@]} -eq 0 ]; then
|
||||
whiptail --title "Error" --msgbox "No Intel e1000e or e1000 network interfaces found!" 10 60
|
||||
msg_error "No Intel e1000e or e1000 network interfaces found! Exiting."
|
||||
exit 1
|
||||
exit 236
|
||||
fi
|
||||
|
||||
msg_ok "Found ${BL}$COUNT${GN} Intel e1000e/e1000 interfaces"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user