mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-03-07 03:15:57 +01:00
Compare commits
135 Commits
exit_code_
...
github-act
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97ee4369bf | ||
|
|
10b47eae33 | ||
|
|
c61b0e766a | ||
|
|
9ff1d088c5 | ||
|
|
be803ced6f | ||
|
|
5949e9e32e | ||
|
|
bb3276bbbd | ||
|
|
b7a09989cb | ||
|
|
039d046649 | ||
|
|
58301651e4 | ||
|
|
b848c2d1bf | ||
|
|
9e2bb23d35 | ||
|
|
eb848fd70f | ||
|
|
176fffff0b | ||
|
|
14e13edeef | ||
|
|
4f70196444 | ||
|
|
acc715de82 | ||
|
|
5bfb5f486f | ||
|
|
6fbd785a87 | ||
|
|
75b1c63884 | ||
|
|
ad0808008a | ||
|
|
fcf75b06bf | ||
|
|
b8d47cdce3 | ||
|
|
8301f04b58 | ||
|
|
34942ac799 | ||
|
|
599f11683d | ||
|
|
55c699f841 | ||
|
|
3a7f922d90 | ||
|
|
352716319f | ||
|
|
5162f13372 | ||
|
|
cbe8cc82c6 | ||
|
|
c02010ea58 | ||
|
|
45e39b21ec | ||
|
|
7cbaf9c055 | ||
|
|
555f18d8df | ||
|
|
f915c68a4b | ||
|
|
da9ddcb382 | ||
|
|
55e6283075 | ||
|
|
e56b9dce35 | ||
|
|
363be950f0 | ||
|
|
0f1a06ca32 | ||
|
|
24957ea881 | ||
|
|
0be065bbef | ||
|
|
10118f4350 | ||
|
|
ac435455a0 | ||
|
|
929cd08718 | ||
|
|
299e7bfabe | ||
|
|
3465f053f5 | ||
|
|
18801eb4ff | ||
|
|
87e14ba12f | ||
|
|
438a519c65 | ||
|
|
572ea7c2be | ||
|
|
fc8b5af5fe | ||
|
|
554dfc5b0e | ||
|
|
4855fdb50d | ||
|
|
4dbb536922 | ||
|
|
154f46d6b8 | ||
|
|
bb8ac9696f | ||
|
|
41b5e5d8b9 | ||
|
|
e07b2325c1 | ||
|
|
8c9c85c1c7 | ||
|
|
2d38e509f0 | ||
|
|
4396108113 | ||
|
|
f82c15ca98 | ||
|
|
1a09b112b6 | ||
|
|
c70c488648 | ||
|
|
91db277446 | ||
|
|
35ce20391c | ||
|
|
783ba03e92 | ||
|
|
e344d3661c | ||
|
|
c62418069d | ||
|
|
41611d2682 | ||
|
|
cf8043a22e | ||
|
|
2521412747 | ||
|
|
199483be82 | ||
|
|
821b2b4415 | ||
|
|
866ae47dd4 | ||
|
|
fbc8133a86 | ||
|
|
7044b6e017 | ||
|
|
3ff140101d | ||
|
|
c4b6528bf0 | ||
|
|
7a85e33791 | ||
|
|
bbfffb97a5 | ||
|
|
4306b4018d | ||
|
|
3722533431 | ||
|
|
f773af17b2 | ||
|
|
56b4490554 | ||
|
|
b45842d76a | ||
|
|
ea279ace89 | ||
|
|
034061e744 | ||
|
|
dd07ba4453 | ||
|
|
380aa4bc0f | ||
|
|
aca721e9ee | ||
|
|
42e546904f | ||
|
|
4045824bf1 | ||
|
|
738cbfd1ae | ||
|
|
278c3cc2d8 | ||
|
|
14a7ac2618 | ||
|
|
a7699361c1 | ||
|
|
82a0893036 | ||
|
|
f9b59d7634 | ||
|
|
f279536eb7 | ||
|
|
8f34c7cd2e | ||
|
|
f922f669a8 | ||
|
|
2694d60faf | ||
|
|
a326994459 | ||
|
|
4c8d1ef010 | ||
|
|
86a9a0aac6 | ||
|
|
5059ed2320 | ||
|
|
df65c60fe4 | ||
|
|
cff2c90041 | ||
|
|
88d1494e46 | ||
|
|
8b62b8f3c5 | ||
|
|
cd38bc3a65 | ||
|
|
46d25645c2 | ||
|
|
3701737eff | ||
|
|
b39e296684 | ||
|
|
d8a7620c64 | ||
|
|
7d5900de18 | ||
|
|
e8b3b936df | ||
|
|
5c246310f4 | ||
|
|
bdad2cc941 | ||
|
|
f23c33fee7 | ||
|
|
5b207cf5bd | ||
|
|
f20c9e4ec9 | ||
|
|
1398ff8397 | ||
|
|
ebc3512f50 | ||
|
|
564a8136a5 | ||
|
|
00047c95b8 | ||
|
|
9849ce79a7 | ||
|
|
cea9858193 | ||
|
|
ee8ea672ef | ||
|
|
fc59910bd2 | ||
|
|
20ab7bc005 | ||
|
|
17de8e761b |
2
.github/workflows/close-new-script-prs.yml
generated
vendored
2
.github/workflows/close-new-script-prs.yml
generated
vendored
@@ -8,7 +8,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
check-new-script:
|
check-new-script:
|
||||||
if: github.repository == 'community-scripts/ProxmoxVE'
|
if: github.repository == 'community-scripts/ProxmoxVE'
|
||||||
runs-on: coolify-runner
|
runs-on: self-hosted
|
||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
contents: read
|
contents: read
|
||||||
|
|||||||
255
.github/workflows/push-json-to-pocketbase.yml
generated
vendored
Normal file
255
.github/workflows/push-json-to-pocketbase.yml
generated
vendored
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
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 authUrl = apiBase + '/collections/users/auth-with-password';
|
||||||
|
console.log('Auth URL: ' + authUrl);
|
||||||
|
const authBody = JSON.stringify({
|
||||||
|
identity: process.env.POCKETBASE_ADMIN_EMAIL,
|
||||||
|
password: process.env.POCKETBASE_ADMIN_PASSWORD
|
||||||
|
});
|
||||||
|
const authRes = await request(authUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: authBody
|
||||||
|
});
|
||||||
|
if (!authRes.ok) {
|
||||||
|
throw new Error('Auth failed. Tried: ' + authUrl + ' - Verify POST to that URL with body {"identity":"...","password":"..."} works. Response: ' + authRes.body);
|
||||||
|
}
|
||||||
|
const token = JSON.parse(authRes.body).token;
|
||||||
|
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
||||||
|
let categoryIdToName = {};
|
||||||
|
try {
|
||||||
|
const metadata = JSON.parse(fs.readFileSync('frontend/public/json/metadata.json', 'utf8'));
|
||||||
|
(metadata.categories || []).forEach(function(cat) { categoryIdToName[cat.id] = cat.name; });
|
||||||
|
} catch (e) { console.warn('Could not load metadata.json:', e.message); }
|
||||||
|
let typeValueToId = {};
|
||||||
|
let categoryNameToPbId = {};
|
||||||
|
try {
|
||||||
|
const typesRes = await request(apiBase + '/collections/z_ref_script_types/records?perPage=500', { headers: { 'Authorization': token } });
|
||||||
|
if (typesRes.ok) {
|
||||||
|
const typesData = JSON.parse(typesRes.body);
|
||||||
|
(typesData.items || []).forEach(function(item) {
|
||||||
|
if (item.type != null) typeValueToId[item.type] = item.id;
|
||||||
|
if (item.name != null) typeValueToId[item.name] = item.id;
|
||||||
|
if (item.value != null) typeValueToId[item.value] = item.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) { console.warn('Could not fetch z_ref_script_types:', e.message); }
|
||||||
|
try {
|
||||||
|
const catRes = await request(apiBase + '/collections/script_categories/records?perPage=500', { headers: { 'Authorization': token } });
|
||||||
|
if (catRes.ok) {
|
||||||
|
const catData = JSON.parse(catRes.body);
|
||||||
|
(catData.items || []).forEach(function(item) { if (item.name) categoryNameToPbId[item.name] = item.id; });
|
||||||
|
}
|
||||||
|
} catch (e) { console.warn('Could not fetch script_categories:', e.message); }
|
||||||
|
var noteTypeToId = {};
|
||||||
|
var installMethodTypeToId = {};
|
||||||
|
var osToId = {};
|
||||||
|
var osVersionToId = {};
|
||||||
|
try {
|
||||||
|
const res = await request(apiBase + '/collections/z_ref_note_types/records?perPage=500', { headers: { 'Authorization': token } });
|
||||||
|
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.type != null) noteTypeToId[item.type] = item.id; });
|
||||||
|
} catch (e) { console.warn('z_ref_note_types:', e.message); }
|
||||||
|
try {
|
||||||
|
const res = await request(apiBase + '/collections/z_ref_install_method_types/records?perPage=500', { headers: { 'Authorization': token } });
|
||||||
|
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.type != null) installMethodTypeToId[item.type] = item.id; });
|
||||||
|
} catch (e) { console.warn('z_ref_install_method_types:', e.message); }
|
||||||
|
try {
|
||||||
|
const res = await request(apiBase + '/collections/z_ref_os/records?perPage=500', { headers: { 'Authorization': token } });
|
||||||
|
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.os != null) osToId[item.os] = item.id; });
|
||||||
|
} catch (e) { console.warn('z_ref_os:', e.message); }
|
||||||
|
try {
|
||||||
|
const res = await request(apiBase + '/collections/z_ref_os_version/records?perPage=500&expand=os', { headers: { 'Authorization': token } });
|
||||||
|
if (res.ok) {
|
||||||
|
(JSON.parse(res.body).items || []).forEach(function(item) {
|
||||||
|
var osName = item.expand && item.expand.os && item.expand.os.os != null ? item.expand.os.os : null;
|
||||||
|
if (osName != null && item.version != null) osVersionToId[osName + '|' + item.version] = item.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) { console.warn('z_ref_os_version:', e.message); }
|
||||||
|
var notesCollUrl = apiBase + '/collections/script_notes/records';
|
||||||
|
var installMethodsCollUrl = apiBase + '/collections/script_install_methods/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,
|
||||||
|
is_dev: false
|
||||||
|
};
|
||||||
|
var resolvedType = typeValueToId[data.type];
|
||||||
|
if (resolvedType == null && data.type === 'ct') resolvedType = typeValueToId['lxc'];
|
||||||
|
if (resolvedType) payload.type = resolvedType;
|
||||||
|
var resolvedCats = (data.categories || []).map(function(n) { return categoryNameToPbId[categoryIdToName[n]]; }).filter(Boolean);
|
||||||
|
if (resolvedCats.length) payload.categories = resolvedCats;
|
||||||
|
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;
|
||||||
|
async function resolveNotesAndInstallMethods(scriptId) {
|
||||||
|
var noteIds = [];
|
||||||
|
for (var i = 0; i < (data.notes || []).length; i++) {
|
||||||
|
var note = data.notes[i];
|
||||||
|
var typeId = noteTypeToId[note.type];
|
||||||
|
if (typeId == null) continue;
|
||||||
|
var postRes = await request(notesCollUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ text: note.text || '', type: typeId })
|
||||||
|
});
|
||||||
|
if (postRes.ok) noteIds.push(JSON.parse(postRes.body).id);
|
||||||
|
}
|
||||||
|
var installMethodIds = [];
|
||||||
|
for (var j = 0; j < (data.install_methods || []).length; j++) {
|
||||||
|
var im = data.install_methods[j];
|
||||||
|
var typeId = installMethodTypeToId[im.type];
|
||||||
|
var res = im.resources || {};
|
||||||
|
var osId = osToId[res.os];
|
||||||
|
var osVersionKey = (res.os != null && res.version != null) ? res.os + '|' + res.version : null;
|
||||||
|
var osVersionId = osVersionKey ? osVersionToId[osVersionKey] : null;
|
||||||
|
var imBody = {
|
||||||
|
script: scriptId,
|
||||||
|
resources_cpu: res.cpu != null ? res.cpu : 0,
|
||||||
|
resources_ram: res.ram != null ? res.ram : 0,
|
||||||
|
resources_hdd: res.hdd != null ? res.hdd : 0
|
||||||
|
};
|
||||||
|
if (typeId) imBody.type = typeId;
|
||||||
|
if (osId) imBody.os = osId;
|
||||||
|
if (osVersionId) imBody.os_version = osVersionId;
|
||||||
|
var imPostRes = await request(installMethodsCollUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(imBody)
|
||||||
|
});
|
||||||
|
if (imPostRes.ok) installMethodIds.push(JSON.parse(imPostRes.body).id);
|
||||||
|
}
|
||||||
|
return { noteIds: noteIds, installMethodIds: installMethodIds };
|
||||||
|
}
|
||||||
|
if (existingId) {
|
||||||
|
var resolved = await resolveNotesAndInstallMethods(existingId);
|
||||||
|
payload.notes = resolved.noteIds;
|
||||||
|
payload.install_methods = resolved.installMethodIds;
|
||||||
|
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);
|
||||||
|
var scriptId = JSON.parse(r.body).id;
|
||||||
|
var resolved = await resolveNotesAndInstallMethods(scriptId);
|
||||||
|
var patchRes = await request(recordsUrl + '/' + scriptId, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ install_methods: resolved.installMethodIds, notes: resolved.noteIds })
|
||||||
|
});
|
||||||
|
if (!patchRes.ok) throw new Error('PATCH relations failed: ' + patchRes.body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('Done.');
|
||||||
|
})().catch(e => { console.error(e); process.exit(1); });
|
||||||
|
ENDSCRIPT
|
||||||
|
shell: bash
|
||||||
124
CHANGELOG.md
124
CHANGELOG.md
@@ -410,18 +410,142 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## 2026-03-07
|
||||||
|
|
||||||
|
## 2026-03-06
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- RustDesk Server: Fix update script [@tremor021](https://github.com/tremor021) ([#12625](https://github.com/community-scripts/ProxmoxVE/pull/12625))
|
||||||
|
- [Node-RED] Restart service after update [@Aurelien30000](https://github.com/Aurelien30000) ([#12621](https://github.com/community-scripts/ProxmoxVE/pull/12621))
|
||||||
|
- wealthfolio: update cors [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12617](https://github.com/community-scripts/ProxmoxVE/pull/12617))
|
||||||
|
- CryptPad: Better update handling [@tremor021](https://github.com/tremor021) ([#12611](https://github.com/community-scripts/ProxmoxVE/pull/12611))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- RustDesk Server: Switch to updated repository [@tremor021](https://github.com/tremor021) ([#12083](https://github.com/community-scripts/ProxmoxVE/pull/12083))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- Semaphore: Move from BoltDB to SQLite [@tremor021](https://github.com/tremor021) ([#12624](https://github.com/community-scripts/ProxmoxVE/pull/12624))
|
||||||
|
|
||||||
|
## 2026-03-05
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- ddclient ([#12587](https://github.com/community-scripts/ProxmoxVE/pull/12587))
|
||||||
|
- Netbird ([#12585](https://github.com/community-scripts/ProxmoxVE/pull/12585))
|
||||||
|
- Papra ([#12577](https://github.com/community-scripts/ProxmoxVE/pull/12577))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fluid-calendar: add build-essential to install and update dependencies [@Copilot](https://github.com/Copilot) ([#12602](https://github.com/community-scripts/ProxmoxVE/pull/12602))
|
||||||
|
- Refactor: BentoPDF [@vhsdream](https://github.com/vhsdream) ([#12597](https://github.com/community-scripts/ProxmoxVE/pull/12597))
|
||||||
|
- Tianji: Fix the bug introduced by the refactor [@tremor021](https://github.com/tremor021) ([#12564](https://github.com/community-scripts/ProxmoxVE/pull/12564))
|
||||||
|
- PowerDNS: use 'launch=' instead of 'launch+=' for gsqlite3 backend [@MickLesk](https://github.com/MickLesk) ([#12579](https://github.com/community-scripts/ProxmoxVE/pull/12579))
|
||||||
|
|
||||||
|
### 🗑️ Deleted Scripts
|
||||||
|
|
||||||
|
- Suwayomi-Server: remove due to inactivity and very low usage [@MickLesk](https://github.com/MickLesk) ([#12596](https://github.com/community-scripts/ProxmoxVE/pull/12596))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- core: add var_os / var_version to whitelist for app.vars [@MickLesk](https://github.com/MickLesk) ([#12576](https://github.com/community-scripts/ProxmoxVE/pull/12576))
|
||||||
|
|
||||||
|
## 2026-03-04
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix: gitea-mirror [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12549](https://github.com/community-scripts/ProxmoxVE/pull/12549))
|
||||||
|
- fix(immich): correct LibRaw clone URL to official upstream [@DenislavDenev](https://github.com/DenislavDenev) ([#12526](https://github.com/community-scripts/ProxmoxVE/pull/12526))
|
||||||
|
- update: stirling-pdf: java 25 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12552](https://github.com/community-scripts/ProxmoxVE/pull/12552))
|
||||||
|
- Docmost: register NoopAuditService globally when EE submodule is missing [@MickLesk](https://github.com/MickLesk) ([#12551](https://github.com/community-scripts/ProxmoxVE/pull/12551))
|
||||||
|
- jellyseer/overseer migration corrupting /usr/bin/update [@MickLesk](https://github.com/MickLesk) ([#12539](https://github.com/community-scripts/ProxmoxVE/pull/12539))
|
||||||
|
- PowerDNS: use gsqlite3 backend instead of BIND [@MickLesk](https://github.com/MickLesk) ([#12538](https://github.com/community-scripts/ProxmoxVE/pull/12538))
|
||||||
|
- addon migrations: /usr/bin/update replacement to prevent syntax error [@MickLesk](https://github.com/MickLesk) ([#12540](https://github.com/community-scripts/ProxmoxVE/pull/12540))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Fluid-Calendar: NodeJS bump [@tremor021](https://github.com/tremor021) ([#12558](https://github.com/community-scripts/ProxmoxVE/pull/12558))
|
||||||
|
- Refactor: LiteLLM [@tremor021](https://github.com/tremor021) ([#12550](https://github.com/community-scripts/ProxmoxVE/pull/12550))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- tools: fall back to distro packages for psql [@MickLesk](https://github.com/MickLesk) ([#12542](https://github.com/community-scripts/ProxmoxVE/pull/12542))
|
||||||
|
- fix: whitelist var_searchdomain and fix the handling of var_ns and va… [@tommoyer](https://github.com/tommoyer) ([#12521](https://github.com/community-scripts/ProxmoxVE/pull/12521))
|
||||||
|
|
||||||
|
## 2026-03-03
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Tinyauth: v5 Support & add Debian Version [@MickLesk](https://github.com/MickLesk) ([#12501](https://github.com/community-scripts/ProxmoxVE/pull/12501))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- cross-seed: install build-essential to resolve missing `make` error [@Copilot](https://github.com/Copilot) ([#12522](https://github.com/community-scripts/ProxmoxVE/pull/12522))
|
||||||
|
- meshcentral: increased disk space to 4GB [@MickLesk](https://github.com/MickLesk) ([#12509](https://github.com/community-scripts/ProxmoxVE/pull/12509))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- opnsense-vm: harden temp dir, bridge detection and network selection [@MickLesk](https://github.com/MickLesk) ([#12513](https://github.com/community-scripts/ProxmoxVE/pull/12513))
|
||||||
|
|
||||||
|
### 🗑️ Deleted Scripts
|
||||||
|
|
||||||
|
- Remove Unifi Network Server scripts (dead APT repo) [@Copilot](https://github.com/Copilot) ([#12500](https://github.com/community-scripts/ProxmoxVE/pull/12500))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core: recovery - add ENOSPC disk-full detection with auto-retry using * 2 hdd [@MickLesk](https://github.com/MickLesk) ([#12511](https://github.com/community-scripts/ProxmoxVE/pull/12511))
|
||||||
|
|
||||||
|
### 📚 Documentation
|
||||||
|
|
||||||
|
- Fix config_path casing in reactive-resume.json [@ScubyG](https://github.com/ScubyG) ([#12525](https://github.com/community-scripts/ProxmoxVE/pull/12525))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Revert #11534 PR that messed up search [@BramSuurdje](https://github.com/BramSuurdje) ([#12492](https://github.com/community-scripts/ProxmoxVE/pull/12492))
|
||||||
|
|
||||||
## 2026-03-02
|
## 2026-03-02
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- PowerDNS ([#12481](https://github.com/community-scripts/ProxmoxVE/pull/12481))
|
||||||
- Profilarr ([#12441](https://github.com/community-scripts/ProxmoxVE/pull/12441))
|
- Profilarr ([#12441](https://github.com/community-scripts/ProxmoxVE/pull/12441))
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 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
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
- Migrate: DokPloy, Komodo, Coolify, Dockge, Runtipi to Addons [@MickLesk](https://github.com/MickLesk) ([#12275](https://github.com/community-scripts/ProxmoxVE/pull/12275))
|
- 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
|
### 💾 Core
|
||||||
|
|
||||||
- #### ✨ New Features
|
- #### ✨ New Features
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ function update_script() {
|
|||||||
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||||
if [[ -z "$COMPOSE_FILE" ]]; then
|
if [[ -z "$COMPOSE_FILE" ]]; then
|
||||||
msg_error "No valid compose file found in /opt/komodo!"
|
msg_error "No valid compose file found in /opt/komodo!"
|
||||||
exit 1
|
exit 252
|
||||||
fi
|
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 pull
|
||||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||||
@@ -48,9 +48,11 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Migrating update function"
|
msg_info "Migrating update function"
|
||||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
TMP_UPDATE=$(mktemp)
|
||||||
|
cat <<'MIGRATION_EOF' >"$TMP_UPDATE"
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh)"
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh)"
|
||||||
MIGRATION_EOF
|
MIGRATION_EOF
|
||||||
|
mv "$TMP_UPDATE" /usr/bin/update
|
||||||
chmod +x /usr/bin/update
|
chmod +x /usr/bin/update
|
||||||
|
|
||||||
ln -sf /usr/bin/update /usr/bin/update_komodo 2>/dev/null || true
|
ln -sf /usr/bin/update /usr/bin/update_komodo 2>/dev/null || true
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ function update_script() {
|
|||||||
msg_info "Updating Node-RED"
|
msg_info "Updating Node-RED"
|
||||||
$STD npm install -g --unsafe-perm node-red
|
$STD npm install -g --unsafe-perm node-red
|
||||||
msg_ok "Updated Node-RED"
|
msg_ok "Updated Node-RED"
|
||||||
|
|
||||||
|
msg_info "Restarting Node-RED"
|
||||||
|
$STD rc-service nodered restart
|
||||||
|
msg_ok "Restarted Node-RED"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,21 +27,21 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
RELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
||||||
if [ "${RELEASE}" != "$(cat ~/.rustdesk-server 2>/dev/null)" ] || [ ! -f ~/.rustdesk-server ]; then
|
if [ "${RELEASE}" != "$(cat ~/.rustdesk-server 2>/dev/null)" ] || [ ! -f ~/.rustdesk-server ]; then
|
||||||
msg_info "Updating RustDesk Server to v${RELEASE}"
|
msg_info "Updating RustDesk Server to v${RELEASE}"
|
||||||
$STD apk -U upgrade
|
$STD apk -U upgrade
|
||||||
$STD service rustdesk-server-hbbs stop
|
$STD service rustdesk-server-hbbs stop
|
||||||
$STD service rustdesk-server-hbbr stop
|
$STD service rustdesk-server-hbbr stop
|
||||||
temp_file1=$(mktemp)
|
temp_file1=$(mktemp)
|
||||||
curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
|
curl -fsSL "https://github.com/lejianwen/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
|
||||||
$STD unzip "$temp_file1"
|
$STD unzip "$temp_file1"
|
||||||
cp -r amd64/* /opt/rustdesk-server/
|
cp -r amd64/* /opt/rustdesk-server/
|
||||||
echo "${RELEASE}" >~/.rustdesk-server
|
echo "${RELEASE}" >~/.rustdesk-server
|
||||||
$STD service rustdesk-server-hbbs start
|
$STD service rustdesk-server-hbbs start
|
||||||
$STD service rustdesk-server-hbbr start
|
$STD service rustdesk-server-hbbr start
|
||||||
rm -rf amd64
|
rm -rf amd64
|
||||||
rm -f $temp_file1
|
rm -f "$temp_file1"
|
||||||
msg_ok "Updated RustDesk Server"
|
msg_ok "Updated RustDesk Server"
|
||||||
else
|
else
|
||||||
msg_ok "No update required. ${APP} is already at v${RELEASE}"
|
msg_ok "No update required. ${APP} is already at v${RELEASE}"
|
||||||
@@ -56,7 +56,7 @@ function update_script() {
|
|||||||
echo "${APIRELEASE}" >~/.rustdesk-api
|
echo "${APIRELEASE}" >~/.rustdesk-api
|
||||||
$STD service rustdesk-api start
|
$STD service rustdesk-api start
|
||||||
rm -rf release
|
rm -rf release
|
||||||
rm -f $temp_file2
|
rm -f "$temp_file2"
|
||||||
msg_ok "Updated RustDesk API"
|
msg_ok "Updated RustDesk API"
|
||||||
else
|
else
|
||||||
msg_ok "No update required. RustDesk API is already at v${APIRELEASE}"
|
msg_ok "No update required. RustDesk API is already at v${APIRELEASE}"
|
||||||
|
|||||||
@@ -35,6 +35,20 @@ function update_script() {
|
|||||||
$STD service tinyauth stop
|
$STD service tinyauth stop
|
||||||
msg_ok "Service Stopped"
|
msg_ok "Service Stopped"
|
||||||
|
|
||||||
|
if [[ -f /opt/tinyauth/.env ]] && ! grep -q "^TINYAUTH_" /opt/tinyauth/.env; then
|
||||||
|
msg_info "Migrating .env to v5 format"
|
||||||
|
sed -i \
|
||||||
|
-e 's/^DATABASE_PATH=/TINYAUTH_DATABASE_PATH=/' \
|
||||||
|
-e 's/^USERS=/TINYAUTH_AUTH_USERS=/' \
|
||||||
|
-e "s/^USERS='/TINYAUTH_AUTH_USERS='/" \
|
||||||
|
-e 's/^APP_URL=/TINYAUTH_APPURL=/' \
|
||||||
|
-e 's/^SECRET=/TINYAUTH_AUTH_SECRET=/' \
|
||||||
|
-e 's/^PORT=/TINYAUTH_SERVER_PORT=/' \
|
||||||
|
-e 's/^ADDRESS=/TINYAUTH_SERVER_ADDRESS=/' \
|
||||||
|
/opt/tinyauth/.env
|
||||||
|
msg_ok "Migrated .env to v5 format"
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Updating Tinyauth"
|
msg_info "Updating Tinyauth"
|
||||||
rm -f /opt/tinyauth/tinyauth
|
rm -f /opt/tinyauth/tinyauth
|
||||||
curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth
|
curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
APP="BentoPDF"
|
APP="BentoPDF"
|
||||||
var_tags="${var_tags:-pdf-editor}"
|
var_tags="${var_tags:-pdf-editor}"
|
||||||
var_cpu="${var_cpu:-1}"
|
var_cpu="${var_cpu:-2}"
|
||||||
var_ram="${var_ram:-4096}"
|
var_ram="${var_ram:-4096}"
|
||||||
var_disk="${var_disk:-4}"
|
var_disk="${var_disk:-4}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
@@ -35,16 +35,32 @@ function update_script() {
|
|||||||
systemctl stop bentopdf
|
systemctl stop bentopdf
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
[[ -f /opt/bentopdf/.env.production ]] && cp /opt/bentopdf/.env.production /opt/production.env
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bentopdf" "alam00000/bentopdf" "tarball" "latest" "/opt/bentopdf"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bentopdf" "alam00000/bentopdf" "tarball" "latest" "/opt/bentopdf"
|
||||||
|
|
||||||
msg_info "Updating BentoPDF"
|
msg_info "Updating BentoPDF"
|
||||||
cd /opt/bentopdf
|
cd /opt/bentopdf
|
||||||
$STD npm ci --no-audit --no-fund
|
$STD npm ci --no-audit --no-fund
|
||||||
|
$STD npm install http-server -g
|
||||||
|
if [[ -f /opt/production.env ]]; then
|
||||||
|
mv /opt/production.env ./.env.production
|
||||||
|
else
|
||||||
|
cp ./.env.example ./.env.production
|
||||||
|
fi
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=3072"
|
||||||
export SIMPLE_MODE=true
|
export SIMPLE_MODE=true
|
||||||
$STD npm run build -- --mode production
|
export VITE_USE_CDN=true
|
||||||
|
$STD npm run build:all
|
||||||
msg_ok "Updated BentoPDF"
|
msg_ok "Updated BentoPDF"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
if grep -q '8080' /etc/systemd/system/bentopdf.service; then
|
||||||
|
sed -i -e 's|/bentopdf|/bentopdf/dist|' \
|
||||||
|
-e 's|npx.*|npx http-server -g -b -d false -r --no-dotfiles|' \
|
||||||
|
/etc/systemd/system/bentopdf.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
fi
|
||||||
systemctl start bentopdf
|
systemctl start bentopdf
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
|||||||
@@ -46,9 +46,11 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Migrating update function"
|
msg_info "Migrating update function"
|
||||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
TMP_UPDATE=$(mktemp)
|
||||||
|
cat <<'MIGRATION_EOF' >"$TMP_UPDATE"
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/coolify.sh)"
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/coolify.sh)"
|
||||||
MIGRATION_EOF
|
MIGRATION_EOF
|
||||||
|
mv "$TMP_UPDATE" /usr/bin/update
|
||||||
chmod +x /usr/bin/update
|
chmod +x /usr/bin/update
|
||||||
|
|
||||||
ln -sf /usr/bin/update /usr/bin/update_coolify 2>/dev/null || true
|
ln -sf /usr/bin/update /usr/bin/update_coolify 2>/dev/null || true
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ function update_script() {
|
|||||||
check_container_resources
|
check_container_resources
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
ensure_dependencies build-essential
|
||||||
|
|
||||||
if command -v cross-seed &>/dev/null; then
|
if command -v cross-seed &>/dev/null; then
|
||||||
current_version=$(cross-seed --version)
|
current_version=$(cross-seed --version)
|
||||||
|
|||||||
@@ -33,17 +33,23 @@ function update_script() {
|
|||||||
systemctl stop cryptpad
|
systemctl stop cryptpad
|
||||||
msg_info "Stopped Service"
|
msg_info "Stopped Service"
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
msg_info "Creating backup"
|
||||||
[ -f /opt/cryptpad/config/config.js ] && mv /opt/cryptpad/config/config.js /opt/
|
[ -f /opt/cryptpad/config/config.js ] && mv /opt/cryptpad/config/config.js /opt/
|
||||||
msg_ok "Backed up configuration"
|
for dir in blob block customize data datastore www/common/onlyoffice/dist onlyoffice-conf; do
|
||||||
|
[ -d "/opt/cryptpad/${dir}" ] && mv "/opt/cryptpad/${dir}" "/tmp/cryptpad_${dir//\//_}"
|
||||||
|
done
|
||||||
|
msg_ok "Created backup"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cryptpad" "cryptpad/cryptpad" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cryptpad" "cryptpad/cryptpad" "tarball"
|
||||||
|
|
||||||
msg_info "Restoring configuration"
|
msg_info "Restoring backup"
|
||||||
mv /opt/config.js /opt/cryptpad/config/
|
mv /opt/config.js /opt/cryptpad/config/
|
||||||
msg_ok "Configuration restored"
|
for dir in blob block customize data datastore www/common/onlyoffice/dist onlyoffice-conf; do
|
||||||
|
[ -d "/tmp/cryptpad_${dir//\//_}" ] && mv "/tmp/cryptpad_${dir//\//_}" "/opt/cryptpad/${dir}"
|
||||||
|
done
|
||||||
|
msg_ok "Restored backup"
|
||||||
|
|
||||||
msg_info "Updating CryptaPad"
|
msg_info "Updating CryptPad"
|
||||||
cd /opt/cryptpad
|
cd /opt/cryptpad
|
||||||
$STD npm ci
|
$STD npm ci
|
||||||
$STD npm run install:components
|
$STD npm run install:components
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2026 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://ui.com/download/unifi
|
|
||||||
|
|
||||||
APP="Unifi"
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
var_tags="${var_tags:-network;unifi}"
|
# Author: mitchscobell
|
||||||
var_cpu="${var_cpu:-2}"
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
var_ram="${var_ram:-2048}"
|
# Source: https://ddclient.net/
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
|
APP="ddclient"
|
||||||
|
var_tags="${var_tags:-network}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-512}"
|
||||||
|
var_disk="${var_disk:-2}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-12}"
|
var_version="${var_version:-13}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
header_info "$APP"
|
header_info "$APP"
|
||||||
@@ -23,16 +24,16 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
check_container_storage
|
check_container_storage
|
||||||
check_container_resources
|
check_container_resources
|
||||||
if [[ ! -d /usr/lib/unifi ]]; then
|
if [[ ! -f /etc/ddclient.conf ]]; then
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
JAVA_VERSION="21" setup_java
|
msg_info "Updating ddclient"
|
||||||
|
$STD apt update
|
||||||
msg_info "Updating ${APP}"
|
$STD apt install --only-upgrade -y ddclient
|
||||||
$STD apt update --allow-releaseinfo-change
|
$STD systemctl restart ddclient
|
||||||
ensure_dependencies unifi
|
msg_ok "Updated ddclient"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
@@ -43,5 +44,3 @@ description
|
|||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8443${CL}"
|
|
||||||
@@ -48,9 +48,11 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Migrating update function"
|
msg_info "Migrating update function"
|
||||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
TMP_UPDATE=$(mktemp)
|
||||||
|
cat <<'MIGRATION_EOF' >"$TMP_UPDATE"
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dockge.sh)"
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dockge.sh)"
|
||||||
MIGRATION_EOF
|
MIGRATION_EOF
|
||||||
|
mv "$TMP_UPDATE" /usr/bin/update
|
||||||
chmod +x /usr/bin/update
|
chmod +x /usr/bin/update
|
||||||
|
|
||||||
ln -sf /usr/bin/update /usr/bin/update_dockge 2>/dev/null || true
|
ln -sf /usr/bin/update /usr/bin/update_dockge 2>/dev/null || true
|
||||||
|
|||||||
@@ -48,6 +48,17 @@ function update_script() {
|
|||||||
cd /opt/docmost
|
cd /opt/docmost
|
||||||
mv /opt/.env /opt/docmost/.env
|
mv /opt/.env /opt/docmost/.env
|
||||||
mv /opt/data /opt/docmost/data
|
mv /opt/data /opt/docmost/data
|
||||||
|
|
||||||
|
# Fix: Docmost EE (audit logs etc.) lives in a git submodule that is NOT
|
||||||
|
# included in GitHub tarballs. The community NoopAuditService exists but
|
||||||
|
# is only exported by CoreModule – child modules such as UserModule cannot
|
||||||
|
# resolve it. Making CoreModule @Global() exposes the token app-wide.
|
||||||
|
if [[ ! -f /opt/docmost/apps/server/src/ee/ee.module.ts ]] \
|
||||||
|
&& ! grep -q '@Global()' /opt/docmost/apps/server/src/core/core.module.ts 2>/dev/null; then
|
||||||
|
sed -i '/^ Module,$/a\ Global,' /opt/docmost/apps/server/src/core/core.module.ts
|
||||||
|
sed -i '/^@Module({$/i @Global()' /opt/docmost/apps/server/src/core/core.module.ts
|
||||||
|
fi
|
||||||
|
|
||||||
$STD pnpm install --force
|
$STD pnpm install --force
|
||||||
$STD pnpm build
|
$STD pnpm build
|
||||||
msg_ok "Updated ${APP}"
|
msg_ok "Updated ${APP}"
|
||||||
|
|||||||
@@ -46,9 +46,11 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Migrating update function"
|
msg_info "Migrating update function"
|
||||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
TMP_UPDATE=$(mktemp)
|
||||||
|
cat <<'MIGRATION_EOF' >"$TMP_UPDATE"
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dokploy.sh)"
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/dokploy.sh)"
|
||||||
MIGRATION_EOF
|
MIGRATION_EOF
|
||||||
|
mv "$TMP_UPDATE" /usr/bin/update
|
||||||
chmod +x /usr/bin/update
|
chmod +x /usr/bin/update
|
||||||
|
|
||||||
ln -sf /usr/bin/update /usr/bin/update_dokploy 2>/dev/null || true
|
ln -sf /usr/bin/update /usr/bin/update_dokploy 2>/dev/null || true
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function update_script() {
|
|||||||
|
|
||||||
if [[ ! -d /opt/endurain ]]; then
|
if [[ ! -d /opt/endurain ]]; then
|
||||||
msg_error "No ${APP} installation found!"
|
msg_error "No ${APP} installation found!"
|
||||||
exit 1
|
exit 233
|
||||||
fi
|
fi
|
||||||
if check_for_gh_release "endurain" "endurain-project/endurain"; then
|
if check_for_gh_release "endurain" "endurain-project/endurain"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function update_script() {
|
|||||||
check_container_resources
|
check_container_resources
|
||||||
if ! command -v evcc >/dev/null 2>&1; then
|
if ! command -v evcc >/dev/null 2>&1; then
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit 1
|
exit 233
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f /etc/apt/sources.list.d/evcc-stable.list ]]; then
|
if [[ -f /etc/apt/sources.list.d/evcc-stable.list ]]; then
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ensure_dependencies build-essential
|
||||||
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
|
||||||
if check_for_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar"; then
|
if check_for_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop fluid-calendar
|
systemctl stop fluid-calendar
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ EOF
|
|||||||
msg_ok "Old Enviroment fixed"
|
msg_ok "Old Enviroment fixed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ensure_dependencies git
|
||||||
|
|
||||||
if check_for_gh_release "gitea-mirror" "RayLabsHQ/gitea-mirror"; then
|
if check_for_gh_release "gitea-mirror" "RayLabsHQ/gitea-mirror"; then
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop gitea-mirror
|
systemctl stop gitea-mirror
|
||||||
@@ -94,7 +96,7 @@ EOF
|
|||||||
|
|
||||||
msg_info "Backup Data"
|
msg_info "Backup Data"
|
||||||
mkdir -p /opt/gitea-mirror-backup/data
|
mkdir -p /opt/gitea-mirror-backup/data
|
||||||
cp /opt/gitea-mirror/data/* /opt/gitea-mirror-backup/data/
|
cp -r /opt/gitea-mirror/data/* /opt/gitea-mirror-backup/data/
|
||||||
msg_ok "Backup Data"
|
msg_ok "Backup Data"
|
||||||
|
|
||||||
msg_info "Installing Bun"
|
msg_info "Installing Bun"
|
||||||
@@ -111,12 +113,11 @@ EOF
|
|||||||
$STD bun run setup
|
$STD bun run setup
|
||||||
$STD bun run build
|
$STD bun run build
|
||||||
APP_VERSION=$(grep -o '"version": *"[^"]*"' package.json | cut -d'"' -f4)
|
APP_VERSION=$(grep -o '"version": *"[^"]*"' package.json | cut -d'"' -f4)
|
||||||
|
sed -i.bak "s|^npm_package_version=.*|npm_package_version=${APP_VERSION}|" /opt/gitea-mirror.env
|
||||||
sudo sed -i.bak "s|^npm_package_version=.*|npm_package_version=${APP_VERSION}|" /opt/gitea-mirror.env
|
|
||||||
msg_ok "Updated and rebuilt ${APP}"
|
msg_ok "Updated and rebuilt ${APP}"
|
||||||
|
|
||||||
msg_info "Restoring Data"
|
msg_info "Restoring Data"
|
||||||
cp /opt/gitea-mirror-backup/data/* /opt/gitea-mirror/data
|
cp -r /opt/gitea-mirror-backup/data/* /opt/gitea-mirror/data
|
||||||
msg_ok "Restored Data"
|
msg_ok "Restored Data"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function update_script() {
|
|||||||
|
|
||||||
if ! dpkg -s grafana >/dev/null 2>&1; then
|
if ! dpkg -s grafana >/dev/null 2>&1; then
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit 1
|
exit 233
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f /etc/apt/sources.list.d/grafana.list ]] || [[ ! -f /etc/apt/sources.list.d/grafana.sources ]]; then
|
if [[ -f /etc/apt/sources.list.d/grafana.list ]] || [[ ! -f /etc/apt/sources.list.d/grafana.sources ]]; then
|
||||||
|
|||||||
6
ct/headers/ddclient
Normal file
6
ct/headers/ddclient
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
__ __ ___ __
|
||||||
|
____/ /___/ /____/ (_)__ ____ / /_
|
||||||
|
/ __ / __ / ___/ / / _ \/ __ \/ __/
|
||||||
|
/ /_/ / /_/ / /__/ / / __/ / / / /_
|
||||||
|
\__,_/\__,_/\___/_/_/\___/_/ /_/\__/
|
||||||
|
|
||||||
6
ct/headers/netbird
Normal file
6
ct/headers/netbird
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
_ __ __ ____ _ __
|
||||||
|
/ | / /__ / /_/ __ )(_)________/ /
|
||||||
|
/ |/ / _ \/ __/ __ / / ___/ __ /
|
||||||
|
/ /| / __/ /_/ /_/ / / / / /_/ /
|
||||||
|
/_/ |_/\___/\__/_____/_/_/ \__,_/
|
||||||
|
|
||||||
6
ct/headers/papra
Normal file
6
ct/headers/papra
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
____
|
||||||
|
/ __ \____ _____ _________ _
|
||||||
|
/ /_/ / __ `/ __ \/ ___/ __ `/
|
||||||
|
/ ____/ /_/ / /_/ / / / /_/ /
|
||||||
|
/_/ \__,_/ .___/_/ \__,_/
|
||||||
|
/_/
|
||||||
6
ct/headers/powerdns
Normal file
6
ct/headers/powerdns
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
____ ____ _ _______
|
||||||
|
/ __ \____ _ _____ _____/ __ \/ | / / ___/
|
||||||
|
/ /_/ / __ \ | /| / / _ \/ ___/ / / / |/ /\__ \
|
||||||
|
/ ____/ /_/ / |/ |/ / __/ / / /_/ / /| /___/ /
|
||||||
|
/_/ \____/|__/|__/\___/_/ /_____/_/ |_//____/
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
_____ _ _____
|
|
||||||
/ ___/__ ___ ______ ___ ______ ____ ___ (_) ___/___ ______ _____ _____
|
|
||||||
\__ \/ / / / | /| / / __ `/ / / / __ \/ __ `__ \/ /\__ \/ _ \/ ___/ | / / _ \/ ___/
|
|
||||||
___/ / /_/ /| |/ |/ / /_/ / /_/ / /_/ / / / / / / /___/ / __/ / | |/ / __/ /
|
|
||||||
/____/\__,_/ |__/|__/\__,_/\__, /\____/_/ /_/ /_/_//____/\___/_/ |___/\___/_/
|
|
||||||
/____/
|
|
||||||
6
ct/headers/tinyauth
Normal file
6
ct/headers/tinyauth
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
_______ __ __
|
||||||
|
/_ __(_)___ __ ______ ___ __/ /_/ /_
|
||||||
|
/ / / / __ \/ / / / __ `/ / / / __/ __ \
|
||||||
|
/ / / / / / / /_/ / /_/ / /_/ / /_/ / / /
|
||||||
|
/_/ /_/_/ /_/\__, /\__,_/\__,_/\__/_/ /_/
|
||||||
|
/____/
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
__ __ _ _____
|
|
||||||
/ / / /___ (_) __(_)
|
|
||||||
/ / / / __ \/ / /_/ /
|
|
||||||
/ /_/ / / / / / __/ /
|
|
||||||
\____/_/ /_/_/_/ /_/
|
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ function compile_libraw() {
|
|||||||
if [[ "$LIBRAW_REVISION" != "$(grep 'libraw' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
|
if [[ "$LIBRAW_REVISION" != "$(grep 'libraw' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
|
||||||
msg_info "Recompiling libraw"
|
msg_info "Recompiling libraw"
|
||||||
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
|
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
|
||||||
$STD git clone https://github.com/libraw/libraw.git "$SOURCE"
|
$STD git clone https://github.com/LibRaw/LibRaw.git "$SOURCE"
|
||||||
cd "$SOURCE"
|
cd "$SOURCE"
|
||||||
$STD git reset --hard "$LIBRAW_REVISION"
|
$STD git reset --hard "$LIBRAW_REVISION"
|
||||||
$STD autoreconf --install
|
$STD autoreconf --install
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function update_script() {
|
|||||||
|
|
||||||
if [[ ! -f /etc/itsm-ng/config_db.php ]]; then
|
if [[ ! -f /etc/itsm-ng/config_db.php ]]; then
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit 1
|
exit 233
|
||||||
fi
|
fi
|
||||||
setup_mariadb
|
setup_mariadb
|
||||||
|
|
||||||
|
|||||||
@@ -45,14 +45,15 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Switching update script to Seerr"
|
msg_info "Switching update script to Seerr"
|
||||||
cat <<'EOF' >/usr/bin/update
|
TMP_UPDATE=$(mktemp)
|
||||||
#!/usr/bin/env bash
|
cat <<'EOF' >"$TMP_UPDATE"
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/seerr.sh)"
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/seerr.sh)"
|
||||||
EOF
|
EOF
|
||||||
|
mv "$TMP_UPDATE" /usr/bin/update
|
||||||
chmod +x /usr/bin/update
|
chmod +x /usr/bin/update
|
||||||
msg_ok "Switched update script to Seerr"
|
msg_ok "Switched update script to Seerr"
|
||||||
msg_warn "Please type 'update' again to complete the migration"
|
msg_warn "Please type 'update' again to complete the migration"
|
||||||
exit
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Updating Jellyseerr"
|
msg_info "Updating Jellyseerr"
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ function update_script() {
|
|||||||
|
|
||||||
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
||||||
msg_error "Unable to detect latest Kasm release URL."
|
msg_error "Unable to detect latest Kasm release URL."
|
||||||
exit 1
|
exit 250
|
||||||
fi
|
fi
|
||||||
msg_info "Checked for new version"
|
msg_info "Checked for new version"
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function update_script() {
|
|||||||
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||||
if [[ -z "$COMPOSE_FILE" ]]; then
|
if [[ -z "$COMPOSE_FILE" ]]; then
|
||||||
msg_error "No valid compose file found in /opt/komodo!"
|
msg_error "No valid compose file found in /opt/komodo!"
|
||||||
exit 1
|
exit 252
|
||||||
fi
|
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 pull
|
||||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||||
@@ -52,9 +52,11 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Migrating update function"
|
msg_info "Migrating update function"
|
||||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
TMP_UPDATE=$(mktemp)
|
||||||
|
cat <<'MIGRATION_EOF' >"$TMP_UPDATE"
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh)"
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/komodo.sh)"
|
||||||
MIGRATION_EOF
|
MIGRATION_EOF
|
||||||
|
mv "$TMP_UPDATE" /usr/bin/update
|
||||||
chmod +x /usr/bin/update
|
chmod +x /usr/bin/update
|
||||||
|
|
||||||
ln -sf /usr/bin/update /usr/bin/update_komodo 2>/dev/null || true
|
ln -sf /usr/bin/update /usr/bin/update_komodo 2>/dev/null || true
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ function update_script() {
|
|||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
VENV_PATH="/opt/litellm/.venv"
|
VENV_PATH="/opt/litellm/.venv"
|
||||||
PYTHON_VERSION="3.13" setup_uv
|
PYTHON_VERSION="3.13" USE_UVX="YES" setup_uv
|
||||||
|
|
||||||
msg_info "Updating LiteLLM"
|
msg_info "Updating LiteLLM"
|
||||||
$STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
|
$STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function update_script() {
|
|||||||
|
|
||||||
if ! dpkg -s loki >/dev/null 2>&1; then
|
if ! dpkg -s loki >/dev/null 2>&1; then
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit 1
|
exit 233
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CHOICE=$(msg_menu "Loki Update Options" \
|
CHOICE=$(msg_menu "Loki Update Options" \
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ APP="MeshCentral"
|
|||||||
var_tags="${var_tags:-remote-management}"
|
var_tags="${var_tags:-remote-management}"
|
||||||
var_cpu="${var_cpu:-1}"
|
var_cpu="${var_cpu:-1}"
|
||||||
var_ram="${var_ram:-512}"
|
var_ram="${var_ram:-512}"
|
||||||
var_disk="${var_disk:-2}"
|
var_disk="${var_disk:-4}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-13}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|||||||
47
ct/netbird.sh
Normal file
47
ct/netbird.sh
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/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: TechHutTV
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://netbird.io/
|
||||||
|
|
||||||
|
APP="NetBird"
|
||||||
|
var_tags="${var_tags:-network;vpn}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-512}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
var_tun="${var_tun:-yes}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -f /etc/netbird/config.json ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Updating Netbird"
|
||||||
|
$STD apt update
|
||||||
|
$STD apt upgrade -y
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access NetBird by entering the container and running:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}netbird up${CL}"
|
||||||
@@ -44,10 +44,11 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Switching update script to Seerr"
|
msg_info "Switching update script to Seerr"
|
||||||
cat <<'EOF' >/usr/bin/update
|
TMP_UPDATE=$(mktemp)
|
||||||
#!/usr/bin/env bash
|
cat <<'EOF' >"$TMP_UPDATE"
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/seerr.sh)"
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/seerr.sh)"
|
||||||
EOF
|
EOF
|
||||||
|
mv "$TMP_UPDATE" /usr/bin/update
|
||||||
chmod +x /usr/bin/update
|
chmod +x /usr/bin/update
|
||||||
msg_ok "Switched update script to Seerr"
|
msg_ok "Switched update script to Seerr"
|
||||||
msg_warn "Please type 'update' again to complete the migration"
|
msg_warn "Please type 'update' again to complete the migration"
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ function update_script() {
|
|||||||
echo -e "${TAB}${GATEWAY}${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/9223${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/9223${CL}"
|
||||||
echo -e ""
|
echo -e ""
|
||||||
msg_custom "⚠️" "Update aborted. Please migrate your data first."
|
msg_custom "⚠️" "Update aborted. Please migrate your data first."
|
||||||
exit 1
|
exit 253
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
68
ct/papra.sh
Normal file
68
ct/papra.sh
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/papra-hq/papra
|
||||||
|
|
||||||
|
APP="Papra"
|
||||||
|
var_tags="${var_tags:-document-management}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-2048}"
|
||||||
|
var_disk="${var_disk:-10}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/papra ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "papra" "papra-hq/papra"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop papra
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
msg_info "Backing up Configuration"
|
||||||
|
cp /opt/papra/apps/papra-server/.env /opt/papra_env.bak
|
||||||
|
msg_ok "Backed up Configuration"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "papra" "papra-hq/papra" "tarball"
|
||||||
|
|
||||||
|
msg_info "Building Application"
|
||||||
|
cd /opt/papra
|
||||||
|
cp /opt/papra_env.bak /opt/papra/apps/papra-server/.env
|
||||||
|
$STD pnpm install --frozen-lockfile
|
||||||
|
$STD pnpm --filter "@papra/app-client..." run build
|
||||||
|
$STD pnpm --filter "@papra/app-server..." run build
|
||||||
|
ln -sf /opt/papra/apps/papra-client/dist /opt/papra/apps/papra-server/public
|
||||||
|
rm -f /opt/papra_env.bak
|
||||||
|
msg_ok "Built Application"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start papra
|
||||||
|
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}:1221${CL}"
|
||||||
71
ct/powerdns.sh
Normal file
71
ct/powerdns.sh
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#!/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: Slaviša Arežina (tremor021)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://www.powerdns.com/
|
||||||
|
|
||||||
|
APP="PowerDNS"
|
||||||
|
var_tags="${var_tags:-dns}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
if [[ ! -d /opt/poweradmin ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Updating PowerDNS"
|
||||||
|
$STD apt update
|
||||||
|
$STD apt install -y --only-upgrade pdns-server pdns-backend-sqlite3
|
||||||
|
msg_ok "Updated PowerDNS"
|
||||||
|
|
||||||
|
if check_for_gh_release "poweradmin" "poweradmin/poweradmin"; then
|
||||||
|
msg_info "Backing up Configuration"
|
||||||
|
cp /opt/poweradmin/config/settings.php /opt/poweradmin_settings.php.bak
|
||||||
|
cp /opt/poweradmin/powerdns.db /opt/poweradmin_powerdns.db.bak
|
||||||
|
msg_ok "Backed up Configuration"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "poweradmin" "poweradmin/poweradmin" "tarball"
|
||||||
|
|
||||||
|
msg_info "Updating Poweradmin"
|
||||||
|
cp /opt/poweradmin_settings.php.bak /opt/poweradmin/config/settings.php
|
||||||
|
cp /opt/poweradmin_powerdns.db.bak /opt/poweradmin/powerdns.db
|
||||||
|
rm -rf /opt/poweradmin/install
|
||||||
|
rm -f /opt/poweradmin_settings.php.bak /opt/poweradmin_powerdns.db.bak
|
||||||
|
chown -R www-data:pdns /opt/poweradmin
|
||||||
|
chmod 775 /opt/poweradmin
|
||||||
|
chown pdns:pdns /opt/poweradmin/powerdns.db
|
||||||
|
chmod 664 /opt/poweradmin/powerdns.db
|
||||||
|
msg_ok "Updated Poweradmin"
|
||||||
|
|
||||||
|
msg_info "Restarting Services"
|
||||||
|
systemctl restart pdns apache2
|
||||||
|
msg_ok "Restarted Services"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||||
@@ -46,9 +46,11 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Migrating update function"
|
msg_info "Migrating update function"
|
||||||
cat <<'MIGRATION_EOF' >/usr/bin/update
|
TMP_UPDATE=$(mktemp)
|
||||||
|
cat <<'MIGRATION_EOF' >"$TMP_UPDATE"
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/runtipi.sh)"
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/runtipi.sh)"
|
||||||
MIGRATION_EOF
|
MIGRATION_EOF
|
||||||
|
mv "$TMP_UPDATE" /usr/bin/update
|
||||||
chmod +x /usr/bin/update
|
chmod +x /usr/bin/update
|
||||||
|
|
||||||
ln -sf /usr/bin/update /usr/bin/update_runtipi 2>/dev/null || true
|
ln -sf /usr/bin/update /usr/bin/update_runtipi 2>/dev/null || true
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE=$(curl -fsSL https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
if check_for_gh_release "rustdesk-api"; then
|
||||||
APIRELEASE=$(curl -fsSL https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
if [[ "${RELEASE}" != "$(cat ~/.rustdesk-hbbr)" ]] || [[ "${APIRELEASE}" != "$(cat ~/.rustdesk-api)" ]] || [[ ! -f ~/.rustdesk-hbbr ]] || [[ ! -f ~/.rustdesk-api ]]; then
|
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop rustdesk-hbbr
|
systemctl stop rustdesk-hbbr
|
||||||
systemctl stop rustdesk-hbbs
|
systemctl stop rustdesk-hbbs
|
||||||
@@ -40,13 +38,13 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
msg_info "Stopped Service"
|
msg_info "Stopped Service"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "rustdesk-hbbr" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbr*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-hbbr" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbr*amd64.deb"
|
||||||
fetch_and_deploy_gh_release "rustdesk-hbbs" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbs*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-hbbs" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbs*amd64.deb"
|
||||||
fetch_and_deploy_gh_release "rustdesk-utils" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-utils" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*amd64.deb"
|
||||||
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*amd64.deb"
|
||||||
|
|
||||||
msg_info "Starting services"
|
msg_info "Starting services"
|
||||||
systemctl start -q rustdesk-* --all
|
systemctl start -q rustdesk-*
|
||||||
msg_ok "Services started"
|
msg_ok "Services started"
|
||||||
|
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
|||||||
@@ -28,6 +28,34 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -f /opt/semaphore/semaphore_db.bolt ]]; then
|
||||||
|
msg_warn "WARNING: Due to bugs with BoltDB database, update script will move your application"
|
||||||
|
msg_warn "to use SQLite database instead. Unfortunately, this will reset your application and make it a fresh"
|
||||||
|
msg_warn "installation. All your data will be lost!"
|
||||||
|
echo ""
|
||||||
|
read -r -p "${TAB3}Do you want to continue? (y/N): " CONFIRM
|
||||||
|
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
msg_info "Moving from BoltDB to SQLite"
|
||||||
|
systemctl stop semaphore
|
||||||
|
rm -rf /opt/semaphore/semaphore_db.bolt
|
||||||
|
sed -i \
|
||||||
|
-e 's|"bolt": {|"sqlite": {|' \
|
||||||
|
-e 's|/semaphore_db.bolt"|/database.sqlite"|' \
|
||||||
|
-e '/semaphore_db.bolt/d' \
|
||||||
|
-e '/"dialect"/d' \
|
||||||
|
-e '/^ },$/a\ "dialect": "sqlite",' \
|
||||||
|
/opt/semaphore/config.json
|
||||||
|
SEM_PW=$(cat ~/semaphore.creds)
|
||||||
|
systemctl start semaphore
|
||||||
|
$STD semaphore user add --admin --login admin --email admin@helper-scripts.com --name Administrator --password "${SEM_PW}" --config /opt/semaphore/config.json
|
||||||
|
|
||||||
|
msg_ok "Moved from BoltDB to SQLite"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "semaphore" "semaphoreui/semaphore"; then
|
if check_for_gh_release "semaphore" "semaphoreui/semaphore"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop semaphore
|
systemctl stop semaphore
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
PYTHON_VERSION="3.12" setup_uv
|
PYTHON_VERSION="3.12" setup_uv
|
||||||
JAVA_VERSION="21" setup_java
|
JAVA_VERSION="25" setup_java
|
||||||
|
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop stirlingpdf libreoffice-listener unoserver
|
systemctl stop stirlingpdf libreoffice-listener unoserver
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: Slaviša Arežina (tremor021)
|
# Author: MickLesk (CanbiZ)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/Suwayomi/Suwayomi-Server
|
# Source: https://github.com/steveiliop56/tinyauth
|
||||||
|
|
||||||
APP="SuwayomiServer"
|
APP="Tinyauth"
|
||||||
var_tags="${var_tags:-media;manga}"
|
var_tags="${var_tags:-auth}"
|
||||||
var_cpu="${var_cpu:-1}"
|
var_cpu="${var_cpu:-1}"
|
||||||
var_ram="${var_ram:-1024}"
|
var_ram="${var_ram:-512}"
|
||||||
var_disk="${var_disk:-4}"
|
var_disk="${var_disk:-4}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-13}"
|
||||||
@@ -23,23 +23,20 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
check_container_storage
|
check_container_storage
|
||||||
check_container_resources
|
check_container_resources
|
||||||
|
if [[ ! -d /opt/tinyauth ]]; then
|
||||||
if [[ ! -f /usr/bin/suwayomi-server ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "suwayomi-server" "Suwayomi/Suwayomi-Server"; then
|
if check_for_gh_release "tinyauth" "steveiliop56/tinyauth"; then
|
||||||
JAVA_VERSION=21 setup_java
|
|
||||||
|
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop suwayomi-server
|
systemctl stop tinyauth
|
||||||
msg_info "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "suwayomi-server" "Suwayomi/Suwayomi-Server" "binary"
|
fetch_and_deploy_gh_release "tinyauth" "steveiliop56/tinyauth" "singlefile" "latest" "/opt/tinyauth" "tinyauth-amd64"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start suwayomi-server
|
systemctl start tinyauth
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
fi
|
fi
|
||||||
@@ -53,4 +50,4 @@ description
|
|||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:4567${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||||
@@ -75,10 +75,31 @@ if [ -f \$pg_config_file ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
systemctl restart postgresql
|
systemctl restart postgresql
|
||||||
|
sudo -u postgres psql -c "ALTER USER tracearr WITH SUPERUSER;"
|
||||||
EOF
|
EOF
|
||||||
chmod +x /data/tracearr/prestart.sh
|
chmod +x /data/tracearr/prestart.sh
|
||||||
msg_ok "Updated prestart script"
|
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
|
if check_for_gh_release "tracearr" "connorgallopo/Tracearr"; then
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop tracearr postgresql redis
|
systemctl stop tracearr postgresql redis
|
||||||
@@ -122,6 +143,8 @@ EOF
|
|||||||
sed -i "s/^APP_VERSION=.*/APP_VERSION=$(cat /root/.tracearr)/" /data/tracearr/.env
|
sed -i "s/^APP_VERSION=.*/APP_VERSION=$(cat /root/.tracearr)/" /data/tracearr/.env
|
||||||
chmod 600 /data/tracearr/.env
|
chmod 600 /data/tracearr/.env
|
||||||
chown -R tracearr:tracearr /data/tracearr
|
chown -R tracearr:tracearr /data/tracearr
|
||||||
|
mkdir -p /data/backup
|
||||||
|
chown -R tracearr:tracearr /data/backup
|
||||||
msg_ok "Configured Tracearr"
|
msg_ok "Configured Tracearr"
|
||||||
|
|
||||||
msg_info "Starting services"
|
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 "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"
|
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
|
[[ "$CONFIRM1" =~ ^[yY]$ ]] || exit 0
|
||||||
|
|
||||||
echo
|
echo
|
||||||
msg_warn "Vikunja may not start after the update until you manually adjust the config."
|
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"
|
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
|
[[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if grep -q '^WF_CORS_ALLOW_ORIGINS=\*$' /opt/wealthfolio/.env; then
|
||||||
|
sed -i "s|^WF_CORS_ALLOW_ORIGINS=\*$|WF_CORS_ALLOW_ORIGINS=http://${LOCAL_IP}:8080|" /opt/wealthfolio/.env
|
||||||
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "wealthfolio" "afadil/wealthfolio"; then
|
if check_for_gh_release "wealthfolio" "afadil/wealthfolio"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop wealthfolio
|
systemctl stop wealthfolio
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"type": "default",
|
"type": "default",
|
||||||
"script": "ct/bentopdf.sh",
|
"script": "ct/bentopdf.sh",
|
||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 1,
|
"cpu": 2,
|
||||||
"ram": 4096,
|
"ram": 4096,
|
||||||
"hdd": 4,
|
"hdd": 4,
|
||||||
"os": "debian",
|
"os": "debian",
|
||||||
|
|||||||
44
frontend/public/json/ddclient.json
Normal file
44
frontend/public/json/ddclient.json
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "ddclient",
|
||||||
|
"slug": "ddclient",
|
||||||
|
"categories": [
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"date_created": "2026-03-05",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": null,
|
||||||
|
"documentation": "https://ddclient.net/",
|
||||||
|
"website": "https://ddclient.net/",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ddclient.webp",
|
||||||
|
"config_path": "/etc/ddclient.conf",
|
||||||
|
"description": "ddclient is a Perl client used to update dynamic DNS entries for accounts on a wide range of dynamic DNS service providers. It supports multiple protocols and providers, allowing automatic IP address updates for your domain names.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/ddclient.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 1,
|
||||||
|
"ram": 512,
|
||||||
|
"hdd": 2,
|
||||||
|
"os": "debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"type": "info",
|
||||||
|
"text": "After installation, edit `/etc/ddclient.conf` with your dynamic DNS provider credentials"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "info",
|
||||||
|
"text": "Sample configuration is created for Namecheap but can be modified for other providers"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-03-02T12:12:21Z",
|
"generated": "2026-03-07T00:19:56Z",
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"slug": "2fauth",
|
"slug": "2fauth",
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "ampache",
|
"slug": "ampache",
|
||||||
"repo": "ampache/ampache",
|
"repo": "ampache/ampache",
|
||||||
"version": "7.9.1",
|
"version": "7.9.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-25T08:52:58Z"
|
"date": "2026-03-05T03:54:03Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "argus",
|
"slug": "argus",
|
||||||
@@ -151,9 +151,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "booklore",
|
"slug": "booklore",
|
||||||
"repo": "booklore-app/BookLore",
|
"repo": "booklore-app/BookLore",
|
||||||
"version": "v2.0.5",
|
"version": "v2.0.6",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-01T16:13:13Z"
|
"date": "2026-03-06T19:16:29Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "bookstack",
|
"slug": "bookstack",
|
||||||
@@ -193,16 +193,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "checkmate",
|
"slug": "checkmate",
|
||||||
"repo": "bluewave-labs/Checkmate",
|
"repo": "bluewave-labs/Checkmate",
|
||||||
"version": "v3.4.0",
|
"version": "v3.5.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-20T21:08:55Z"
|
"date": "2026-03-06T21:18:36Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "cleanuparr",
|
"slug": "cleanuparr",
|
||||||
"repo": "Cleanuparr/Cleanuparr",
|
"repo": "Cleanuparr/Cleanuparr",
|
||||||
"version": "v2.7.6",
|
"version": "v2.7.7",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-27T19:32:02Z"
|
"date": "2026-03-02T13:08:32Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "cloudreve",
|
"slug": "cloudreve",
|
||||||
@@ -214,9 +214,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "comfyui",
|
"slug": "comfyui",
|
||||||
"repo": "comfyanonymous/ComfyUI",
|
"repo": "comfyanonymous/ComfyUI",
|
||||||
"version": "v0.15.1",
|
"version": "v0.16.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-26T22:01:35Z"
|
"date": "2026-03-05T23:18:25Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "commafeed",
|
"slug": "commafeed",
|
||||||
@@ -242,9 +242,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "cosmos",
|
"slug": "cosmos",
|
||||||
"repo": "azukaar/Cosmos-Server",
|
"repo": "azukaar/Cosmos-Server",
|
||||||
"version": "v0.21.6",
|
"version": "v0.21.7",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-28T22:00:49Z"
|
"date": "2026-03-03T18:15:29Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "cronicle",
|
"slug": "cronicle",
|
||||||
@@ -270,9 +270,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "databasus",
|
"slug": "databasus",
|
||||||
"repo": "databasus/databasus",
|
"repo": "databasus/databasus",
|
||||||
"version": "v3.16.4",
|
"version": "v3.17.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-01T08:20:17Z"
|
"date": "2026-03-06T07:07:22Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "dawarich",
|
"slug": "dawarich",
|
||||||
@@ -284,23 +284,23 @@
|
|||||||
{
|
{
|
||||||
"slug": "discopanel",
|
"slug": "discopanel",
|
||||||
"repo": "nickheyer/discopanel",
|
"repo": "nickheyer/discopanel",
|
||||||
"version": "v1.0.37",
|
"version": "v2.0.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-18T08:53:43Z"
|
"date": "2026-03-06T08:19:39Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "dispatcharr",
|
"slug": "dispatcharr",
|
||||||
"repo": "Dispatcharr/Dispatcharr",
|
"repo": "Dispatcharr/Dispatcharr",
|
||||||
"version": "v0.20.1",
|
"version": "v0.20.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-26T21:38:19Z"
|
"date": "2026-03-03T01:40:33Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "docmost",
|
"slug": "docmost",
|
||||||
"repo": "docmost/docmost",
|
"repo": "docmost/docmost",
|
||||||
"version": "v0.25.3",
|
"version": "v0.70.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-10T02:58:23Z"
|
"date": "2026-03-04T12:54:49Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "domain-locker",
|
"slug": "domain-locker",
|
||||||
@@ -326,9 +326,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "drawio",
|
"slug": "drawio",
|
||||||
"repo": "jgraph/drawio",
|
"repo": "jgraph/drawio",
|
||||||
"version": "v29.5.2",
|
"version": "v29.6.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-22T10:36:14Z"
|
"date": "2026-03-06T09:14:17Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "duplicati",
|
"slug": "duplicati",
|
||||||
@@ -382,9 +382,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "firefly",
|
"slug": "firefly",
|
||||||
"repo": "firefly-iii/firefly-iii",
|
"repo": "firefly-iii/firefly-iii",
|
||||||
"version": "v6.5.1",
|
"version": "v6.5.4",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-27T20:55:55Z"
|
"date": "2026-03-06T09:07:56Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "fladder",
|
"slug": "fladder",
|
||||||
@@ -424,9 +424,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "frigate",
|
"slug": "frigate",
|
||||||
"repo": "blakeblackshear/frigate",
|
"repo": "blakeblackshear/frigate",
|
||||||
"version": "v0.16.4",
|
"version": "v0.17.0",
|
||||||
"pinned": true,
|
"pinned": true,
|
||||||
"date": "2026-01-29T00:42:14Z"
|
"date": "2026-02-27T03:03:01Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "gatus",
|
"slug": "gatus",
|
||||||
@@ -438,9 +438,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "ghostfolio",
|
"slug": "ghostfolio",
|
||||||
"repo": "ghostfolio/ghostfolio",
|
"repo": "ghostfolio/ghostfolio",
|
||||||
"version": "2.245.0",
|
"version": "2.247.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-01T09:09:57Z"
|
"date": "2026-03-04T07:48:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "gitea",
|
"slug": "gitea",
|
||||||
@@ -452,9 +452,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "gitea-mirror",
|
"slug": "gitea-mirror",
|
||||||
"repo": "RayLabsHQ/gitea-mirror",
|
"repo": "RayLabsHQ/gitea-mirror",
|
||||||
"version": "v3.11.0",
|
"version": "v3.12.4",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-02T10:19:59Z"
|
"date": "2026-03-06T05:02:40Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "glance",
|
"slug": "glance",
|
||||||
@@ -473,9 +473,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "gokapi",
|
"slug": "gokapi",
|
||||||
"repo": "Forceu/Gokapi",
|
"repo": "Forceu/Gokapi",
|
||||||
"version": "v2.2.2",
|
"version": "v2.2.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-31T21:11:27Z"
|
"date": "2026-03-04T21:29:16Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "gotify",
|
"slug": "gotify",
|
||||||
@@ -501,9 +501,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "grocy",
|
"slug": "grocy",
|
||||||
"repo": "grocy/grocy",
|
"repo": "grocy/grocy",
|
||||||
"version": "v4.5.0",
|
"version": "v4.6.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-03-28T19:02:22Z"
|
"date": "2026-03-06T17:35:19Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "guardian",
|
"slug": "guardian",
|
||||||
@@ -550,16 +550,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "homarr",
|
"slug": "homarr",
|
||||||
"repo": "homarr-labs/homarr",
|
"repo": "homarr-labs/homarr",
|
||||||
"version": "v1.54.0",
|
"version": "v1.55.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-27T19:38:50Z"
|
"date": "2026-03-06T19:40:16Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "homebox",
|
"slug": "homebox",
|
||||||
"repo": "sysadminsmedia/homebox",
|
"repo": "sysadminsmedia/homebox",
|
||||||
"version": "v0.23.1",
|
"version": "v0.24.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-01T22:53:32Z"
|
"date": "2026-03-03T16:09:55Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "homepage",
|
"slug": "homepage",
|
||||||
@@ -585,9 +585,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "immich-public-proxy",
|
"slug": "immich-public-proxy",
|
||||||
"repo": "alangrainger/immich-public-proxy",
|
"repo": "alangrainger/immich-public-proxy",
|
||||||
"version": "v1.15.3",
|
"version": "v1.15.4",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T22:54:27Z"
|
"date": "2026-03-02T21:28:06Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "inspircd",
|
"slug": "inspircd",
|
||||||
@@ -606,16 +606,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "invoiceninja",
|
"slug": "invoiceninja",
|
||||||
"repo": "invoiceninja/invoiceninja",
|
"repo": "invoiceninja/invoiceninja",
|
||||||
"version": "v5.12.69",
|
"version": "v5.12.70",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-26T22:23:32Z"
|
"date": "2026-03-06T01:53:38Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "jackett",
|
"slug": "jackett",
|
||||||
"repo": "Jackett/Jackett",
|
"repo": "Jackett/Jackett",
|
||||||
"version": "v0.24.1247",
|
"version": "v0.24.1292",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-02T05:56:37Z"
|
"date": "2026-03-06T05:57:21Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "jellystat",
|
"slug": "jellystat",
|
||||||
@@ -641,9 +641,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "kapowarr",
|
"slug": "kapowarr",
|
||||||
"repo": "Casvt/Kapowarr",
|
"repo": "Casvt/Kapowarr",
|
||||||
"version": "V1.2.0",
|
"version": "V1.3.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-04-16T14:55:28Z"
|
"date": "2026-03-06T16:38:21Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "karakeep",
|
"slug": "karakeep",
|
||||||
@@ -662,16 +662,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "keycloak",
|
"slug": "keycloak",
|
||||||
"repo": "keycloak/keycloak",
|
"repo": "keycloak/keycloak",
|
||||||
"version": "26.5.4",
|
"version": "26.5.5",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-20T09:19:45Z"
|
"date": "2026-03-05T15:40:30Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "kima-hub",
|
"slug": "kima-hub",
|
||||||
"repo": "Chevron7Locked/kima-hub",
|
"repo": "Chevron7Locked/kima-hub",
|
||||||
"version": "v1.6.0",
|
"version": "v1.6.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-02T05:43:31Z"
|
"date": "2026-03-05T05:38:02Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "kimai",
|
"slug": "kimai",
|
||||||
@@ -690,9 +690,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "koel",
|
"slug": "koel",
|
||||||
"repo": "koel/koel",
|
"repo": "koel/koel",
|
||||||
"version": "v8.3.0",
|
"version": "v8.3.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-08T21:32:58Z"
|
"date": "2026-03-04T08:22:06Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "koillection",
|
"slug": "koillection",
|
||||||
@@ -753,9 +753,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "libretranslate",
|
"slug": "libretranslate",
|
||||||
"repo": "LibreTranslate/LibreTranslate",
|
"repo": "LibreTranslate/LibreTranslate",
|
||||||
"version": "v1.9.4",
|
"version": "v1.9.5",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-24T17:06:05Z"
|
"date": "2026-03-03T18:25:04Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "lidarr",
|
"slug": "lidarr",
|
||||||
@@ -872,9 +872,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "metube",
|
"slug": "metube",
|
||||||
"repo": "alexta69/metube",
|
"repo": "alexta69/metube",
|
||||||
"version": "2026.02.27",
|
"version": "2026.03.06",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-27T11:47:02Z"
|
"date": "2026-03-06T13:52:56Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "miniflux",
|
"slug": "miniflux",
|
||||||
@@ -921,9 +921,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "netbox",
|
"slug": "netbox",
|
||||||
"repo": "netbox-community/netbox",
|
"repo": "netbox-community/netbox",
|
||||||
"version": "v4.5.3",
|
"version": "v4.5.4",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T15:39:18Z"
|
"date": "2026-03-03T20:32:16Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "nextcloud-exporter",
|
"slug": "nextcloud-exporter",
|
||||||
@@ -942,9 +942,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "nightscout",
|
"slug": "nightscout",
|
||||||
"repo": "nightscout/cgm-remote-monitor",
|
"repo": "nightscout/cgm-remote-monitor",
|
||||||
"version": "v15.0.5",
|
"version": "v15.0.6",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-01T21:22:37Z"
|
"date": "2026-03-03T23:04:35Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "nocodb",
|
"slug": "nocodb",
|
||||||
@@ -1061,9 +1061,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "paperless-ngx",
|
"slug": "paperless-ngx",
|
||||||
"repo": "paperless-ngx/paperless-ngx",
|
"repo": "paperless-ngx/paperless-ngx",
|
||||||
"version": "v2.20.9",
|
"version": "v2.20.10",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-28T10:17:35Z"
|
"date": "2026-03-04T19:20:57Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "patchmon",
|
"slug": "patchmon",
|
||||||
@@ -1110,9 +1110,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "photoprism",
|
"slug": "photoprism",
|
||||||
"repo": "photoprism/photoprism",
|
"repo": "photoprism/photoprism",
|
||||||
"version": "251130-b3068414c",
|
"version": "260305-fad9d5395",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-12-01T05:07:31Z"
|
"date": "2026-03-05T20:25:12Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "pihole-exporter",
|
"slug": "pihole-exporter",
|
||||||
@@ -1138,9 +1138,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "pocketbase",
|
"slug": "pocketbase",
|
||||||
"repo": "pocketbase/pocketbase",
|
"repo": "pocketbase/pocketbase",
|
||||||
"version": "v0.36.5",
|
"version": "v0.36.6",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-21T11:45:32Z"
|
"date": "2026-03-06T08:07:09Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "pocketid",
|
"slug": "pocketid",
|
||||||
@@ -1149,6 +1149,13 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-23T19:50:48Z"
|
"date": "2026-02-23T19:50:48Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"slug": "powerdns",
|
||||||
|
"repo": "poweradmin/poweradmin",
|
||||||
|
"version": "v4.0.7",
|
||||||
|
"pinned": false,
|
||||||
|
"date": "2026-02-15T20:09:48Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"slug": "privatebin",
|
"slug": "privatebin",
|
||||||
"repo": "PrivateBin/PrivateBin",
|
"repo": "PrivateBin/PrivateBin",
|
||||||
@@ -1222,9 +1229,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "pulse",
|
"slug": "pulse",
|
||||||
"repo": "rcourtman/Pulse",
|
"repo": "rcourtman/Pulse",
|
||||||
"version": "v5.1.16",
|
"version": "v5.1.21",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-01T23:13:09Z"
|
"date": "2026-03-06T12:13:08Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "pve-scripts-local",
|
"slug": "pve-scripts-local",
|
||||||
@@ -1278,9 +1285,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "rclone",
|
"slug": "rclone",
|
||||||
"repo": "rclone/rclone",
|
"repo": "rclone/rclone",
|
||||||
"version": "v1.73.1",
|
"version": "v1.73.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T18:27:21Z"
|
"date": "2026-03-06T20:42:26Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "rdtclient",
|
"slug": "rdtclient",
|
||||||
@@ -1299,9 +1306,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "recyclarr",
|
"slug": "recyclarr",
|
||||||
"repo": "recyclarr/recyclarr",
|
"repo": "recyclarr/recyclarr",
|
||||||
"version": "v8.3.2",
|
"version": "v8.4.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-25T22:39:51Z"
|
"date": "2026-03-06T01:25:59Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "reitti",
|
"slug": "reitti",
|
||||||
@@ -1326,10 +1333,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "rustdeskserver",
|
"slug": "rustdeskserver",
|
||||||
"repo": "rustdesk/rustdesk-server",
|
"repo": "lejianwen/rustdesk-server",
|
||||||
"version": "1.1.15",
|
"version": "v0.1.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-12T05:38:30Z"
|
"date": "2025-09-01T02:52:30Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "rustypaste",
|
"slug": "rustypaste",
|
||||||
@@ -1348,9 +1355,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "scanopy",
|
"slug": "scanopy",
|
||||||
"repo": "scanopy/scanopy",
|
"repo": "scanopy/scanopy",
|
||||||
"version": "v0.14.10",
|
"version": "v0.14.14",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-28T21:05:12Z"
|
"date": "2026-03-06T06:50:38Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "scraparr",
|
"slug": "scraparr",
|
||||||
@@ -1362,9 +1369,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "seaweedfs",
|
"slug": "seaweedfs",
|
||||||
"repo": "seaweedfs/seaweedfs",
|
"repo": "seaweedfs/seaweedfs",
|
||||||
"version": "4.13",
|
"version": "4.15",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T01:09:45Z"
|
"date": "2026-03-05T06:30:30Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "seelf",
|
"slug": "seelf",
|
||||||
@@ -1383,9 +1390,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "semaphore",
|
"slug": "semaphore",
|
||||||
"repo": "semaphoreui/semaphore",
|
"repo": "semaphoreui/semaphore",
|
||||||
"version": "v2.17.15",
|
"version": "v2.17.16",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-28T09:04:40Z"
|
"date": "2026-03-05T12:39:05Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "shelfmark",
|
"slug": "shelfmark",
|
||||||
@@ -1404,9 +1411,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "silverbullet",
|
"slug": "silverbullet",
|
||||||
"repo": "silverbulletmd/silverbullet",
|
"repo": "silverbulletmd/silverbullet",
|
||||||
"version": "2.4.1",
|
"version": "2.5.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-16T12:08:28Z"
|
"date": "2026-03-06T12:20:58Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "slskd",
|
"slug": "slskd",
|
||||||
@@ -1439,9 +1446,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "sonobarr",
|
"slug": "sonobarr",
|
||||||
"repo": "Dodelidoo-Labs/sonobarr",
|
"repo": "Dodelidoo-Labs/sonobarr",
|
||||||
"version": "0.11.0",
|
"version": "0.12.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-21T19:07:21Z"
|
"date": "2026-03-03T13:43:02Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "speedtest-tracker",
|
"slug": "speedtest-tracker",
|
||||||
@@ -1460,16 +1467,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "sportarr",
|
"slug": "sportarr",
|
||||||
"repo": "Sportarr/Sportarr",
|
"repo": "Sportarr/Sportarr",
|
||||||
"version": "v4.0.983.1057",
|
"version": "v4.0.986.1061",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-26T18:54:50Z"
|
"date": "2026-03-06T01:04:24Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "stirling-pdf",
|
"slug": "stirling-pdf",
|
||||||
"repo": "Stirling-Tools/Stirling-PDF",
|
"repo": "Stirling-Tools/Stirling-PDF",
|
||||||
"version": "v2.5.3",
|
"version": "v2.7.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-23T23:23:39Z"
|
"date": "2026-03-06T11:21:47Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "streamlink-webui",
|
"slug": "streamlink-webui",
|
||||||
@@ -1555,6 +1562,13 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T16:30:09Z"
|
"date": "2026-02-13T16:30:09Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"slug": "tinyauth",
|
||||||
|
"repo": "steveiliop56/tinyauth",
|
||||||
|
"version": "v5.0.1",
|
||||||
|
"pinned": false,
|
||||||
|
"date": "2026-03-04T21:05:05Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"slug": "traccar",
|
"slug": "traccar",
|
||||||
"repo": "traccar/traccar",
|
"repo": "traccar/traccar",
|
||||||
@@ -1565,9 +1579,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "tracearr",
|
"slug": "tracearr",
|
||||||
"repo": "connorgallopo/Tracearr",
|
"repo": "connorgallopo/Tracearr",
|
||||||
"version": "v1.4.19",
|
"version": "v1.4.21",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-28T21:25:47Z"
|
"date": "2026-03-03T18:43:20Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "tracktor",
|
"slug": "tracktor",
|
||||||
@@ -1579,9 +1593,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "traefik",
|
"slug": "traefik",
|
||||||
"repo": "traefik/traefik",
|
"repo": "traefik/traefik",
|
||||||
"version": "v3.6.9",
|
"version": "v3.6.10",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-23T17:21:17Z"
|
"date": "2026-03-06T15:08:35Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "trilium",
|
"slug": "trilium",
|
||||||
@@ -1593,9 +1607,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "trip",
|
"slug": "trip",
|
||||||
"repo": "itskovacs/TRIP",
|
"repo": "itskovacs/TRIP",
|
||||||
"version": "1.41.0",
|
"version": "1.41.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-23T17:57:31Z"
|
"date": "2026-03-04T07:25:35Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "tududi",
|
"slug": "tududi",
|
||||||
@@ -1635,9 +1649,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "upgopher",
|
"slug": "upgopher",
|
||||||
"repo": "wanetty/upgopher",
|
"repo": "wanetty/upgopher",
|
||||||
"version": "v1.14.0",
|
"version": "v1.15.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-24T22:43:34Z"
|
"date": "2026-03-03T13:40:45Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "upsnap",
|
"slug": "upsnap",
|
||||||
@@ -1649,9 +1663,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "uptimekuma",
|
"slug": "uptimekuma",
|
||||||
"repo": "louislam/uptime-kuma",
|
"repo": "louislam/uptime-kuma",
|
||||||
"version": "2.1.3",
|
"version": "2.2.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-19T05:37:30Z"
|
"date": "2026-03-05T02:08:14Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "vaultwarden",
|
"slug": "vaultwarden",
|
||||||
@@ -1684,9 +1698,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "wallos",
|
"slug": "wallos",
|
||||||
"repo": "ellite/Wallos",
|
"repo": "ellite/Wallos",
|
||||||
"version": "v4.6.1",
|
"version": "v4.6.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-10T21:06:46Z"
|
"date": "2026-03-05T22:18:06Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "wanderer",
|
"slug": "wanderer",
|
||||||
@@ -1705,9 +1719,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "watcharr",
|
"slug": "watcharr",
|
||||||
"repo": "sbondCo/Watcharr",
|
"repo": "sbondCo/Watcharr",
|
||||||
"version": "v2.1.1",
|
"version": "v3.0.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-07-15T22:38:01Z"
|
"date": "2026-03-04T09:29:14Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "watchyourlan",
|
"slug": "watchyourlan",
|
||||||
@@ -1726,9 +1740,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "wealthfolio",
|
"slug": "wealthfolio",
|
||||||
"repo": "afadil/wealthfolio",
|
"repo": "afadil/wealthfolio",
|
||||||
"version": "v3.0.0",
|
"version": "v3.0.3",
|
||||||
"pinned": false,
|
"pinned": true,
|
||||||
"date": "2026-02-24T22:37:05Z"
|
"date": "2026-03-03T21:47:55Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "web-check",
|
"slug": "web-check",
|
||||||
@@ -1810,9 +1824,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "zitadel",
|
"slug": "zitadel",
|
||||||
"repo": "zitadel/zitadel",
|
"repo": "zitadel/zitadel",
|
||||||
"version": "v4.12.0",
|
"version": "v4.12.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-02T08:16:10Z"
|
"date": "2026-03-04T12:40:17Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "zoraxy",
|
"slug": "zoraxy",
|
||||||
@@ -1824,9 +1838,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "zwave-js-ui",
|
"slug": "zwave-js-ui",
|
||||||
"repo": "zwave-js/zwave-js-ui",
|
"repo": "zwave-js/zwave-js-ui",
|
||||||
"version": "v11.12.0",
|
"version": "v11.14.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-19T10:14:19Z"
|
"date": "2026-03-06T09:34:32Z"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 1,
|
"cpu": 1,
|
||||||
"ram": 512,
|
"ram": 512,
|
||||||
"hdd": 2,
|
"hdd": 4,
|
||||||
"os": "debian",
|
"os": "debian",
|
||||||
"version": "13"
|
"version": "13"
|
||||||
}
|
}
|
||||||
|
|||||||
50
frontend/public/json/netbird.json
Normal file
50
frontend/public/json/netbird.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"name": "NetBird",
|
||||||
|
"slug": "netbird",
|
||||||
|
"categories": [4],
|
||||||
|
"date_created": "2026-03-05",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": null,
|
||||||
|
"documentation": "https://docs.netbird.io/",
|
||||||
|
"website": "https://netbird.io/",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/netbird.webp",
|
||||||
|
"config_path": "/etc/netbird/config.json",
|
||||||
|
"description": "NetBird is an open source VPN management platform that creates secure peer-to-peer networks using WireGuard. It enables secure connectivity between devices anywhere in the world without complex firewall configurations or port forwarding. NetBird offers features like zero-configuration networking, SSO integration, access control policies, and a centralized management dashboard. It's designed to be simple to deploy and manage, making it ideal for connecting remote teams, securing IoT devices, or building secure infrastructure networks.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/netbird.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 1,
|
||||||
|
"ram": 512,
|
||||||
|
"hdd": 4,
|
||||||
|
"os": "debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "The NetBird client (agent) allows a peer to join a pre-existing NetBird deployment. If a NetBird deployment is not yet available, there are both managed and self-hosted options available.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "After installation, enter the container and run `netbird` to view the commands.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Use a Setup Key from your NetBird dashboard or SSO login to authenticate during setup or in the container.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Check connection status with `netbird status`.",
|
||||||
|
"type": "info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
56
frontend/public/json/papra.json
Normal file
56
frontend/public/json/papra.json
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"name": "Papra",
|
||||||
|
"slug": "papra",
|
||||||
|
"categories": [
|
||||||
|
12
|
||||||
|
],
|
||||||
|
"date_created": "2026-03-05",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 1221,
|
||||||
|
"documentation": "https://github.com/CorentinTh/papra",
|
||||||
|
"website": "https://github.com/CorentinTh/papra",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/papra.webp",
|
||||||
|
"config_path": "/opt/papra/.env",
|
||||||
|
"description": "Papra is a modern, self-hosted document management system with full-text search, OCR support, and automatic document processing. Built with Node.js and featuring a clean web interface for organizing and managing your documents.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/papra.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 2,
|
||||||
|
"ram": 2048,
|
||||||
|
"hdd": 10,
|
||||||
|
"os": "debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "First visit will prompt you to create an account",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Tesseract OCR is pre-installed for all languages",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Documents are stored in /opt/papra/app-data/documents",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ingestion folder available at /opt/papra/ingestion for automatic document import",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Email functionality runs in dry-run mode by default",
|
||||||
|
"type": "warning"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
40
frontend/public/json/powerdns.json
Normal file
40
frontend/public/json/powerdns.json
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "PowerDNS",
|
||||||
|
"slug": "powerdns",
|
||||||
|
"categories": [
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"date_created": "2026-03-02",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 80,
|
||||||
|
"documentation": "https://doc.powerdns.com/index.html",
|
||||||
|
"config_path": "/opt/poweradmin/config/settings.php",
|
||||||
|
"website": "https://www.powerdns.com/",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/powerdns.webp",
|
||||||
|
"description": "The PowerDNS Authoritative Server is a versatile nameserver which supports a large number of backends. These backends can either be plain zone files or be more dynamic in nature. PowerDNS has the concepts of ‘backends’. A backend is a datastore that the server will consult that contains DNS records (and some metadata). The backends range from database backends (MySQL, PostgreSQL) and BIND zone files to co-processes and JSON API’s.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/powerdns.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 1,
|
||||||
|
"ram": 1024,
|
||||||
|
"hdd": 4,
|
||||||
|
"os": "Debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "For administrator credentials type: `cat ~/poweradmin.creds` inside LXC.",
|
||||||
|
"type": "info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"documentation": "https://docs.rxresume.org/",
|
"documentation": "https://docs.rxresume.org/",
|
||||||
"website": "https://rxresume.org",
|
"website": "https://rxresume.org",
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/reactive-resume.webp",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/reactive-resume.webp",
|
||||||
"config_path": "/opt/reactive-resume/.env",
|
"config_path": "/opt/Reactive-Resume/.env",
|
||||||
"description": "A one-of-a-kind resume builder that keeps your privacy in mind. Completely secure, customizable, portable, open-source and free forever.",
|
"description": "A one-of-a-kind resume builder that keeps your privacy in mind. Completely secure, customizable, portable, open-source and free forever.",
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,6 +54,10 @@
|
|||||||
{
|
{
|
||||||
"text": "To see admin password on Alpine, type `cat ~/rustdesk.creds` inside LXC.",
|
"text": "To see admin password on Alpine, type `cat ~/rustdesk.creds` inside LXC.",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "This script uses hbbs/hbbr builds from `lejianwen/rustdesk-server` (instead of the official repo) for full compatibility with the RustDesk API (SSO/OAuth). See `https://github.com/community-scripts/ProxmoxVE/issues/12079`.",
|
||||||
|
"type": "info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
},
|
},
|
||||||
"notes": [
|
"notes": [
|
||||||
{
|
{
|
||||||
"text": "This instance uses BoltDB",
|
"text": "This instance uses SQLite",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Suwayomi-Server",
|
|
||||||
"slug": "suwayomi-server",
|
|
||||||
"categories": [
|
|
||||||
13
|
|
||||||
],
|
|
||||||
"date_created": "2025-08-01",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": 4567,
|
|
||||||
"documentation": "https://github.com/Suwayomi/Suwayomi-Server/wiki",
|
|
||||||
"website": "https://github.com/Suwayomi/Suwayomi-Server",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/suwayomi.webp",
|
|
||||||
"config_path": "",
|
|
||||||
"description": "A free and open source manga reader server that runs extensions built for Mihon (Tachiyomi).",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/suwayomiserver.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 1,
|
|
||||||
"ram": 1024,
|
|
||||||
"hdd": 4,
|
|
||||||
"os": "debian",
|
|
||||||
"version": "13"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": null,
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "This application can be conflicting with Kaspersky products. You maybe need to disable Kaspersky in order to use this application.",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "Alpine-Tinyauth",
|
"name": "Tinyauth",
|
||||||
"slug": "alpine-tinyauth",
|
"slug": "tinyauth",
|
||||||
"categories": [
|
"categories": [
|
||||||
6
|
6
|
||||||
],
|
],
|
||||||
"date_created": "2025-05-06",
|
"date_created": "2026-03-03",
|
||||||
"type": "ct",
|
"type": "ct",
|
||||||
"updateable": true,
|
"updateable": true,
|
||||||
"privileged": false,
|
"privileged": false,
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
"type": "default",
|
"type": "default",
|
||||||
"script": "ct/alpine-tinyauth.sh",
|
"script": "ct/tinyauth.sh",
|
||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 1,
|
"cpu": 1,
|
||||||
"ram": 256,
|
"ram": 512,
|
||||||
"hdd": 2,
|
"hdd": 4,
|
||||||
"os": "alpine",
|
"os": "debian",
|
||||||
"version": "3.23"
|
"version": "13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "UniFi Network Server",
|
|
||||||
"slug": "unifi",
|
|
||||||
"categories": [
|
|
||||||
4
|
|
||||||
],
|
|
||||||
"date_created": "2024-05-02",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": 8443,
|
|
||||||
"documentation": "https://help.ui.com/hc/en-us/articles/360012282453-Self-Hosting-a-UniFi-Network-Server",
|
|
||||||
"website": "https://www.ui.com/",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ubiquiti-unifi.webp",
|
|
||||||
"config_path": "",
|
|
||||||
"description": "UniFi Network Server is a software that helps manage and monitor UniFi networks (Wi-Fi, Ethernet, etc.) by providing an intuitive user interface and advanced features. It allows network administrators to configure, monitor, and upgrade network devices, as well as view network statistics, client devices, and historical events. The aim of the application is to make the management of UniFi networks easier and more efficient.",
|
|
||||||
"disable": true,
|
|
||||||
"disable_description": "This script is disabled because UniFi no longer delivers APT packages for Debian systems. The installation relies on APT repositories that are no longer maintained or available. For more details, see: https://github.com/community-scripts/ProxmoxVE/issues/11876",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/unifi.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 2,
|
|
||||||
"ram": 2048,
|
|
||||||
"hdd": 8,
|
|
||||||
"os": "debian",
|
|
||||||
"version": "12"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": null,
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "For non-AVX CPUs, MongoDB 4.4 is installed. Please note this is a legacy solution that may present security risks and could become unsupported in future updates.",
|
|
||||||
"type": "warning"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -2,42 +2,68 @@
|
|||||||
|
|
||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
|
|
||||||
|
import { githubGist, nord } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
||||||
import { CalendarIcon, Check, Clipboard, Download } from "lucide-react";
|
import { CalendarIcon, Check, Clipboard, Download } from "lucide-react";
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
import SyntaxHighlighter from "react-syntax-highlighter";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
import type { Category } from "@/lib/types";
|
import type { Category } from "@/lib/types";
|
||||||
|
|
||||||
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||||
import { Calendar } from "@/components/ui/calendar";
|
import { Calendar } from "@/components/ui/calendar";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
import { basePath } from "@/config/site-config";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
||||||
import { fetchCategories } from "@/lib/data";
|
import { fetchCategories } from "@/lib/data";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
import type { Script } from "./_schemas/schemas";
|
import type { Script } from "./_schemas/schemas";
|
||||||
|
|
||||||
|
import { ScriptItem } from "../scripts/_components/script-item";
|
||||||
import InstallMethod from "./_components/install-method";
|
import InstallMethod from "./_components/install-method";
|
||||||
import { ScriptSchema } from "./_schemas/schemas";
|
import { ScriptSchema } from "./_schemas/schemas";
|
||||||
import Categories from "./_components/categories";
|
import Categories from "./_components/categories";
|
||||||
import Note from "./_components/note";
|
import Note from "./_components/note";
|
||||||
|
|
||||||
import { githubGist, nord } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
function search(scripts: Script[], query: string): Script[] {
|
||||||
import SyntaxHighlighter from "react-syntax-highlighter";
|
const queryLower = query.toLowerCase().trim();
|
||||||
import { ScriptItem } from "../scripts/_components/script-item";
|
const searchWords = queryLower.split(/\s+/).filter(Boolean);
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
return scripts
|
||||||
import { search } from "@/components/command-menu";
|
.map((script) => {
|
||||||
import { basePath } from "@/config/site-config";
|
const nameLower = script.name.toLowerCase();
|
||||||
import Image from "next/image";
|
const descriptionLower = (script.description || "").toLowerCase();
|
||||||
import { useTheme } from "next-themes";
|
|
||||||
|
let score = 0;
|
||||||
|
|
||||||
|
for (const word of searchWords) {
|
||||||
|
if (nameLower.includes(word)) {
|
||||||
|
score += 10;
|
||||||
|
}
|
||||||
|
if (descriptionLower.includes(word)) {
|
||||||
|
score += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { script, score };
|
||||||
|
})
|
||||||
|
.filter(({ score }) => score > 0)
|
||||||
|
.sort((a, b) => b.score - a.score)
|
||||||
|
.slice(0, 20)
|
||||||
|
.map(({ script }) => script);
|
||||||
|
}
|
||||||
|
|
||||||
const initialScript: Script = {
|
const initialScript: Script = {
|
||||||
name: "",
|
name: "",
|
||||||
@@ -77,32 +103,32 @@ export default function JSONGenerator() {
|
|||||||
|
|
||||||
const selectedCategoryObj = useMemo(
|
const selectedCategoryObj = useMemo(
|
||||||
() => categories.find(cat => cat.id.toString() === selectedCategory),
|
() => categories.find(cat => cat.id.toString() === selectedCategory),
|
||||||
[categories, selectedCategory]
|
[categories, selectedCategory],
|
||||||
);
|
);
|
||||||
|
|
||||||
const allScripts = useMemo(
|
const allScripts = useMemo(
|
||||||
() => categories.flatMap(cat => cat.scripts || []),
|
() => categories.flatMap(cat => cat.scripts || []),
|
||||||
[categories]
|
[categories],
|
||||||
);
|
);
|
||||||
|
|
||||||
const scripts = useMemo(() => {
|
const scripts = useMemo(() => {
|
||||||
const query = searchQuery.trim()
|
const query = searchQuery.trim();
|
||||||
|
|
||||||
if (query) {
|
if (query) {
|
||||||
return search(allScripts, query)
|
return search(allScripts, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedCategoryObj) {
|
if (selectedCategoryObj) {
|
||||||
return selectedCategoryObj.scripts || []
|
return selectedCategoryObj.scripts || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return []
|
return [];
|
||||||
}, [allScripts, selectedCategoryObj, searchQuery]);
|
}, [allScripts, selectedCategoryObj, searchQuery]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchCategories()
|
fetchCategories()
|
||||||
.then(setCategories)
|
.then(setCategories)
|
||||||
.catch((error) => console.error("Error fetching categories:", error));
|
.catch(error => console.error("Error fetching categories:", error));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -122,11 +148,14 @@ export default function JSONGenerator() {
|
|||||||
|
|
||||||
if (updated.type === "pve") {
|
if (updated.type === "pve") {
|
||||||
scriptPath = `tools/pve/${updated.slug}.sh`;
|
scriptPath = `tools/pve/${updated.slug}.sh`;
|
||||||
} else if (updated.type === "addon") {
|
}
|
||||||
|
else if (updated.type === "addon") {
|
||||||
scriptPath = `tools/addon/${updated.slug}.sh`;
|
scriptPath = `tools/addon/${updated.slug}.sh`;
|
||||||
} else if (method.type === "alpine") {
|
}
|
||||||
|
else if (method.type === "alpine") {
|
||||||
scriptPath = `${updated.type}/alpine-${updated.slug}.sh`;
|
scriptPath = `${updated.type}/alpine-${updated.slug}.sh`;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
scriptPath = `${updated.type}/${updated.slug}.sh`;
|
scriptPath = `${updated.type}/${updated.slug}.sh`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,11 +174,13 @@ export default function JSONGenerator() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleCopy = useCallback(() => {
|
const handleCopy = useCallback(() => {
|
||||||
if (!isValid) toast.warning("JSON schema is invalid. Copying anyway.");
|
if (!isValid)
|
||||||
|
toast.warning("JSON schema is invalid. Copying anyway.");
|
||||||
navigator.clipboard.writeText(JSON.stringify(script, null, 2));
|
navigator.clipboard.writeText(JSON.stringify(script, null, 2));
|
||||||
setIsCopied(true);
|
setIsCopied(true);
|
||||||
setTimeout(() => setIsCopied(false), 2000);
|
setTimeout(() => setIsCopied(false), 2000);
|
||||||
if (isValid) toast.success("Copied metadata to clipboard");
|
if (isValid)
|
||||||
|
toast.success("Copied metadata to clipboard");
|
||||||
}, [script]);
|
}, [script]);
|
||||||
|
|
||||||
const importScript = (script: Script) => {
|
const importScript = (script: Script) => {
|
||||||
@@ -166,11 +197,11 @@ export default function JSONGenerator() {
|
|||||||
setIsValid(true);
|
setIsValid(true);
|
||||||
setZodErrors(null);
|
setZodErrors(null);
|
||||||
toast.success("Imported JSON successfully");
|
toast.success("Imported JSON successfully");
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
toast.error("Failed to read or parse the JSON file.");
|
toast.error("Failed to read or parse the JSON file.");
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const handleFileImport = useCallback(() => {
|
const handleFileImport = useCallback(() => {
|
||||||
const input = document.createElement("input");
|
const input = document.createElement("input");
|
||||||
@@ -180,7 +211,8 @@ export default function JSONGenerator() {
|
|||||||
input.onchange = (e: Event) => {
|
input.onchange = (e: Event) => {
|
||||||
const target = e.target as HTMLInputElement;
|
const target = e.target as HTMLInputElement;
|
||||||
const file = target.files?.[0];
|
const file = target.files?.[0];
|
||||||
if (!file) return;
|
if (!file)
|
||||||
|
return;
|
||||||
|
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = (event) => {
|
reader.onload = (event) => {
|
||||||
@@ -189,7 +221,8 @@ export default function JSONGenerator() {
|
|||||||
const parsed = JSON.parse(content);
|
const parsed = JSON.parse(content);
|
||||||
importScript(parsed);
|
importScript(parsed);
|
||||||
toast.success("Imported JSON successfully");
|
toast.success("Imported JSON successfully");
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
toast.error("Failed to read the JSON file.");
|
toast.error("Failed to read the JSON file.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -243,7 +276,10 @@ export default function JSONGenerator() {
|
|||||||
<div className="mt-2 space-y-1">
|
<div className="mt-2 space-y-1">
|
||||||
{zodErrors.issues.map((error, index) => (
|
{zodErrors.issues.map((error, index) => (
|
||||||
<AlertDescription key={index} className="p-1 text-red-500">
|
<AlertDescription key={index} className="p-1 text-red-500">
|
||||||
{error.path.join(".")} -{error.message}
|
{error.path.join(".")}
|
||||||
|
{" "}
|
||||||
|
-
|
||||||
|
{error.message}
|
||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -270,7 +306,7 @@ export default function JSONGenerator() {
|
|||||||
onOpenChange={setIsImportDialogOpen}
|
onOpenChange={setIsImportDialogOpen}
|
||||||
>
|
>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<DropdownMenuItem onSelect={(e) => e.preventDefault()}>
|
<DropdownMenuItem onSelect={e => e.preventDefault()}>
|
||||||
Import existing script
|
Import existing script
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
@@ -292,7 +328,7 @@ export default function JSONGenerator() {
|
|||||||
<SelectValue placeholder="Category" />
|
<SelectValue placeholder="Category" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{categories.map((category) => (
|
{categories.map(category => (
|
||||||
<SelectItem key={category.id} value={category.id.toString()}>
|
<SelectItem key={category.id} value={category.id.toString()}>
|
||||||
{category.name}
|
{category.name}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
@@ -302,17 +338,21 @@ export default function JSONGenerator() {
|
|||||||
<Input
|
<Input
|
||||||
placeholder="Search for a script..."
|
placeholder="Search for a script..."
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
onChange={(e) => setSearchQuery(e.target.value)}
|
onChange={e => setSearchQuery(e.target.value)}
|
||||||
/>
|
/>
|
||||||
{!selectedCategory && !searchQuery ? (
|
{!selectedCategory && !searchQuery
|
||||||
|
? (
|
||||||
<p className="text-muted-foreground text-sm text-center">
|
<p className="text-muted-foreground text-sm text-center">
|
||||||
Select a category or search for a script
|
Select a category or search for a script
|
||||||
</p>
|
</p>
|
||||||
) : scripts.length === 0 ? (
|
)
|
||||||
|
: scripts.length === 0
|
||||||
|
? (
|
||||||
<p className="text-muted-foreground text-sm text-center">
|
<p className="text-muted-foreground text-sm text-center">
|
||||||
No scripts found
|
No scripts found
|
||||||
</p>
|
</p>
|
||||||
) : (
|
)
|
||||||
|
: (
|
||||||
<div className="grid grid-cols-3 auto-rows-min h-64 overflow-y-auto gap-4">
|
<div className="grid grid-cols-3 auto-rows-min h-64 overflow-y-auto gap-4">
|
||||||
{scripts.map(script => (
|
{scripts.map(script => (
|
||||||
<div
|
<div
|
||||||
@@ -348,15 +388,19 @@ export default function JSONGenerator() {
|
|||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<Label>
|
<Label>
|
||||||
Name <span className="text-red-500">*</span>
|
Name
|
||||||
|
{" "}
|
||||||
|
<span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input placeholder="Example" value={script.name} onChange={(e) => updateScript("name", e.target.value)} />
|
<Input placeholder="Example" value={script.name} onChange={e => updateScript("name", e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label>
|
<Label>
|
||||||
Slug <span className="text-red-500">*</span>
|
Slug
|
||||||
|
{" "}
|
||||||
|
<span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input placeholder="example" value={script.slug} onChange={(e) => updateScript("slug", e.target.value)} />
|
<Input placeholder="example" value={script.slug} onChange={e => updateScript("slug", e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -366,7 +410,7 @@ export default function JSONGenerator() {
|
|||||||
<Input
|
<Input
|
||||||
placeholder="Full logo URL"
|
placeholder="Full logo URL"
|
||||||
value={script.logo || ""}
|
value={script.logo || ""}
|
||||||
onChange={(e) => updateScript("logo", e.target.value || null)}
|
onChange={e => updateScript("logo", e.target.value || null)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -374,24 +418,28 @@ export default function JSONGenerator() {
|
|||||||
<Input
|
<Input
|
||||||
placeholder="Path to config file"
|
placeholder="Path to config file"
|
||||||
value={script.config_path || ""}
|
value={script.config_path || ""}
|
||||||
onChange={(e) => updateScript("config_path", e.target.value || "")}
|
onChange={e => updateScript("config_path", e.target.value || "")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label>
|
<Label>
|
||||||
Description <span className="text-red-500">*</span>
|
Description
|
||||||
|
{" "}
|
||||||
|
<span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Textarea
|
<Textarea
|
||||||
placeholder="Example"
|
placeholder="Example"
|
||||||
value={script.description}
|
value={script.description}
|
||||||
onChange={(e) => updateScript("description", e.target.value)}
|
onChange={e => updateScript("description", e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Categories script={script} setScript={setScript} categories={categories} />
|
<Categories script={script} setScript={setScript} categories={categories} />
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<div className="flex flex-col gap-2 w-full">
|
<div className="flex flex-col gap-2 w-full">
|
||||||
<Label>
|
<Label>
|
||||||
Date Created <span className="text-red-500">*</span>
|
Date Created
|
||||||
|
{" "}
|
||||||
|
<span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild className="flex-1">
|
<PopoverTrigger asChild className="flex-1">
|
||||||
@@ -415,7 +463,7 @@ export default function JSONGenerator() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-2 w-full">
|
<div className="flex flex-col gap-2 w-full">
|
||||||
<Label>Type</Label>
|
<Label>Type</Label>
|
||||||
<Select value={script.type} onValueChange={(value) => updateScript("type", value)}>
|
<Select value={script.type} onValueChange={value => updateScript("type", value)}>
|
||||||
<SelectTrigger className="flex-1">
|
<SelectTrigger className="flex-1">
|
||||||
<SelectValue placeholder="Type" />
|
<SelectValue placeholder="Type" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -430,17 +478,17 @@ export default function JSONGenerator() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="w-full flex gap-5">
|
<div className="w-full flex gap-5">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Switch checked={script.updateable} onCheckedChange={(checked) => updateScript("updateable", checked)} />
|
<Switch checked={script.updateable} onCheckedChange={checked => updateScript("updateable", checked)} />
|
||||||
<label>Updateable</label>
|
<label>Updateable</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Switch checked={script.privileged} onCheckedChange={(checked) => updateScript("privileged", checked)} />
|
<Switch checked={script.privileged} onCheckedChange={checked => updateScript("privileged", checked)} />
|
||||||
<label>Privileged</label>
|
<label>Privileged</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Switch
|
<Switch
|
||||||
checked={script.disable || false}
|
checked={script.disable || false}
|
||||||
onCheckedChange={(checked) => updateScript("disable", checked)}
|
onCheckedChange={checked => updateScript("disable", checked)}
|
||||||
/>
|
/>
|
||||||
<label>Disabled</label>
|
<label>Disabled</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -448,12 +496,14 @@ export default function JSONGenerator() {
|
|||||||
{script.disable && (
|
{script.disable && (
|
||||||
<div>
|
<div>
|
||||||
<Label>
|
<Label>
|
||||||
Disable Description <span className="text-red-500">*</span>
|
Disable Description
|
||||||
|
{" "}
|
||||||
|
<span className="text-red-500">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Textarea
|
<Textarea
|
||||||
placeholder="Explain why this script is disabled..."
|
placeholder="Explain why this script is disabled..."
|
||||||
value={script.disable_description || ""}
|
value={script.disable_description || ""}
|
||||||
onChange={(e) => updateScript("disable_description", e.target.value)}
|
onChange={e => updateScript("disable_description", e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -461,18 +511,18 @@ export default function JSONGenerator() {
|
|||||||
placeholder="Interface Port"
|
placeholder="Interface Port"
|
||||||
type="number"
|
type="number"
|
||||||
value={script.interface_port || ""}
|
value={script.interface_port || ""}
|
||||||
onChange={(e) => updateScript("interface_port", e.target.value ? Number(e.target.value) : null)}
|
onChange={e => updateScript("interface_port", e.target.value ? Number(e.target.value) : null)}
|
||||||
/>
|
/>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Website URL"
|
placeholder="Website URL"
|
||||||
value={script.website || ""}
|
value={script.website || ""}
|
||||||
onChange={(e) => updateScript("website", e.target.value || null)}
|
onChange={e => updateScript("website", e.target.value || null)}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Documentation URL"
|
placeholder="Documentation URL"
|
||||||
value={script.documentation || ""}
|
value={script.documentation || ""}
|
||||||
onChange={(e) => updateScript("documentation", e.target.value || null)}
|
onChange={e => updateScript("documentation", e.target.value || null)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<InstallMethod script={script} setScript={setScript} setIsValid={setIsValid} setZodErrors={setZodErrors} />
|
<InstallMethod script={script} setScript={setScript} setIsValid={setIsValid} setZodErrors={setZodErrors} />
|
||||||
@@ -480,22 +530,20 @@ export default function JSONGenerator() {
|
|||||||
<Input
|
<Input
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
value={script.default_credentials.username || ""}
|
value={script.default_credentials.username || ""}
|
||||||
onChange={(e) =>
|
onChange={e =>
|
||||||
updateScript("default_credentials", {
|
updateScript("default_credentials", {
|
||||||
...script.default_credentials,
|
...script.default_credentials,
|
||||||
username: e.target.value || null,
|
username: e.target.value || null,
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
value={script.default_credentials.password || ""}
|
value={script.default_credentials.password || ""}
|
||||||
onChange={(e) =>
|
onChange={e =>
|
||||||
updateScript("default_credentials", {
|
updateScript("default_credentials", {
|
||||||
...script.default_credentials,
|
...script.default_credentials,
|
||||||
password: e.target.value || null,
|
password: e.target.value || null,
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<Note script={script} setScript={setScript} setIsValid={setIsValid} setZodErrors={setZodErrors} />
|
<Note script={script} setScript={setScript} setIsValid={setIsValid} setZodErrors={setZodErrors} />
|
||||||
</form>
|
</form>
|
||||||
@@ -504,7 +552,7 @@ export default function JSONGenerator() {
|
|||||||
<Tabs
|
<Tabs
|
||||||
defaultValue="json"
|
defaultValue="json"
|
||||||
className="w-full"
|
className="w-full"
|
||||||
onValueChange={(value) => setCurrentTab(value as "json" | "preview")}
|
onValueChange={value => setCurrentTab(value as "json" | "preview")}
|
||||||
value={currentTab}
|
value={currentTab}
|
||||||
>
|
>
|
||||||
<TabsList className="grid w-full grid-cols-2">
|
<TabsList className="grid w-full grid-cols-2">
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useRouter } from "next/navigation";
|
|
||||||
import { ArrowRightIcon, Sparkles } from "lucide-react";
|
import { ArrowRightIcon, Sparkles } from "lucide-react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import type { Category, Script } from "@/lib/types";
|
import type { Category, Script } from "@/lib/types";
|
||||||
@@ -21,35 +22,6 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/t
|
|||||||
import { DialogTitle } from "./ui/dialog";
|
import { DialogTitle } from "./ui/dialog";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
import { Badge } from "./ui/badge";
|
import { Badge } from "./ui/badge";
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
export function search(scripts: Script[], query: string): Script[] {
|
|
||||||
const queryLower = query.toLowerCase().trim();
|
|
||||||
const searchWords = queryLower.split(/\s+/).filter(Boolean);
|
|
||||||
|
|
||||||
return scripts
|
|
||||||
.map(script => {
|
|
||||||
const nameLower = script.name.toLowerCase();
|
|
||||||
const descriptionLower = (script.description || "").toLowerCase();
|
|
||||||
|
|
||||||
let score = 0;
|
|
||||||
|
|
||||||
for (const word of searchWords) {
|
|
||||||
if (nameLower.includes(word)) {
|
|
||||||
score += 10;
|
|
||||||
}
|
|
||||||
if (descriptionLower.includes(word)) {
|
|
||||||
score += 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { script, score };
|
|
||||||
})
|
|
||||||
.filter(({ score }) => score > 0)
|
|
||||||
.sort((a, b) => b.score - a.score)
|
|
||||||
.slice(0, 20)
|
|
||||||
.map(({ script }) => script);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formattedBadge(type: string) {
|
export function formattedBadge(type: string) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -79,11 +51,9 @@ function getRandomScript(categories: Category[], previouslySelected: Set<string>
|
|||||||
}
|
}
|
||||||
|
|
||||||
function CommandMenu() {
|
function CommandMenu() {
|
||||||
const [query, setQuery] = React.useState("");
|
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const [links, setLinks] = React.useState<Category[]>([]);
|
const [links, setLinks] = React.useState<Category[]>([]);
|
||||||
const [isLoading, setIsLoading] = React.useState(false);
|
const [isLoading, setIsLoading] = React.useState(false);
|
||||||
const [results, setResults] = React.useState<Script[]>([]);
|
|
||||||
const [selectedScripts, setSelectedScripts] = React.useState<Set<string>>(new Set());
|
const [selectedScripts, setSelectedScripts] = React.useState<Set<string>>(new Set());
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -100,27 +70,6 @@ function CommandMenu() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (query.trim() === "") {
|
|
||||||
fetchSortedCategories();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const scriptMap = new Map<string, Script>();
|
|
||||||
|
|
||||||
for (const category of links) {
|
|
||||||
for (const script of category.scripts || []) {
|
|
||||||
if (!scriptMap.has(script.slug)) {
|
|
||||||
scriptMap.set(script.slug, script);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const uniqueScripts = Array.from(scriptMap.values());
|
|
||||||
const filteredResults = search(uniqueScripts, query);
|
|
||||||
setResults(filteredResults);
|
|
||||||
}
|
|
||||||
}, [query]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
||||||
@@ -248,25 +197,27 @@ function CommandMenu() {
|
|||||||
|
|
||||||
<CommandDialog
|
<CommandDialog
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={setOpen}
|
||||||
setOpen(open);
|
filter={(value: string, search: string) => {
|
||||||
if (open) {
|
const searchLower = search.toLowerCase().trim();
|
||||||
setQuery("");
|
if (!searchLower)
|
||||||
setResults([]);
|
return 1;
|
||||||
}
|
const valueLower = value.toLowerCase();
|
||||||
|
const searchWords = searchLower.split(/\s+/).filter(Boolean);
|
||||||
|
// All search words must appear somewhere in the value (name + description)
|
||||||
|
const allWordsMatch = searchWords.every((word: string) => valueLower.includes(word));
|
||||||
|
return allWordsMatch ? 1 : 0;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogTitle className="sr-only">Search scripts</DialogTitle>
|
<DialogTitle className="sr-only">Search scripts</DialogTitle>
|
||||||
<CommandInput
|
<CommandInput placeholder="Search for a script..." />
|
||||||
placeholder="Search for a script..."
|
|
||||||
onValueChange={setQuery}
|
|
||||||
value={query}
|
|
||||||
/>
|
|
||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty>
|
<CommandEmpty>
|
||||||
{isLoading ? (
|
{isLoading
|
||||||
|
? (
|
||||||
"Searching..."
|
"Searching..."
|
||||||
) : (
|
)
|
||||||
|
: (
|
||||||
<div className="flex flex-col items-center justify-center py-6 text-center">
|
<div className="flex flex-col items-center justify-center py-6 text-center">
|
||||||
<p className="text-sm text-muted-foreground">No scripts match your search.</p>
|
<p className="text-sm text-muted-foreground">No scripts match your search.</p>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
@@ -277,51 +228,16 @@ function CommandMenu() {
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
Documentation <ArrowRightIcon className="ml-2 h-4 w-4" />
|
Documentation
|
||||||
|
{" "}
|
||||||
|
<ArrowRightIcon className="ml-2 h-4 w-4" />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</CommandEmpty>
|
</CommandEmpty>
|
||||||
|
{Object.entries(uniqueScriptsByCategory).map(([categoryName, scripts]) => (
|
||||||
{results.length > 0 ? (
|
|
||||||
<CommandGroup heading="Search Results">
|
|
||||||
{results.map(script => (
|
|
||||||
<CommandItem
|
|
||||||
key={`script:${script.slug}`}
|
|
||||||
value={`${script.name} ${script.type} ${script.description || ""}`}
|
|
||||||
onSelect={() => {
|
|
||||||
setOpen(false);
|
|
||||||
router.push(`/scripts?id=${script.slug}`);
|
|
||||||
}}
|
|
||||||
tabIndex={0}
|
|
||||||
aria-label={`Open script ${script.name}`}
|
|
||||||
onKeyDown={(e) => {
|
|
||||||
if (e.key === "Enter" || e.key === " ") {
|
|
||||||
setOpen(false);
|
|
||||||
router.push(`/scripts?id=${script.slug}`);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="flex gap-2" onClick={() => setOpen(false)}>
|
|
||||||
<Image
|
|
||||||
src={script.logo || `/${basePath}/logo.png`}
|
|
||||||
onError={e => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
|
||||||
unoptimized
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
alt=""
|
|
||||||
className="h-5 w-5"
|
|
||||||
/>
|
|
||||||
<span>{script.name}</span>
|
|
||||||
<span>{formattedBadge(script.type)}</span>
|
|
||||||
</div>
|
|
||||||
</CommandItem>
|
|
||||||
))}
|
|
||||||
</CommandGroup>
|
|
||||||
) : ( // When no search results, show all scripts grouped by category
|
|
||||||
Object.entries(uniqueScriptsByCategory).map(([categoryName, scripts]) => (
|
|
||||||
<CommandGroup key={`category:${categoryName}`} heading={categoryName}>
|
<CommandGroup key={`category:${categoryName}`} heading={categoryName}>
|
||||||
{scripts.map(script => (
|
{scripts.map(script => (
|
||||||
<CommandItem
|
<CommandItem
|
||||||
@@ -356,8 +272,7 @@ function CommandMenu() {
|
|||||||
</CommandItem>
|
</CommandItem>
|
||||||
))}
|
))}
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
))
|
))}
|
||||||
)}
|
|
||||||
</CommandList>
|
</CommandList>
|
||||||
</CommandDialog>
|
</CommandDialog>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
read -r -p "${TAB3}Enter PostgreSQL version (15/16/17): " ver
|
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}"
|
msg_info "Installing PostgreSQL ${ver}"
|
||||||
$STD apk add --no-cache postgresql${ver} postgresql${ver}-contrib postgresql${ver}-openrc sudo
|
$STD apk add --no-cache postgresql${ver} postgresql${ver}-contrib postgresql${ver}-openrc sudo
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ setting_up_container
|
|||||||
network_check
|
network_check
|
||||||
update_os
|
update_os
|
||||||
|
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
RELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
||||||
msg_info "Installing RustDesk Server v${RELEASE}"
|
msg_info "Installing RustDesk Server v${RELEASE}"
|
||||||
temp_file1=$(mktemp)
|
temp_file1=$(mktemp)
|
||||||
curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
|
curl -fsSL "https://github.com/lejianwen/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
|
||||||
$STD unzip "$temp_file1"
|
$STD unzip "$temp_file1"
|
||||||
mv amd64 /opt/rustdesk-server
|
mv amd64 /opt/rustdesk-server
|
||||||
mkdir -p /root/.config/rustdesk
|
mkdir -p /root/.config/rustdesk
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ msg_ok "Installed Tinyauth"
|
|||||||
read -r -p "${TAB3}Enter your Tinyauth subdomain (e.g. https://tinyauth.example.com): " app_url
|
read -r -p "${TAB3}Enter your Tinyauth subdomain (e.g. https://tinyauth.example.com): " app_url
|
||||||
|
|
||||||
cat <<EOF >/opt/tinyauth/.env
|
cat <<EOF >/opt/tinyauth/.env
|
||||||
DATABASE_PATH=/opt/tinyauth/database.db
|
TINYAUTH_DATABASE_PATH=/opt/tinyauth/database.db
|
||||||
USERS='${USER}'
|
TINYAUTH_AUTH_USERS='${USER}'
|
||||||
APP_URL=${app_url}
|
TINYAUTH_APPURL=${app_url}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ case $version in
|
|||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
msg_error "Invalid JDK version selected. Please enter 8, 11, 17 or 21."
|
msg_error "Invalid JDK version selected. Please enter 8, 11, 17 or 21."
|
||||||
exit 1
|
exit 64
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
@@ -39,7 +39,7 @@ case $version in
|
|||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
msg_error "Invalid JDK version selected. Please enter 11, 17 or 21."
|
msg_error "Invalid JDK version selected. Please enter 11, 17 or 21."
|
||||||
exit 1
|
exit 64
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
@@ -53,13 +53,13 @@ case $version in
|
|||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
msg_error "Invalid JDK version selected. Please enter 17 or 21."
|
msg_error "Invalid JDK version selected. Please enter 17 or 21."
|
||||||
exit 1
|
exit 64
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
msg_error "Invalid Tomcat version selected. Please enter 9, 10.1 or 11."
|
msg_error "Invalid Tomcat version selected. Please enter 9, 10.1 or 11."
|
||||||
exit 1
|
exit 64
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,12 @@ fetch_and_deploy_gh_release "bentopdf" "alam00000/bentopdf" "tarball" "latest" "
|
|||||||
msg_info "Setup BentoPDF"
|
msg_info "Setup BentoPDF"
|
||||||
cd /opt/bentopdf
|
cd /opt/bentopdf
|
||||||
$STD npm ci --no-audit --no-fund
|
$STD npm ci --no-audit --no-fund
|
||||||
|
$STD npm install http-server -g
|
||||||
|
cp ./.env.example ./.env.production
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=3072"
|
||||||
export SIMPLE_MODE=true
|
export SIMPLE_MODE=true
|
||||||
$STD npm run build -- --mode production
|
export VITE_USE_CDN=true
|
||||||
|
$STD npm run build:all
|
||||||
msg_ok "Setup BentoPDF"
|
msg_ok "Setup BentoPDF"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
@@ -31,8 +35,8 @@ After=network.target
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
WorkingDirectory=/opt/bentopdf
|
WorkingDirectory=/opt/bentopdf/dist
|
||||||
ExecStart=/usr/bin/npx serve dist -p 8080
|
ExecStart=/usr/bin/npx http-server -g -b -d false -r --no-dotfiles
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=10
|
RestartSec=10
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
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
|
if [[ -z "$JAR_PATH" ]]; then
|
||||||
msg_error "Backend JAR not found"
|
msg_error "Backend JAR not found"
|
||||||
exit 1
|
exit 153
|
||||||
fi
|
fi
|
||||||
cp "$JAR_PATH" /opt/booklore/dist/app.jar
|
cp "$JAR_PATH" /opt/booklore/dist/app.jar
|
||||||
msg_ok "Built Backend"
|
msg_ok "Built Backend"
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ setting_up_container
|
|||||||
network_check
|
network_check
|
||||||
update_os
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y build-essential
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
|
||||||
msg_info "Setup Cross-Seed"
|
msg_info "Setup Cross-Seed"
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ done
|
|||||||
# Install MongoDB Database Tools via direct .deb (no APT repo for Debian 13)
|
# Install MongoDB Database Tools via direct .deb (no APT repo for Debian 13)
|
||||||
[[ "$(get_os_info id)" == "ubuntu" ]] && MONGO_DIST="ubuntu2204" || MONGO_DIST="debian12"
|
[[ "$(get_os_info id)" == "ubuntu" ]] && MONGO_DIST="ubuntu2204" || MONGO_DIST="debian12"
|
||||||
MONGO_VERSION=$(get_latest_gh_tag "mongodb/mongo-tools" "100." || echo "100.14.1")
|
MONGO_VERSION=$(get_latest_gh_tag "mongodb/mongo-tools" "100." || echo "100.14.1")
|
||||||
fetch_and_deploy_from_url "https://fastdl.mongodb.org/tools/db/mongodb-database-tools-${MONGO_DIST}-x86_64-${MONGO_VERSION}.deb"
|
fetch_and_deploy_from_url "https://fastdl.mongodb.org/tools/db/mongodb-database-tools-${MONGO_DIST}-x86_64-${MONGO_VERSION}.deb" ""
|
||||||
mkdir -p /usr/local/mongodb-database-tools/bin
|
mkdir -p /usr/local/mongodb-database-tools/bin
|
||||||
[[ -f /usr/bin/mongodump ]] && ln -sf /usr/bin/mongodump /usr/local/mongodb-database-tools/bin/mongodump
|
[[ -f /usr/bin/mongodump ]] && ln -sf /usr/bin/mongodump /usr/local/mongodb-database-tools/bin/mongodump
|
||||||
[[ -f /usr/bin/mongorestore ]] && ln -sf /usr/bin/mongorestore /usr/local/mongodb-database-tools/bin/mongorestore
|
[[ -f /usr/bin/mongorestore ]] && ln -sf /usr/bin/mongorestore /usr/local/mongodb-database-tools/bin/mongorestore
|
||||||
|
|||||||
37
install/ddclient-install.sh
Normal file
37
install/ddclient-install.sh
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 mitchscobell
|
||||||
|
# Author: mitchscobell
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://ddclient.net/
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing ddclient"
|
||||||
|
DEBIAN_FRONTEND=noninteractive $STD apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -y ddclient
|
||||||
|
msg_ok "Installed ddclient"
|
||||||
|
|
||||||
|
msg_info "Creating ddclient service"
|
||||||
|
cat << EOF >/etc/ddclient.conf
|
||||||
|
protocol=namecheap
|
||||||
|
use=web, web=dynamicdns.park-your-domain.com/getip
|
||||||
|
protocol=namecheap
|
||||||
|
use=web, web=dynamicdns.park-your-domain.com/getip
|
||||||
|
server=dynamicdns.park-your-domain.com
|
||||||
|
login=yourdomain.com
|
||||||
|
password='your-ddns-password'
|
||||||
|
@,www
|
||||||
|
EOF
|
||||||
|
chmod 600 /etc/ddclient.conf
|
||||||
|
systemctl enable -q --now ddclient
|
||||||
|
msg_ok "Created ddclient service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -86,7 +86,7 @@ EOF
|
|||||||
msg_ok "Docker TCP socket available on $socket"
|
msg_ok "Docker TCP socket available on $socket"
|
||||||
else
|
else
|
||||||
msg_error "Docker failed to restart. Check journalctl -xeu docker.service"
|
msg_error "Docker failed to restart. Check journalctl -xeu docker.service"
|
||||||
exit 1
|
exit 150
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,17 @@ fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball"
|
|||||||
|
|
||||||
msg_info "Configuring Docmost (Patience)"
|
msg_info "Configuring Docmost (Patience)"
|
||||||
cd /opt/docmost
|
cd /opt/docmost
|
||||||
|
|
||||||
|
# Fix: Docmost EE (audit logs etc.) lives in a git submodule that is NOT
|
||||||
|
# included in GitHub tarballs. The community NoopAuditService exists but
|
||||||
|
# is only exported by CoreModule – child modules such as UserModule cannot
|
||||||
|
# resolve it. Making CoreModule @Global() exposes the token app-wide.
|
||||||
|
if [[ ! -f /opt/docmost/apps/server/src/ee/ee.module.ts ]] \
|
||||||
|
&& ! grep -q '@Global()' /opt/docmost/apps/server/src/core/core.module.ts 2>/dev/null; then
|
||||||
|
sed -i '/^ Module,$/a\ Global,' /opt/docmost/apps/server/src/core/core.module.ts
|
||||||
|
sed -i '/^@Module({$/i @Global()' /opt/docmost/apps/server/src/core/core.module.ts
|
||||||
|
fi
|
||||||
|
|
||||||
mv .env.example .env
|
mv .env.example .env
|
||||||
mkdir data
|
mkdir data
|
||||||
sed -i -e "s|APP_SECRET=.*|APP_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)|" \
|
sed -i -e "s|APP_SECRET=.*|APP_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)|" \
|
||||||
|
|||||||
@@ -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)
|
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
|
if [[ -z "$LATEST_VERSION" ]]; then
|
||||||
msg_error "Failed to determine latest EMQX version"
|
msg_error "Failed to determine latest EMQX version"
|
||||||
exit 1
|
exit 250
|
||||||
fi
|
fi
|
||||||
msg_ok "Latest version: v$LATEST_VERSION"
|
msg_ok "Latest version: v$LATEST_VERSION"
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y zip
|
$STD apt install -y \
|
||||||
|
build-essential \
|
||||||
|
zip
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
PG_VERSION="17" setup_postgresql
|
PG_VERSION="17" setup_postgresql
|
||||||
PG_DB_NAME="fluiddb" PG_DB_USER="fluiduser" setup_postgresql_db
|
PG_DB_NAME="fluiddb" PG_DB_USER="fluiduser" setup_postgresql_db
|
||||||
NODE_VERSION="20" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
fetch_and_deploy_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar" "tarball"
|
fetch_and_deploy_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar" "tarball"
|
||||||
|
|
||||||
msg_info "Configuring fluid-calendar"
|
msg_info "Configuring fluid-calendar"
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Authors: MickLesk (CanbiZ)
|
# Authors: MickLesk (CanbiZ) | Co-Authors: remz1337
|
||||||
# Co-Authors: remz1337
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://frigate.video/ | Github: https://github.com/blakeblackshear/frigate
|
# Source: https://frigate.video/ | Github: https://github.com/blakeblackshear/frigate
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ update_os
|
|||||||
source /etc/os-release
|
source /etc/os-release
|
||||||
if [[ "$VERSION_ID" != "12" ]]; then
|
if [[ "$VERSION_ID" != "12" ]]; then
|
||||||
msg_error "Frigate requires Debian 12 (Bookworm) due to Python 3.11 dependencies"
|
msg_error "Frigate requires Debian 12 (Bookworm) due to Python 3.11 dependencies"
|
||||||
exit 1
|
exit 238
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Converting APT sources to DEB822 format"
|
msg_info "Converting APT sources to DEB822 format"
|
||||||
@@ -85,6 +84,7 @@ $STD apt install -y \
|
|||||||
tclsh \
|
tclsh \
|
||||||
libopenblas-dev \
|
libopenblas-dev \
|
||||||
liblapack-dev \
|
liblapack-dev \
|
||||||
|
libgomp1 \
|
||||||
make \
|
make \
|
||||||
moreutils
|
moreutils
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
@@ -101,9 +101,16 @@ export NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
|||||||
export TOKENIZERS_PARALLELISM=true
|
export TOKENIZERS_PARALLELISM=true
|
||||||
export TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
export TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
||||||
export OPENCV_FFMPEG_LOGLEVEL=8
|
export OPENCV_FFMPEG_LOGLEVEL=8
|
||||||
|
export PYTHONWARNINGS="ignore:::numpy.core.getlimits"
|
||||||
export HAILORT_LOGGER_PATH=NONE
|
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"
|
msg_info "Building Nginx"
|
||||||
$STD bash /opt/frigate/docker/main/build_nginx.sh
|
$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
|
ldconfig
|
||||||
msg_ok "Built libUSB"
|
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"
|
msg_info "Installing Python Dependencies"
|
||||||
$STD pip3 install -r /opt/frigate/docker/main/requirements.txt
|
$STD pip3 install -r /opt/frigate/docker/main/requirements.txt
|
||||||
msg_ok "Installed Python Dependencies"
|
msg_ok "Installed Python Dependencies"
|
||||||
|
|
||||||
msg_info "Building Python Wheels (Patience)"
|
msg_info "Building Python Wheels (Patience)"
|
||||||
mkdir -p /wheels
|
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
|
$STD bash /opt/frigate/docker/main/build_pysqlite3.sh
|
||||||
for i in {1..3}; do
|
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
|
$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
|
done
|
||||||
msg_ok "Built Python Wheels"
|
msg_ok "Built Python Wheels"
|
||||||
|
|
||||||
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
|
NODE_VERSION="20" setup_nodejs
|
||||||
|
|
||||||
msg_info "Downloading Inference Models"
|
msg_info "Downloading Inference Models"
|
||||||
mkdir -p /models /openvino-model
|
mkdir -p /models /openvino-model
|
||||||
@@ -183,6 +196,10 @@ $STD pip3 install -U /wheels/*.whl
|
|||||||
ldconfig
|
ldconfig
|
||||||
msg_ok "Installed HailoRT Runtime"
|
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"
|
msg_info "Installing OpenVino"
|
||||||
$STD pip3 install -r /opt/frigate/docker/main/requirements-ov.txt
|
$STD pip3 install -r /opt/frigate/docker/main/requirements-ov.txt
|
||||||
msg_ok "Installed OpenVino"
|
msg_ok "Installed OpenVino"
|
||||||
@@ -209,6 +226,8 @@ $STD make version
|
|||||||
cd /opt/frigate/web
|
cd /opt/frigate/web
|
||||||
$STD npm install
|
$STD npm install
|
||||||
$STD npm run build
|
$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/
|
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
|
sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run
|
||||||
msg_ok "Built Frigate Application"
|
msg_ok "Built Frigate Application"
|
||||||
@@ -224,6 +243,19 @@ echo "tmpfs /tmp/cache tmpfs defaults 0 0" >>/etc/fstab
|
|||||||
cat <<EOF >/etc/frigate.env
|
cat <<EOF >/etc/frigate.env
|
||||||
DEFAULT_FFMPEG_VERSION="7.0"
|
DEFAULT_FFMPEG_VERSION="7.0"
|
||||||
INCLUDED_FFMPEG_VERSIONS="7.0:5.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
|
EOF
|
||||||
|
|
||||||
cat <<EOF >/config/config.yml
|
cat <<EOF >/config/config.yml
|
||||||
@@ -237,7 +269,6 @@ cameras:
|
|||||||
input_args: -re -stream_loop -1 -fflags +genpts
|
input_args: -re -stream_loop -1 -fflags +genpts
|
||||||
roles:
|
roles:
|
||||||
- detect
|
- detect
|
||||||
- rtmp
|
|
||||||
detect:
|
detect:
|
||||||
height: 1080
|
height: 1080
|
||||||
width: 1920
|
width: 1920
|
||||||
@@ -255,6 +286,7 @@ ffmpeg:
|
|||||||
detectors:
|
detectors:
|
||||||
detector01:
|
detector01:
|
||||||
type: openvino
|
type: openvino
|
||||||
|
device: AUTO
|
||||||
model:
|
model:
|
||||||
width: 300
|
width: 300
|
||||||
height: 300
|
height: 300
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ $STD apt install -y \
|
|||||||
build-essential \
|
build-essential \
|
||||||
openssl \
|
openssl \
|
||||||
sqlite3 \
|
sqlite3 \
|
||||||
unzip
|
unzip \
|
||||||
|
git
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
msg_info "Installing Bun"
|
msg_info "Installing Bun"
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ msg_ok "(2/5) Compiled libheif"
|
|||||||
msg_info "(3/5) Compiling libraw"
|
msg_info "(3/5) Compiling libraw"
|
||||||
SOURCE=${SOURCE_DIR}/libraw
|
SOURCE=${SOURCE_DIR}/libraw
|
||||||
: "${LIBRAW_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libraw.json)}"
|
: "${LIBRAW_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libraw.json)}"
|
||||||
$STD git clone https://github.com/libraw/libraw.git "$SOURCE"
|
$STD git clone https://github.com/LibRaw/LibRaw.git "$SOURCE"
|
||||||
cd "$SOURCE"
|
cd "$SOURCE"
|
||||||
$STD git reset --hard "$LIBRAW_REVISION"
|
$STD git reset --hard "$LIBRAW_REVISION"
|
||||||
$STD autoreconf --install
|
$STD autoreconf --install
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ fi
|
|||||||
|
|
||||||
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
||||||
msg_error "Unable to detect latest Kasm release URL."
|
msg_error "Unable to detect latest Kasm release URL."
|
||||||
exit 1
|
exit 250
|
||||||
fi
|
fi
|
||||||
msg_ok "Detected Kasm Workspaces version $KASM_VERSION"
|
msg_ok "Detected Kasm Workspaces version $KASM_VERSION"
|
||||||
|
|
||||||
|
|||||||
@@ -20,24 +20,8 @@ $STD apt install -y \
|
|||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
PG_VERSION="17" setup_postgresql
|
PG_VERSION="17" setup_postgresql
|
||||||
PYTHON_VERSION="3.13" setup_uv
|
PG_DB_NAME="litellm_db" PG_DB_USER="litellm" setup_postgresql_db
|
||||||
|
PYTHON_VERSION="3.13" USE_UVX="YES" setup_uv
|
||||||
msg_info "Setting up PostgreSQL"
|
|
||||||
DB_NAME="litellm_db"
|
|
||||||
DB_USER="litellm"
|
|
||||||
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
|
|
||||||
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
|
|
||||||
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
|
|
||||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
|
|
||||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
|
|
||||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
|
|
||||||
{
|
|
||||||
echo "${APPLICATION} Credentials"
|
|
||||||
echo "Database Name: $DB_NAME"
|
|
||||||
echo "Database User: $DB_USER"
|
|
||||||
echo "Database Password: $DB_PASS"
|
|
||||||
} >>~/litellm.creds
|
|
||||||
msg_ok "Set up PostgreSQL"
|
|
||||||
|
|
||||||
msg_info "Setting up Virtual Environment"
|
msg_info "Setting up Virtual Environment"
|
||||||
mkdir -p /opt/litellm
|
mkdir -p /opt/litellm
|
||||||
@@ -53,10 +37,9 @@ mkdir -p /opt
|
|||||||
cat <<EOF >/opt/litellm/litellm.yaml
|
cat <<EOF >/opt/litellm/litellm.yaml
|
||||||
general_settings:
|
general_settings:
|
||||||
master_key: sk-1234
|
master_key: sk-1234
|
||||||
database_url: postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME
|
database_url: postgresql://$PG_DB_USER:$PG_DB_PASS@127.0.0.1:5432/$PG_DB_NAME
|
||||||
store_model_in_db: true
|
store_model_in_db: true
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
|
uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
|
||||||
msg_ok "Configured LiteLLM"
|
msg_ok "Configured LiteLLM"
|
||||||
|
|
||||||
@@ -73,7 +56,6 @@ Restart=always
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl enable -q --now litellm
|
systemctl enable -q --now litellm
|
||||||
msg_ok "Created Service"
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
|||||||
180
install/netbird-install.sh
Normal file
180
install/netbird-install.sh
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: TechHutTV
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://netbird.io/
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing NetBird"
|
||||||
|
setup_deb822_repo \
|
||||||
|
"netbird" \
|
||||||
|
"https://pkgs.netbird.io/debian/public.key" \
|
||||||
|
"https://pkgs.netbird.io/debian" \
|
||||||
|
"stable"
|
||||||
|
$STD apt install -y netbird
|
||||||
|
msg_ok "Installed NetBird"
|
||||||
|
|
||||||
|
msg_info "Starting NetBird Service"
|
||||||
|
systemctl enable -q --now netbird
|
||||||
|
msg_ok "Started NetBird Service"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo -e "${BL}NetBird Deployment Type${CL}"
|
||||||
|
echo "─────────────────────────────────────────"
|
||||||
|
echo "Are you using NetBird Managed or Self-Hosted?"
|
||||||
|
echo ""
|
||||||
|
echo " 1) NetBird Managed (default) - Use NetBird's managed service"
|
||||||
|
echo " 2) Self-Hosted - Use your own NetBird management server"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -r -p "${TAB3}Select deployment type [1]: " DEPLOYMENT_TYPE
|
||||||
|
DEPLOYMENT_TYPE="${DEPLOYMENT_TYPE:-1}"
|
||||||
|
|
||||||
|
NETBIRD_MGMT_URL=""
|
||||||
|
case "$DEPLOYMENT_TYPE" in
|
||||||
|
1)
|
||||||
|
msg_ok "Using NetBird Managed service"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
echo ""
|
||||||
|
echo -e "${BL}Self-Hosted Configuration${CL}"
|
||||||
|
echo "─────────────────────────────────────────"
|
||||||
|
echo "Enter your NetBird management server URL."
|
||||||
|
echo "Example: https://management.example.com"
|
||||||
|
echo ""
|
||||||
|
read -r -p "Management URL: " NETBIRD_MGMT_URL
|
||||||
|
|
||||||
|
if [[ -z "$NETBIRD_MGMT_URL" ]]; then
|
||||||
|
msg_warn "No management URL provided. Run 'netbird up --management-url <url>' to connect."
|
||||||
|
else
|
||||||
|
NETBIRD_MGMT_URL="${NETBIRD_MGMT_URL%/}"
|
||||||
|
msg_ok "Management URL configured: ${NETBIRD_MGMT_URL}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
msg_warn "Invalid selection. Using NetBird Managed service."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo -e "${BL}NetBird Connection Setup${CL}"
|
||||||
|
echo "─────────────────────────────────────────"
|
||||||
|
echo "Choose how to connect to your NetBird network:"
|
||||||
|
echo ""
|
||||||
|
if [[ "$DEPLOYMENT_TYPE" == "1" ]]; then
|
||||||
|
echo " 1) Setup Key (default) - Use a pre-generated setup key"
|
||||||
|
echo " 2) SSO Login - Authenticate via browser with your identity provider"
|
||||||
|
echo " 3) Skip - Configure later with 'netbird up'"
|
||||||
|
else
|
||||||
|
echo " 1) Setup Key (default) - Use a pre-generated setup key"
|
||||||
|
echo " 2) Skip - Configure later with 'netbird up'"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -r -p "Select authentication method [1]: " AUTH_METHOD
|
||||||
|
AUTH_METHOD="${AUTH_METHOD:-1}"
|
||||||
|
|
||||||
|
if [[ "$DEPLOYMENT_TYPE" == "1" ]]; then
|
||||||
|
case "$AUTH_METHOD" in
|
||||||
|
1)
|
||||||
|
echo ""
|
||||||
|
echo "Enter your NetBird setup key from the NetBird dashboard."
|
||||||
|
echo ""
|
||||||
|
read -r -p "Setup key: " NETBIRD_SETUP_KEY
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ -z "$NETBIRD_SETUP_KEY" ]]; then
|
||||||
|
msg_warn "No setup key provided. Run 'netbird up -k <key>' to connect."
|
||||||
|
else
|
||||||
|
msg_info "Connecting to NetBird with setup key"
|
||||||
|
if $STD netbird up -k "$NETBIRD_SETUP_KEY"; then
|
||||||
|
msg_ok "Connected to NetBird"
|
||||||
|
else
|
||||||
|
msg_warn "Connection failed. Run 'netbird up -k <key>' to retry."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
echo ""
|
||||||
|
echo -e "${BL}SSO Authentication${CL}"
|
||||||
|
echo "─────────────────────────────────────────"
|
||||||
|
echo "A login URL will appear below."
|
||||||
|
echo "Copy the URL and open it in your browser to authenticate."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
msg_info "Starting SSO login"
|
||||||
|
netbird login 2>&1 || true
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
msg_info "Connecting to NetBird"
|
||||||
|
if $STD netbird up; then
|
||||||
|
msg_ok "Connected to NetBird"
|
||||||
|
else
|
||||||
|
msg_warn "Connection failed. Run 'netbird up' to retry."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
msg_ok "Skipped. Run 'netbird up' to connect."
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
msg_warn "Invalid selection. Run 'netbird up' to connect."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
case "$AUTH_METHOD" in
|
||||||
|
1)
|
||||||
|
echo ""
|
||||||
|
echo "Enter your NetBird setup key from the NetBird dashboard."
|
||||||
|
echo ""
|
||||||
|
read -r -p "Setup key: " NETBIRD_SETUP_KEY
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ -z "$NETBIRD_SETUP_KEY" ]]; then
|
||||||
|
if [[ -z "$NETBIRD_MGMT_URL" ]]; then
|
||||||
|
msg_warn "No setup key provided. Run 'netbird up -k <key> --management-url <url>' to connect."
|
||||||
|
else
|
||||||
|
msg_warn "No setup key provided. Run 'netbird up -k <key> --management-url $NETBIRD_MGMT_URL' to connect."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ -z "$NETBIRD_MGMT_URL" ]]; then
|
||||||
|
msg_error "Management URL is required for self-hosted deployments. Please configure it first."
|
||||||
|
else
|
||||||
|
msg_info "Connecting to NetBird with setup key"
|
||||||
|
if $STD netbird up -k "$NETBIRD_SETUP_KEY" --management-url "$NETBIRD_MGMT_URL"; then
|
||||||
|
msg_ok "Connected to NetBird"
|
||||||
|
else
|
||||||
|
msg_warn "Connection failed. Run 'netbird up -k <key> --management-url $NETBIRD_MGMT_URL' to retry."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
if [[ -z "$NETBIRD_MGMT_URL" ]]; then
|
||||||
|
msg_ok "Skipped. Run 'netbird up --management-url <url>' to connect."
|
||||||
|
else
|
||||||
|
msg_ok "Skipped. Run 'netbird up --management-url $NETBIRD_MGMT_URL' to connect."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [[ -z "$NETBIRD_MGMT_URL" ]]; then
|
||||||
|
msg_warn "Invalid selection. Run 'netbird up --management-url <url>' to connect."
|
||||||
|
else
|
||||||
|
msg_warn "Invalid selection. Run 'netbird up --management-url $NETBIRD_MGMT_URL' to connect."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -51,7 +51,7 @@ while true; do
|
|||||||
attempts=$((attempts + 1))
|
attempts=$((attempts + 1))
|
||||||
if [[ "$attempts" -ge 3 ]]; then
|
if [[ "$attempts" -ge 3 ]]; then
|
||||||
msg_error "Maximum attempts reached. Exiting."
|
msg_error "Maximum attempts reached. Exiting."
|
||||||
exit 1
|
exit 254
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -76,11 +76,11 @@ for i in {1..60}; do
|
|||||||
elif [[ "$STATUS" == "unhealthy" ]]; then
|
elif [[ "$STATUS" == "unhealthy" ]]; then
|
||||||
msg_error "NPMplus container is unhealthy! Check logs."
|
msg_error "NPMplus container is unhealthy! Check logs."
|
||||||
docker logs "$CONTAINER_ID"
|
docker logs "$CONTAINER_ID"
|
||||||
exit 1
|
exit 150
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
sleep 2
|
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
|
done
|
||||||
msg_ok "Builded and started NPMplus"
|
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}"
|
msg_ok "Installed Ollama ${RELEASE}"
|
||||||
else
|
else
|
||||||
msg_error "Extraction failed – archive corrupt or incomplete"
|
msg_error "Extraction failed – archive corrupt or incomplete"
|
||||||
exit 1
|
exit 251
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
msg_error "Download failed – $OLLAMA_URL not reachable"
|
msg_error "Download failed – $OLLAMA_URL not reachable"
|
||||||
exit 1
|
exit 250
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Creating ollama User and Group"
|
msg_info "Creating ollama User and Group"
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ EOF
|
|||||||
else
|
else
|
||||||
msg_error "Failed to download or verify GPG key from $KEY_URL"
|
msg_error "Failed to download or verify GPG key from $KEY_URL"
|
||||||
[[ -f "$TMP_KEY_CONTENT" ]] && rm -f "$TMP_KEY_CONTENT"
|
[[ -f "$TMP_KEY_CONTENT" ]] && rm -f "$TMP_KEY_CONTENT"
|
||||||
exit 1
|
exit 250
|
||||||
fi
|
fi
|
||||||
rm -f "$TMP_KEY_CONTENT"
|
rm -f "$TMP_KEY_CONTENT"
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ for server in "${servers[@]}"; do
|
|||||||
done
|
done
|
||||||
if ((attempt >= MAX_ATTEMPTS)); then
|
if ((attempt >= MAX_ATTEMPTS)); then
|
||||||
msg_error "No more attempts - aborting script!"
|
msg_error "No more attempts - aborting script!"
|
||||||
exit 1
|
exit 254
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
79
install/papra-install.sh
Normal file
79
install/papra-install.sh
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/papra-hq/papra
|
||||||
|
|
||||||
|
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 \
|
||||||
|
tesseract-ocr \
|
||||||
|
tesseract-ocr-all
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
RELEASE=$(curl -fsSL https://api.github.com/repos/papra-hq/papra/releases | grep -oP '"tag_name":\s*"\K@papra/app@[^"]+' | head -n1)
|
||||||
|
fetch_and_deploy_gh_release "papra" "papra-hq/papra" "tarball" "${RELEASE}" "/opt/papra"
|
||||||
|
|
||||||
|
pnpm_version=$(grep -oP '"packageManager":\s*"pnpm@\K[^"]+' /opt/papra/package.json)
|
||||||
|
NODE_VERSION="24" NODE_MODULE="pnpm@$pnpm_version" setup_nodejs
|
||||||
|
|
||||||
|
msg_info "Installing Papra (Patience)"
|
||||||
|
cd /opt/papra
|
||||||
|
$STD pnpm install --frozen-lockfile
|
||||||
|
$STD pnpm --filter "@papra/app-client..." run build
|
||||||
|
$STD pnpm --filter "@papra/app-server..." run build
|
||||||
|
ln -sf /opt/papra/apps/papra-client/dist /opt/papra/apps/papra-server/public
|
||||||
|
msg_ok "Installed Papra"
|
||||||
|
|
||||||
|
msg_info "Configuring Papra"
|
||||||
|
mkdir -p /opt/papra_data/{db,documents,ingestion}
|
||||||
|
[[ ! -f /opt/papra_data/.secret ]] && openssl rand -hex 32 >/opt/papra_data/.secret
|
||||||
|
cat <<EOF >/opt/papra/apps/papra-server/.env
|
||||||
|
NODE_ENV=production
|
||||||
|
SERVER_SERVE_PUBLIC_DIR=true
|
||||||
|
PORT=1221
|
||||||
|
DATABASE_URL=file:/opt/papra_data/db/db.sqlite
|
||||||
|
DOCUMENT_STORAGE_FILESYSTEM_ROOT=/opt/papra_data/documents
|
||||||
|
PAPRA_CONFIG_DIR=/opt/papra_data
|
||||||
|
AUTH_SECRET=$(cat /opt/papra_data/.secret)
|
||||||
|
BETTER_AUTH_SECRET=$(cat /opt/papra_data/.secret)
|
||||||
|
BETTER_AUTH_TELEMETRY=0
|
||||||
|
CLIENT_BASE_URL=http://${LOCAL_IP}:1221
|
||||||
|
SERVER_BASE_URL=http://${LOCAL_IP}:1221
|
||||||
|
EMAILS_DRY_RUN=true
|
||||||
|
INGESTION_FOLDER_IS_ENABLED=true
|
||||||
|
INGESTION_FOLDER_ROOT_PATH=/opt/papra_data/ingestion
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured Papra"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/papra.service
|
||||||
|
[Unit]
|
||||||
|
Description=Papra Document Management
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/opt/papra/apps/papra-server
|
||||||
|
EnvironmentFile=/opt/papra/apps/papra-server/.env
|
||||||
|
ExecStartPre=/usr/bin/pnpm run migrate:up
|
||||||
|
ExecStart=/usr/bin/node dist/index.js
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now papra
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -16,7 +16,7 @@ update_os
|
|||||||
read -r -p "${TAB3}Enter PostgreSQL version (15/16/17/18): " ver
|
read -r -p "${TAB3}Enter PostgreSQL version (15/16/17/18): " ver
|
||||||
[[ $ver =~ ^(15|16|17|18)$ ]] || {
|
[[ $ver =~ ^(15|16|17|18)$ ]] || {
|
||||||
echo "Invalid version"
|
echo "Invalid version"
|
||||||
exit 1
|
exit 64
|
||||||
}
|
}
|
||||||
PG_VERSION=$ver setup_postgresql
|
PG_VERSION=$ver setup_postgresql
|
||||||
|
|
||||||
|
|||||||
144
install/powerdns-install.sh
Normal file
144
install/powerdns-install.sh
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: Slaviša Arežina (tremor021)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://www.powerdns.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 sqlite3
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
PHP_VERSION="8.3" PHP_APACHE="YES" PHP_FPM="YES" PHP_MODULE="gettext,tokenizer,sqlite3,ldap" setup_php
|
||||||
|
setup_deb822_repo \
|
||||||
|
"pdns" \
|
||||||
|
"https://repo.powerdns.com/FD380FBB-pub.asc" \
|
||||||
|
"http://repo.powerdns.com/debian" \
|
||||||
|
"trixie-auth-50"
|
||||||
|
|
||||||
|
cat <<EOF >/etc/apt/preferences.d/auth-50
|
||||||
|
Package: pdns-*
|
||||||
|
Pin: origin repo.powerdns.com
|
||||||
|
Pin-Priority: 600
|
||||||
|
EOF
|
||||||
|
|
||||||
|
escape_sql() {
|
||||||
|
printf '%s' "$1" | sed "s/'/''/g"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_info "Setting up PowerDNS"
|
||||||
|
$STD apt install -y \
|
||||||
|
pdns-server \
|
||||||
|
pdns-backend-sqlite3
|
||||||
|
sed -i 's/^launch=$/# launch=/' /etc/powerdns/pdns.conf
|
||||||
|
rm -f /etc/powerdns/pdns.d/bind.conf
|
||||||
|
cat <<EOF >/etc/powerdns/pdns.d/gsqlite3.conf
|
||||||
|
launch=gsqlite3
|
||||||
|
gsqlite3-database=/opt/poweradmin/powerdns.db
|
||||||
|
EOF
|
||||||
|
msg_ok "Setup PowerDNS"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "poweradmin" "poweradmin/poweradmin" "tarball"
|
||||||
|
|
||||||
|
msg_info "Setting up Poweradmin"
|
||||||
|
sqlite3 /opt/poweradmin/powerdns.db </opt/poweradmin/sql/poweradmin-sqlite-db-structure.sql
|
||||||
|
sqlite3 /opt/poweradmin/powerdns.db </opt/poweradmin/sql/pdns/49/schema.sqlite3.sql
|
||||||
|
PA_ADMIN_USERNAME="admin"
|
||||||
|
PA_ADMIN_EMAIL="admin@example.com"
|
||||||
|
PA_ADMIN_FULLNAME="Administrator"
|
||||||
|
PA_ADMIN_PASSWORD=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
|
||||||
|
PA_SESSION_KEY=$(openssl rand -base64 75 | tr -dc 'A-Za-z0-9^@#!(){}[]%_\-+=~' | head -c 50)
|
||||||
|
PASSWORD_HASH=$(php -r "echo password_hash(\$argv[1], PASSWORD_DEFAULT);" -- "${PA_ADMIN_PASSWORD}" 2>/dev/null)
|
||||||
|
sqlite3 /opt/poweradmin/powerdns.db "INSERT INTO users (username, password, fullname, email, description, perm_templ, active, use_ldap) \
|
||||||
|
VALUES ('$(escape_sql "${PA_ADMIN_USERNAME}")', '$(escape_sql "${PASSWORD_HASH}")', '$(escape_sql "${PA_ADMIN_FULLNAME}")', \
|
||||||
|
'$(escape_sql "${PA_ADMIN_EMAIL}")', 'System Administrator', 1, 1, 0);"
|
||||||
|
|
||||||
|
cat <<EOF >~/poweradmin.creds
|
||||||
|
Admin Username: ${PA_ADMIN_USERNAME}
|
||||||
|
Admin Password: ${PA_ADMIN_PASSWORD}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF >/opt/poweradmin/config/settings.php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Poweradmin Settings Configuration File
|
||||||
|
*
|
||||||
|
* Generated by the installer on 2026-02-02 21:01:40
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
/**
|
||||||
|
* Database Settings
|
||||||
|
*/
|
||||||
|
'database' => [
|
||||||
|
'type' => 'sqlite',
|
||||||
|
'file' => '/opt/poweradmin/powerdns.db',
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security Settings
|
||||||
|
*/
|
||||||
|
'security' => [
|
||||||
|
'session_key' => '${PA_SESSION_KEY}',
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface Settings
|
||||||
|
*/
|
||||||
|
'interface' => [
|
||||||
|
'language' => 'en_EN',
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DNS Settings
|
||||||
|
*/
|
||||||
|
'dns' => [
|
||||||
|
'hostmaster' => 'localhost.lan',
|
||||||
|
'ns1' => '8.8.8.8',
|
||||||
|
'ns2' => '9.9.9.9',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
EOF
|
||||||
|
rm -rf /opt/poweradmin/install
|
||||||
|
msg_ok "Setup Poweradmin"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
rm /etc/apache2/sites-enabled/000-default.conf
|
||||||
|
cat <<EOF >/etc/apache2/sites-enabled/poweradmin.conf
|
||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName localhost
|
||||||
|
DocumentRoot /opt/poweradmin
|
||||||
|
|
||||||
|
<Directory /opt/poweradmin>
|
||||||
|
Options -Indexes +FollowSymLinks
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# For DDNS update functionality
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteRule ^/update(.*)\$ /dynamic_update.php [L]
|
||||||
|
RewriteRule ^/nic/update(.*)\$ /dynamic_update.php [L]
|
||||||
|
</VirtualHost>
|
||||||
|
EOF
|
||||||
|
$STD a2enmod rewrite headers
|
||||||
|
chown -R www-data:pdns /opt/poweradmin
|
||||||
|
chmod 775 /opt/poweradmin
|
||||||
|
chown pdns:pdns /opt/poweradmin/powerdns.db
|
||||||
|
chmod 664 /opt/poweradmin/powerdns.db
|
||||||
|
usermod -aG pdns www-data
|
||||||
|
$STD systemctl restart pdns apache2
|
||||||
|
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"
|
msg_ok "Created User"
|
||||||
else
|
else
|
||||||
msg_error "User creation failed"
|
msg_error "User creation failed"
|
||||||
exit 1
|
exit 71
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p /etc/pulse
|
mkdir -p /etc/pulse
|
||||||
|
|||||||
@@ -13,10 +13,13 @@ setting_up_container
|
|||||||
network_check
|
network_check
|
||||||
update_os
|
update_os
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "rustdesk-hbbr" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbr*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-hbbr" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbr*amd64.deb"
|
||||||
fetch_and_deploy_gh_release "rustdesk-hbbs" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbs*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-hbbs" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbs*amd64.deb"
|
||||||
fetch_and_deploy_gh_release "rustdesk-utils" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-utils" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*amd64.deb"
|
||||||
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*amd64.deb"
|
||||||
|
systemctl enable -q --now rustdesk-hbbr
|
||||||
|
systemctl enable -q --now rustdesk-hbbs
|
||||||
|
systemctl enable -q --now rustdesk-api
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
customize
|
customize
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ SEM_KEY=$(openssl rand -base64 32)
|
|||||||
SEM_PW=$(openssl rand -base64 12)
|
SEM_PW=$(openssl rand -base64 12)
|
||||||
cat <<EOF >/opt/semaphore/config.json
|
cat <<EOF >/opt/semaphore/config.json
|
||||||
{
|
{
|
||||||
"bolt": {
|
"sqlite": {
|
||||||
"host": "/opt/semaphore/semaphore_db.bolt"
|
"host": "/opt/semaphore/database.sqlite"
|
||||||
},
|
},
|
||||||
|
"dialect": "sqlite",
|
||||||
"tmp_path": "/opt/semaphore/tmp",
|
"tmp_path": "/opt/semaphore/tmp",
|
||||||
"cookie_hash": "${SEM_HASH}",
|
"cookie_hash": "${SEM_HASH}",
|
||||||
"cookie_encryption": "${SEM_ENCRYPTION}",
|
"cookie_encryption": "${SEM_ENCRYPTION}",
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ while true; do
|
|||||||
[Nn]|[Nn][Oo]|"")
|
[Nn]|[Nn][Oo]|"")
|
||||||
msg_error "Terms not accepted. Installation cannot proceed."
|
msg_error "Terms not accepted. Installation cannot proceed."
|
||||||
msg_error "Please review the terms and run the script again if you wish to 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."
|
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|')
|
RELEASE=$(echo "$DOWNLOAD_URL" | sed 's|.*/releases/\([^/]*\)/.*|\1|')
|
||||||
$STD curl -fsSL -o "splunk-enterprise.tgz" "$DOWNLOAD_URL" || {
|
$STD curl -fsSL -o "splunk-enterprise.tgz" "$DOWNLOAD_URL" || {
|
||||||
msg_error "Failed to download Splunk Enterprise from the provided link."
|
msg_error "Failed to download Splunk Enterprise from the provided link."
|
||||||
exit 1
|
exit 250
|
||||||
}
|
}
|
||||||
$STD tar -xzf "splunk-enterprise.tgz" -C /opt
|
$STD tar -xzf "splunk-enterprise.tgz" -C /opt
|
||||||
rm -f "splunk-enterprise.tgz"
|
rm -f "splunk-enterprise.tgz"
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ $STD apt install -y \
|
|||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
PYTHON_VERSION="3.12" setup_uv
|
PYTHON_VERSION="3.12" setup_uv
|
||||||
JAVA_VERSION="21" setup_java
|
JAVA_VERSION="25" setup_java
|
||||||
|
|
||||||
read -r -p "${TAB3}Do you want to use Stirling-PDF with Login? (no/n = without Login) [Y/n] " response
|
read -r -p "${TAB3}Do you want to use Stirling-PDF with Login? (no/n = without Login) [Y/n] " response
|
||||||
response=${response,,} # Convert to lowercase
|
response=${response,,} # Convert to lowercase
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Slaviša Arežina (tremor021)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/Suwayomi/Suwayomi-Server
|
|
||||||
|
|
||||||
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 libc++-dev
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
JAVA_VERSION=21 setup_java
|
|
||||||
fetch_and_deploy_gh_release "suwayomi-server" "Suwayomi/Suwayomi-Server" "binary"
|
|
||||||
|
|
||||||
msg_info "Creating Service"
|
|
||||||
cat <<EOF >/etc/systemd/system/suwayomi-server.service
|
|
||||||
[Unit]
|
|
||||||
Description=Suwayomi-Server Service
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/usr/bin/suwayomi-server
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
systemctl enable -q --now suwayomi-server
|
|
||||||
msg_ok "Created Service"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -27,6 +27,8 @@ PG_VERSION="17" setup_postgresql
|
|||||||
PG_DB_NAME="tianji_db" PG_DB_USER="tianji" setup_postgresql_db
|
PG_DB_NAME="tianji_db" PG_DB_USER="tianji" setup_postgresql_db
|
||||||
PYTHON_VERSION="3.13" setup_uv
|
PYTHON_VERSION="3.13" setup_uv
|
||||||
fetch_and_deploy_gh_release "tianji" "msgbyte/tianji" "tarball"
|
fetch_and_deploy_gh_release "tianji" "msgbyte/tianji" "tarball"
|
||||||
|
TIANJI_SECRET=$(openssl rand -base64 256 | tr -dc 'A-Za-z' | head -c 64)
|
||||||
|
echo "Tianji Secret: $TIANJI_SECRET" >>~/tianji.creds
|
||||||
|
|
||||||
msg_info "Setting up Tianji"
|
msg_info "Setting up Tianji"
|
||||||
cd /opt/tianji
|
cd /opt/tianji
|
||||||
|
|||||||
62
install/tinyauth-install.sh
Normal file
62
install/tinyauth-install.sh
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/steveiliop56/tinyauth
|
||||||
|
|
||||||
|
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 \
|
||||||
|
openssl \
|
||||||
|
apache2-utils
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "tinyauth" "steveiliop56/tinyauth" "singlefile" "latest" "/opt/tinyauth" "tinyauth-amd64"
|
||||||
|
|
||||||
|
msg_info "Setting up Tinyauth"
|
||||||
|
PASS=$(openssl rand -base64 8 | tr -dc 'a-zA-Z0-9' | head -c 8)
|
||||||
|
USER=$(htpasswd -Bbn "tinyauth" "${PASS}")
|
||||||
|
cat <<EOF >/opt/tinyauth/credentials.txt
|
||||||
|
Tinyauth Credentials
|
||||||
|
Username: tinyauth
|
||||||
|
Password: ${PASS}
|
||||||
|
EOF
|
||||||
|
msg_ok "Set up Tinyauth"
|
||||||
|
|
||||||
|
read -r -p "${TAB3}Enter your Tinyauth subdomain (e.g. https://tinyauth.example.com): " app_url
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/opt/tinyauth/.env
|
||||||
|
TINYAUTH_DATABASE_PATH=/opt/tinyauth/database.db
|
||||||
|
TINYAUTH_AUTH_USERS='${USER}'
|
||||||
|
TINYAUTH_APPURL=${app_url}
|
||||||
|
EOF
|
||||||
|
cat <<EOF >/etc/systemd/system/tinyauth.service
|
||||||
|
[Unit]
|
||||||
|
Description=Tinyauth Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
EnvironmentFile=/opt/tinyauth/.env
|
||||||
|
ExecStart=/opt/tinyauth/tinyauth
|
||||||
|
WorkingDirectory=/opt/tinyauth
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now tinyauth
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -44,7 +44,20 @@ $STD timescaledb-tune -yes -memory "$ram_for_tsdb"MB
|
|||||||
$STD systemctl restart postgresql
|
$STD systemctl restart postgresql
|
||||||
msg_ok "Installed TimescaleDB"
|
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"
|
fetch_and_deploy_gh_release "tracearr" "connorgallopo/Tracearr" "tarball" "latest" "/opt/tracearr.build"
|
||||||
|
|
||||||
msg_info "Building Tracearr"
|
msg_info "Building Tracearr"
|
||||||
@@ -75,6 +88,7 @@ msg_info "Configuring Tracearr"
|
|||||||
$STD useradd -r -s /bin/false -U tracearr
|
$STD useradd -r -s /bin/false -U tracearr
|
||||||
$STD chown -R tracearr:tracearr /opt/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/tracearr
|
||||||
|
install -d -m 750 -o tracearr -g tracearr /data/backup
|
||||||
export JWT_SECRET=$(openssl rand -hex 32)
|
export JWT_SECRET=$(openssl rand -hex 32)
|
||||||
export COOKIE_SECRET=$(openssl rand -hex 32)
|
export COOKIE_SECRET=$(openssl rand -hex 32)
|
||||||
cat <<EOF >/data/tracearr/.env
|
cat <<EOF >/data/tracearr/.env
|
||||||
@@ -89,7 +103,6 @@ JWT_SECRET=$JWT_SECRET
|
|||||||
COOKIE_SECRET=$COOKIE_SECRET
|
COOKIE_SECRET=$COOKIE_SECRET
|
||||||
APP_VERSION=$(cat /root/.tracearr)
|
APP_VERSION=$(cat /root/.tracearr)
|
||||||
#CORS_ORIGIN=http://localhost:5173
|
#CORS_ORIGIN=http://localhost:5173
|
||||||
#MOBILE_BETA_MODE=true
|
|
||||||
EOF
|
EOF
|
||||||
chmod 600 /data/tracearr/.env
|
chmod 600 /data/tracearr/.env
|
||||||
chown -R tracearr:tracearr /data/tracearr
|
chown -R tracearr:tracearr /data/tracearr
|
||||||
@@ -140,6 +153,7 @@ if [ -f \$pg_config_file ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
systemctl restart postgresql
|
systemctl restart postgresql
|
||||||
|
sudo -u postgres psql -c "ALTER USER tracearr WITH SUPERUSER;"
|
||||||
EOF
|
EOF
|
||||||
chmod +x /data/tracearr/prestart.sh
|
chmod +x /data/tracearr/prestart.sh
|
||||||
cat <<EOF >/lib/systemd/system/tracearr.service
|
cat <<EOF >/lib/systemd/system/tracearr.service
|
||||||
|
|||||||
@@ -1,53 +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://ui.com/download/unifi
|
|
||||||
|
|
||||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
|
||||||
color
|
|
||||||
verb_ip6
|
|
||||||
catch_errors
|
|
||||||
setting_up_container
|
|
||||||
network_check
|
|
||||||
update_os
|
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
|
||||||
$STD apt install -y apt-transport-https
|
|
||||||
curl -fsSL "https://dl.ui.com/unifi/unifi-repo.gpg" -o "/usr/share/keyrings/unifi-repo.gpg"
|
|
||||||
cat <<EOF | sudo tee /etc/apt/sources.list.d/100-ubnt-unifi.sources >/dev/null
|
|
||||||
Types: deb
|
|
||||||
URIs: https://www.ui.com/downloads/unifi/debian
|
|
||||||
Suites: stable
|
|
||||||
Components: ubiquiti
|
|
||||||
Architectures: amd64
|
|
||||||
Signed-By: /usr/share/keyrings/unifi-repo.gpg
|
|
||||||
EOF
|
|
||||||
$STD apt update
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
JAVA_VERSION="21" setup_java
|
|
||||||
|
|
||||||
if lscpu | grep -q 'avx'; then
|
|
||||||
MONGO_VERSION="8.0" setup_mongodb
|
|
||||||
else
|
|
||||||
msg_error "No AVX detected (CPU-Flag)! We have discontinued support for this. You are welcome to try it manually with a Debian LXC, but due to the many issues with Unifi, we currently only support AVX CPUs."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! dpkg -l | grep -q 'libssl1.1'; then
|
|
||||||
msg_info "Installing libssl (if needed)"
|
|
||||||
curl -fsSL "https://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1w-0+deb11u4_amd64.deb" -o "/tmp/libssl.deb"
|
|
||||||
$STD dpkg -i /tmp/libssl.deb
|
|
||||||
rm -f /tmp/libssl.deb
|
|
||||||
msg_ok "Installed libssl1.1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Installing UniFi Network Server"
|
|
||||||
$STD apt install -y unifi
|
|
||||||
msg_ok "Installed UniFi Network Server"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -16,13 +16,13 @@ update_os
|
|||||||
if [[ "${CTTYPE:-1}" != "0" ]]; then
|
if [[ "${CTTYPE:-1}" != "0" ]]; then
|
||||||
msg_error "UniFi OS Server requires a privileged LXC container."
|
msg_error "UniFi OS Server requires a privileged LXC container."
|
||||||
msg_error "Recreate the container with unprivileged=0."
|
msg_error "Recreate the container with unprivileged=0."
|
||||||
exit 1
|
exit 10
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -e /dev/net/tun ]]; then
|
if [[ ! -e /dev/net/tun ]]; then
|
||||||
msg_error "Missing /dev/net/tun in container."
|
msg_error "Missing /dev/net/tun in container."
|
||||||
msg_error "Enable TUN/TAP (var_tun=yes) or add /dev/net/tun passthrough."
|
msg_error "Enable TUN/TAP (var_tun=yes) or add /dev/net/tun passthrough."
|
||||||
exit 1
|
exit 236
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
@@ -48,7 +48,7 @@ TEMP_JSON="$(mktemp)"
|
|||||||
if ! curl -fsSL "$API_URL" -o "$TEMP_JSON"; then
|
if ! curl -fsSL "$API_URL" -o "$TEMP_JSON"; then
|
||||||
rm -f "$TEMP_JSON"
|
rm -f "$TEMP_JSON"
|
||||||
msg_error "Failed to fetch data from Ubiquiti API"
|
msg_error "Failed to fetch data from Ubiquiti API"
|
||||||
exit 1
|
exit 250
|
||||||
fi
|
fi
|
||||||
LATEST=$(jq -r '
|
LATEST=$(jq -r '
|
||||||
._embedded.firmware
|
._embedded.firmware
|
||||||
@@ -62,7 +62,7 @@ UOS_URL=$(echo "$LATEST" | jq -r '._links.data.href')
|
|||||||
rm -f "$TEMP_JSON"
|
rm -f "$TEMP_JSON"
|
||||||
if [[ -z "$UOS_URL" || -z "$UOS_VERSION" || "$UOS_URL" == "null" ]]; then
|
if [[ -z "$UOS_URL" || -z "$UOS_VERSION" || "$UOS_URL" == "null" ]]; then
|
||||||
msg_error "Failed to parse UniFi OS Server version or download URL"
|
msg_error "Failed to parse UniFi OS Server version or download URL"
|
||||||
exit 1
|
exit 250
|
||||||
fi
|
fi
|
||||||
msg_ok "Found UniFi OS Server ${UOS_VERSION}"
|
msg_ok "Found UniFi OS Server ${UOS_VERSION}"
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user