Compare commits

...
85 Commits
Author SHA1 Message Date
github-actions[bot] a026ab5926 Update AppImage beta build (2026-11-03 22:24:19) 2026-11-03 22:24:20 +00:00
MacRimi 1dca76aaa5 fix(oci): check high availability in the preflight so tests without Proxmox keep working 2026-11-03 23:16:25 +01:00
MacRimi dcb1d65ec8 fix(monitor): keep the theme-aware logo list and add Tailscale 2026-11-03 23:08:30 +01:00
ProxMenuxBot 7bb99d30ff chore(lang): auto-rebuild translation cache
Source: a89eb92
Triggered by: push
2026-11-03 22:00:23 +00:00
MacRimi a89eb921cc fix(oci): refuse an HA-managed container before downloading the image and explain how to proceed 2026-11-03 22:49:47 +01:00
github-actions[bot] 97da4321c8 Update AppImage beta build (2026-11-03 20:27:40) 2026-11-03 20:27:40 +00:00
MacRimi 11c0c683d7 fix(monitor): run scheduled backup jobs detached and follow them by their task UPID 2026-11-03 21:15:40 +01:00
MacRimi 6628744900 Merge branch 'develop' of https://github.com/MacRimi/ProxMenux into develop 2026-11-03 21:02:17 +01:00
MacRimi 194a959492 fix(monitor): show the light variant of selfh.st logos in the dark theme 2026-11-03 21:02:06 +01:00
MacRimiandGitHub 74e5b7a4ff Merge pull request #587 from MaEscalanteHe/docs/drift-utils
docs(web): fix Utils drift
2026-11-03 20:58:55 +01:00
MacRimiandGitHub 244181f9df Merge pull request #586 from MaEscalanteHe/docs/drift-backup-restore
docs(web): fix Backup & Restore drift
2026-11-03 20:58:33 +01:00
Manuel Escalante e3f85b3e09 docs(web): translate utils drift fixes 2026-11-03 20:00:03 +01:00
Manuel Escalante c0067d35a6 docs(web): fix Utils drift found in docs audit 2026-11-03 19:59:52 +01:00
Manuel Escalante cd3d4061d0 docs(web): translate backup-restore drift fixes 2026-11-03 19:52:20 +01:00
Manuel Escalante e9272c90a0 docs(web): fix Backup & Restore drift found in docs audit 2026-11-03 19:52:20 +01:00
MacRimi e51553ada8 test: give the cached health check a safe margin before the cache expires 2026-11-03 19:50:03 +01:00
MacRimiandGitHub c07b328bb9 Merge pull request #582 from jcastro/feature/oci-catalog-refresh
Refresh the OCI application catalog automatically with a local cache
2026-11-03 19:46:54 +01:00
MacRimiandGitHub 9a9d0f2379 Merge pull request #576 from dodog/main
Refine Slovak translations in common.json
2026-11-03 19:42:30 +01:00
MacRimiandGitHub 389a07c265 Merge pull request #575 from MaEscalanteHe/docs/drift-monitor
docs(web): fix Monitor drift
2026-11-03 19:41:56 +01:00
MacRimiandGitHub c5df337db6 Merge pull request #574 from MaEscalanteHe/docs/drift-settings-intro
docs(web): fix Settings, Introduction and Installation drift
2026-11-03 19:41:29 +01:00
ProxMenuxBot 3e2b8d72d1 chore(lang): auto-rebuild translation cache
Source: 3bf4c0d
Triggered by: push
2026-11-03 18:14:42 +00:00
MacRimiandGitHub 3bf4c0d82f Merge pull request #585 from jcastro/feature/oci-artcraft-suite
feat(oci): add thirteen ArtCraft desktop applications
2026-11-03 19:00:47 +01:00
MacRimi c3024b8448 Merge develop into feature/oci-artcraft-suite 2026-11-03 18:52:37 +01:00
ProxMenuxBot ab76ab161b chore(lang): auto-rebuild translation cache
Source: 7f59ee5
Triggered by: push
2026-11-03 17:50:46 +00:00
MacRimi f61c59d093 Merge develop into feature/oci-artcraft-suite
Resolve the catalog conflicts and regenerate VALIDATION.md.
2026-11-03 18:43:52 +01:00
MacRimiandGitHub 7f59ee5103 Merge pull request #580 from jcastro/feature/oci-app-catalog-additions
Add KitchenOwl, Krusader, Spoolman, Unbound and Z-Wave JS UI
2026-11-03 18:30:15 +01:00
github-actions[bot] cef1dc7422 Update AppImage beta build (2026-11-03 17:25:45) 2026-11-03 17:25:45 +00:00
MacRimi 888b99330b Merge develop into feature/oci-app-catalog-additions 2026-11-03 18:20:08 +01:00
ProxMenuxBot af0dd74067 chore(lang): auto-rebuild translation cache
Source: 7ec022a
Triggered by: push
2026-11-03 17:13:55 +00:00
Jonatan Castro 75a96b2658 Complete Swedish Authelia label after syncing develop 2026-11-03 18:06:58 +01:00
MacRimi 114882fcba Merge develop into feature/oci-app-catalog-additions
Resolve the catalog conflicts and regenerate VALIDATION.md.
2026-11-03 18:06:57 +01:00
Jonatan Castro 79c0f268fd Merge develop and refresh the OCI validation summary 2026-11-03 18:05:19 +01:00
MacRimiandGitHub 7ec022af81 Merge pull request #584 from jcastro/feature/oci-airdcpp
feat(oci): add AirDC++ Web Client
2026-11-03 18:02:36 +01:00
Jonatan Castro 07f7f9a6a1 Apply profile compatibility gate using effective menu visibility 2026-11-03 17:58:52 +01:00
Jonatan Castro fec97c57d9 Prune catalog snapshots and defer recipes requiring newer profile keys 2026-11-03 17:56:15 +01:00
MacRimi 4ba0d6a236 Merge develop into feature/oci-airdcpp
Resolve the catalog index conflict and regenerate VALIDATION.md.
2026-11-03 17:47:35 +01:00
ProxMenuxBot 96b3a919ba chore(lang): auto-rebuild translation cache
Source: c628e65
Triggered by: push
2026-11-03 16:46:28 +00:00
MacRimiandGitHub c628e65e2f Merge pull request #581 from jcastro/feature/oci-authelia
Add Authelia to the OCI catalog
2026-11-03 17:42:30 +01:00
MacRimi 1e08a5939b ci: cancel superseded test runs on the same branch or pull request 2026-11-03 17:10:11 +01:00
MacRimiandGitHub 163c7c3505 Merge pull request #583 from jcastro/fix/oci-failed-update-recovery
fix(oci): recover automatically after failed image replacements
2026-11-03 16:50:36 +01:00
MacRimi eb46fffd45 fix(oci): apply the llama.cpp context size and stable Vulkan settings for integrated GPUs 2026-11-03 16:46:38 +01:00
Manuel Escalante a4c2c34597 fix(i18n): use localized UI labels in Monitor docs 2026-11-03 16:04:15 +01:00
Jonatan Castro aa19af66eb Add thirteen ArtCraft desktop applications to the OCI catalog 2026-11-03 14:50:20 +01:00
Jonatan Castro f19c300387 Restore the previous OCI installation after a failed image replacement 2026-11-03 13:32:16 +01:00
Jonatan Castro c1183bdeed Use the AirDC++ index page for startup health checks 2026-11-03 13:22:55 +01:00
Jonatan Castro 19e35a567f Add AirDC++ Web Client OCI recipe 2026-11-03 12:51:00 +01:00
Jonatan Castro f428dc76f0 Isolate catalog worker in offline Slovak menu regression 2026-11-03 12:38:57 +01:00
Jonatan Castro e412d3161d Harden OCI catalog refresh recovery and retries 2026-11-03 12:30:54 +01:00
Jonatan Castro 13a8ac1001 Refresh OCI catalog automatically with local cache and app counters 2026-11-03 12:20:23 +01:00
Jonatan Castro f0d54fca13 Leave lab verification to maintainers 2026-11-03 11:35:59 +01:00
Jonatan Castro d9973635fb Add Authelia to OCI catalog 2026-11-03 11:34:27 +01:00
Manuel Escalante 75b13d87da fix(i18n/de): correct the backups tab alt text in the guest detail dialog 2026-11-03 10:25:41 +01:00
Manuel Escalante ac97e2c5a6 docs(web): apply review feedback on Monitor docs 2026-11-03 09:54:33 +01:00
Manuel Escalante 700f72babd docs(web): fix release channel wording from review 2026-11-03 09:45:39 +01:00
Jonatan Castro 0ab40b4eea feat(oci): add five application recipes 2026-11-03 00:27:00 +01:00
MacRimi 9940f05adf fix(oci): llama.cpp lists the models in /models, with resources and notes to add one 2026-11-02 23:45:10 +01:00
Jozef GaalandJozef Gaal 8328d5d366 Refine 'onServer' explanation in common.json 2026-11-02 23:17:00 +01:00
Jozef GaalandJozef Gaal 7e6a942d16 Fix Slovak translations in common.json 2026-11-02 23:17:00 +01:00
Jozef GaalandJozef Gaal 03928c4277 Refine Slovak translations in common.json 2026-11-02 23:16:59 +01:00
MacRimiandGitHub 8aefd70e52 Merge pull request #578 from jcastro/feature/oci-paperclip
Add Paperclip to the OCI catalog
2026-11-02 23:02:03 +01:00
MacRimiandGitHub 6bee13114c Merge pull request #579 from f3rs3n/fix/log2ram-journal-transition
fix(log2ram): keep journal protection enabled until disk migration
2026-11-02 23:00:50 +01:00
martino 6a1513a014 fix(log2ram): keep journal protection enabled until disk migration 2026-11-02 22:32:28 +01:00
Jonatan Castro fb083e92cb feat(oci): add Paperclip application recipe 2026-11-02 20:37:29 +01:00
github-actions[bot] 781d2500ad Update AppImage beta build (2026-11-02 18:39:06) 2026-11-02 18:39:06 +00:00
MacRimi 98931fe4a7 New version 1.2.8 2026-11-02 19:22:47 +01:00
MacRimi 46337f162f New version 1.2.8 2026-11-02 19:20:30 +01:00
MacRimiandGitHub 064c2a6c39 Merge pull request #557 from MaEscalanteHe/feature/web-refresh
fix(web): dependency cleanup, HTML entity rendering and sidebar fixes
2026-11-02 19:10:00 +01:00
MacRimi 3feb5ca5cb fix(web): wrap inline code and scroll tables on narrow screens 2026-11-02 19:01:03 +01:00
MacRimi b0215d4bbb fix: OCI image data paths, LAN endpoints for OpenAI-compatible AI and lab-validated apps 2026-11-02 18:42:32 +01:00
MacRimi 9f3fffd249 fix: one source for the disk type and a config volume for SearXNG 2026-11-02 17:28:31 +01:00
Manuel Escalante 511211f10b fix(web): keep ICU quotes out of messages inserted as raw HTML 2026-11-02 10:32:41 +01:00
github-actions[bot] 41081121f8 Update AppImage beta build (2026-11-02 07:28:12) 2026-11-02 07:28:12 +00:00
MacRimi e83794b7e2 fix(web): send only the client translations to each page 2026-11-02 08:25:28 +01:00
Manuel Escalante 418afe385b docs(web): translate AI explanations of backup errors 2026-11-01 14:38:05 +01:00
Manuel Escalante 9ed09cc28e docs(web): document AI explanations of backup errors 2026-11-01 14:36:54 +01:00
Manuel Escalante 4261019549 docs(web): translate settings-intro drift fixes 2026-11-01 14:05:13 +01:00
Manuel Escalante 5dc98e9daf docs(web): translate monitor drift fixes 2026-11-01 14:05:13 +01:00
Manuel Escalante 488044e0b9 docs(web): fix remaining Settings and Introduction drift from docs audit 2026-11-01 14:05:13 +01:00
Manuel Escalante 7320fc6ff6 docs(web): fix Monitor drift found in docs audit 2026-11-01 14:05:13 +01:00
Manuel Escalante 398ca55247 docs(web): fix Monitor API paths and token and SSL location 2026-11-01 14:05:13 +01:00
Manuel Escalante 4f415c98cf docs(web): fix Monitor install and Change Language drift in Settings 2026-11-01 14:05:12 +01:00
Manuel Escalante 64fa4f8115 fix(web): restore Change Language entry in docs sidebar 2026-10-29 19:54:41 +01:00
Manuel Escalante c26eb49e2c fix(web): render HTML entities in translated text 2026-10-29 09:41:32 +01:00
Manuel Escalante db12972253 fix(web): pass em tag to host-local-disk format steps 2026-10-29 09:41:32 +01:00
Manuel Escalante fac7ac5021 chore(web): drop unused dependencies and apply minor updates and audit fixes 2026-10-29 09:41:32 +01:00
451 changed files with 30342 additions and 3551 deletions
+188 -2
View File
@@ -5,6 +5,7 @@ and interval the host already has."""
import os
from pathlib import Path
import shutil
import shlex
import subprocess
import tempfile
import unittest
@@ -25,10 +26,176 @@ class KeepOnDiskTests(unittest.TestCase):
(self.log / "journal/abc/system.journal").write_text("entries")
(self.log / "pveproxy").mkdir()
(self.log / "pveproxy/access.log").write_text("GET /")
self.config = self.root / "etc/log2ram.conf"
self.config.parent.mkdir()
self.config.write_text("SIZE=128M\nJOURNALD_AWARE=true\nNOTIFICATION=true\n")
def run_setup(self, edit_failure=False):
# Extract only the shared setup function, never an administrative caller.
body = SETUP.read_text().split("pmx_log2ram_setup() {", 1)[1].split("\n}\n", 1)[0]
body = body.replace("/etc/", str(self.root / "etc") + "/")
for directory in ("cron.d", "tmpfiles.d"):
(self.root / "etc" / directory).mkdir(exist_ok=True)
stubs = r'''
translate() { printf '%s' "$1"; }
msg_info() { :; }
msg_ok() { :; }
pmx_install_pkg() { :; }
_pmx_log2ram_install_release() { :; }
_pmx_log2ram_pbs_logrotate() { :; }
_pmx_log2ram_remove_legacy() { :; }
pmx_edit_file() { local file="$1"; shift; sed -i "$@" "$file"; }
pmx_append_file() { cat >> "$1"; }
pmx_write_file() { cat > "$1"; }
pmx_remove_file() { rm -f "$1"; }
pmx_apply_setting() { :; }
systemctl() { printf '%s\n' "$*" >> "$SYSTEMCTL_TRACE"; }
'''
if edit_failure:
# A failed configuration writer must be handled even by root runners.
stubs += "\npmx_edit_file() { return 1; }\n"
script = (stubs + "\npmx_log2ram_setup() {" + body + "\n}\n"
+ "pmx_log2ram_setup 256 3 false\n")
env = dict(os.environ, SYSTEMCTL_TRACE=str(self.root / "systemctl.trace"),
PMX_L2R_TAG="1.7.2", PMX_L2R_SCRIPTS=str(KEEP.parent),
PMX_L2R_REVERT_UNIT=str(self.root / "etc/revert.service"))
return subprocess.run(["bash", "-c", script], env=env, capture_output=True, text=True, timeout=10)
def test_setup_keeps_journal_aware_syncing_until_boot(self):
self.config.write_text("SIZE=128M\nJOURNALD_AWARE=false\nNOTIFICATION=true\n")
result = self.run_setup()
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("JOURNALD_AWARE=true\n", self.config.read_text())
self.assertIn("SIZE=256M\n", self.config.read_text())
self.assertFalse((self.log / "journal").is_symlink())
self.assertEqual((self.root / "systemctl.trace").read_text(), "daemon-reload\n")
def test_boot_disables_journal_aware_syncing_after_relocation(self):
self.assertEqual(self.run_setup().returncode, 0)
result = self.run_script()
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(os.readlink(self.log / "journal"), "/var/hdd.journal")
self.assertEqual((self.root / "var/hdd.journal/abc/system.journal").read_text(), "entries")
self.assertIn("JOURNALD_AWARE=false\n", self.config.read_text())
self.assertIn("SIZE=256M\n", self.config.read_text())
# Reapplying the repair to an already-relocated installation is safe.
self.assertEqual(self.run_setup().returncode, 0)
self.assertEqual(self.run_script().returncode, 0)
self.assertIn("JOURNALD_AWARE=false\n", self.config.read_text())
self.assertEqual(sorted(p.name for p in (self.root / "var/hdd.journal").iterdir()), ["abc"])
def test_boot_migration_failure_is_not_ignored_by_startup(self):
self.assertEqual(self.run_setup().returncode, 0)
# A non-directory destination causes a real copy failure, without mounts.
conflict = self.root / "var/hdd.journal"
conflict.write_text("blocked")
unit = self.root / "etc/systemd/system/log2ram.service.d/proxmenux.conf"
command = next(line.split("=", 1)[1] for line in unit.read_text().splitlines()
if line.startswith("ExecStartPre="))
result = subprocess.run(["bash", *shlex.split(command.lstrip("-"))],
env=dict(os.environ, PMX_L2R_ROOT=str(self.root)),
capture_output=True, text=True, timeout=10)
self.assertNotEqual(result.returncode, 0, result.stderr)
self.assertIn("JOURNALD_AWARE=true\n", self.config.read_text())
self.assertFalse(command.startswith("-"), "systemd must not ignore the helper's failure")
conflict.unlink()
self.assertEqual(self.run_script().returncode, 0)
self.assertIn("JOURNALD_AWARE=false\n", self.config.read_text())
def test_setup_adds_journal_aware_setting_when_missing(self):
self.config.write_text("SIZE=128M\n#JOURNALD_AWARE=false\n")
result = self.run_setup()
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("\nJOURNALD_AWARE=true\n", self.config.read_text())
self.assertEqual(self.run_script().returncode, 0)
self.assertIn("\nJOURNALD_AWARE=false\n", self.config.read_text())
def check_missing_setting_without_final_newline(self, content):
self.config.write_text(content)
result = self.run_setup()
self.assertEqual(result.returncode, 0, result.stderr)
for expected in ("true", "false"):
with self.subTest(journal_aware=expected):
# Read shell semantics in a fresh Bash, not a substring match.
sourced = subprocess.run(
["bash", "--noprofile", "--norc", "-c",
'unset JOURNALD_AWARE NOTIFICATION; source "$1"; '
'printf "%s\\n%s\\n" "${JOURNALD_AWARE-UNSET}" "${NOTIFICATION-UNSET}"',
"fixture", str(self.config)],
capture_output=True, text=True, timeout=10)
self.assertEqual(sourced.returncode, 0, sourced.stderr)
self.assertEqual(sourced.stdout, expected + "\nfalse\n")
if expected == "true":
self.assertFalse((self.log / "journal").is_symlink())
self.assertEqual((self.log / "journal/abc/system.journal").read_text(), "entries")
result = self.run_script()
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(os.readlink(self.log / "journal"), "/var/hdd.journal")
self.assertEqual((self.root / "var/hdd.journal/abc/system.journal").read_text(), "entries")
def test_missing_setting_after_comment_without_final_newline(self):
self.check_missing_setting_without_final_newline(
"SIZE=128M\nNOTIFICATION=false\n#JOURNALD_AWARE=false")
def test_missing_setting_after_assignment_without_final_newline(self):
self.check_missing_setting_without_final_newline("SIZE=128M\nNOTIFICATION=false")
def test_setup_reports_configuration_edit_failure(self):
self.config.write_text("SIZE=128M\nJOURNALD_AWARE=false\nNOTIFICATION=false\n")
result = self.run_setup(edit_failure=True)
self.assertNotEqual(result.returncode, 0, result.stderr)
self.assertIn("JOURNALD_AWARE=false\n", self.config.read_text())
def test_an_existing_link_with_an_unusable_disk_target_fails(self):
self.assertEqual(self.run_script().returncode, 0)
self.config.write_text("JOURNALD_AWARE=true\n")
disk = self.root / "var/hdd.journal"
shutil.rmtree(disk)
disk.write_text("blocked")
result = self.run_script()
self.assertNotEqual(result.returncode, 0, result.stderr)
self.assertEqual(self.config.read_text(), "JOURNALD_AWARE=true\n")
def test_an_unexpected_journal_link_does_not_complete_migration(self):
shutil.rmtree(self.log / "journal")
(self.log / "journal").symlink_to("pveproxy")
result = self.run_script()
self.assertNotEqual(result.returncode, 0, result.stderr)
self.assertEqual(os.readlink(self.log / "journal"), "pveproxy")
self.assertIn("JOURNALD_AWARE=true\n", self.config.read_text())
def test_a_missing_journal_with_an_unusable_disk_target_fails(self):
shutil.rmtree(self.log / "journal")
(self.root / "var/hdd.journal").write_text("blocked")
result = self.run_script()
self.assertNotEqual(result.returncode, 0, result.stderr)
self.assertIn("JOURNALD_AWARE=true\n", self.config.read_text())
self.assertFalse((self.log / "journal").is_symlink())
def test_failed_source_removal_does_not_complete_migration(self):
(self.root / "var/hdd.journal").mkdir()
result = subprocess.run(
["bash", "-c", 'rm() { return 1; }; export -f rm; exec bash "$1"', "fixture", str(KEEP)],
env=dict(os.environ, PMX_L2R_ROOT=str(self.root)), capture_output=True, text=True, timeout=10)
self.assertNotEqual(result.returncode, 0, result.stderr)
self.assertIn("JOURNALD_AWARE=true\n", self.config.read_text())
self.assertTrue((self.log / "journal/abc/system.journal").is_file())
def test_boot_configuration_failure_is_reported_and_can_be_retried(self):
self.config.unlink()
self.config.mkdir()
result = self.run_script()
self.assertNotEqual(result.returncode, 0, result.stderr)
self.assertEqual(os.readlink(self.log / "journal"), "/var/hdd.journal")
self.config.rmdir()
self.config.write_text("JOURNALD_AWARE=true\n")
self.assertEqual(self.run_script().returncode, 0)
self.assertEqual(self.config.read_text(), "JOURNALD_AWARE=false\n")
def run_script(self, revert=False):
env = dict(os.environ, PMX_L2R_ROOT=str(self.root), PMX_L2R_REVERT="1" if revert else "0")
return subprocess.run(["bash", str(KEEP)], env=env, capture_output=True, text=True)
return subprocess.run(["bash", str(KEEP)], env=env, capture_output=True, text=True, timeout=10)
def test_the_journal_moves_to_disk_behind_a_link(self):
self.assertEqual(self.run_script().returncode, 0)
@@ -78,6 +245,7 @@ class KeepOnDiskTests(unittest.TestCase):
def test_removing_log2ram_puts_the_folders_back(self):
(self.log / "proxmox-backup").mkdir()
self.run_script()
self.config.unlink() # Revert must not require or rewrite Log2RAM settings.
self.assertEqual(self.run_script(revert=True).returncode, 0)
for name in ("journal", "proxmox-backup"):
self.assertFalse((self.log / name).is_symlink(), name)
@@ -99,7 +267,7 @@ class KeptSettingsTests(unittest.TestCase):
library = Path(folder) / "setup.sh"
library.write_text(script)
result = subprocess.run(["bash", "-c", f'source "{library}"; {function}'],
capture_output=True, text=True)
capture_output=True, text=True, timeout=10)
return result.stdout.strip()
def test_the_size_comes_from_the_installed_configuration(self):
@@ -114,6 +282,24 @@ class KeptSettingsTests(unittest.TestCase):
cron = "MAILTO=\"\"\n0 */3 * * * root /usr/local/bin/log2ram write >/dev/null 2>&1\n"
self.assertEqual(self.read("pmx_log2ram_current_hours", {"/etc/cron.d/log2ram": cron}), "3")
def test_both_modes_offer_a_repair_to_version_2_0_installs(self):
for filename, function, updater in (
("auto_post_install.sh", "install_log2ram_auto", "_update_existing_log2ram_auto"),
("customizable_post_install.sh", "configure_log2ram", "_update_existing_log2ram_custom"),
):
with self.subTest(mode=filename), tempfile.TemporaryDirectory() as folder:
config = Path(folder) / "log2ram.conf"
config.write_text("JOURNALD_AWARE=false\n")
source = (ROOT / "scripts/post_install" / filename).read_text()
body = source.split(function + "() {", 1)[1].split("\n}\n", 1)[0]
body = body.replace("/etc/log2ram.conf", str(config))
script = ("pmx_journal_context() { :; }\n"
+ updater + "() { printf '%s\\n' \"$1\"; }\n"
+ function + "() {" + body + "\n}\n" + function)
result = subprocess.run(["bash", "-c", script], capture_output=True, text=True, timeout=10)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout.strip(), "2.1")
def test_the_release_is_pinned_to_a_verified_commit(self):
text = SETUP.read_text()
self.assertIn('PMX_L2R_TAG="1.7.2"', text)
+8 -2
View File
@@ -12,7 +12,7 @@ from unittest.mock import Mock, patch
ROOT=Path(__file__).resolve().parents[3]
sys.path[:0]=[str(ROOT/'oci/src'),str(ROOT/'oci/remote')]
from proxmenux_oci import cli, custom, custom_mounts, extra_devices, i18n, installer, ui as native_ui, updates
from proxmenux_oci import catalog_refresh, cli, custom, custom_mounts, extra_devices, i18n, installer, ui as native_ui, updates
from proxmenux_oci.catalog import Catalog
@@ -203,7 +203,13 @@ class InputAndCancellationTests(StorageFixture):
def test_real_menu_error_handler_has_slovak_heading_and_preserves_detail(self):
ui=Mock();ui.choose.side_effect=['custom',None]
with patch.object(cli,'interactive_ui',return_value=ui),patch.object(custom,'explore',side_effect=ValueError('fiction-detail')), \
patch.object(updates,'UpdateCheck') as checker:
patch.object(updates,'UpdateCheck') as checker, \
patch.object(catalog_refresh,'CatalogRefresh') as catalog_checker:
# Keep this wording/error-handler test offline and free of writes.
# The real background worker has its own catalog lifecycle tests.
catalog_check=catalog_checker.return_value.__enter__.return_value
catalog_check.active=False;catalog_check.consume.return_value=False
catalog_check.describe.return_value=''
check=checker.return_value.__enter__.return_value
check.active=False;check.notice.return_value='';check.status.return_value={'available':[]}
self.assertEqual(cli.interactive(self.catalog),0)
@@ -24,7 +24,10 @@ class VmBackupJobsWiring(TestCase):
source = ROUTES.read_text()
self.assertNotIn('shell=True', source)
self.assertNotIn('os.system', source)
self.assertEqual(source.count('subprocess.run('), 1)
# pvesh, and the transient unit a backup started by hand runs in.
programs = re.findall(r'subprocess\.run\(\s*\[\s*"([a-z-]+)"', source)
self.assertEqual(len(programs), source.count('subprocess.run('))
self.assertEqual(set(programs), {'pvesh', 'systemd-run', 'systemctl'})
self.assertIn('subprocess.run(["pvesh", *args]', source)
def test_the_monitor_ships_and_registers_it(self):
+5
View File
@@ -25,6 +25,11 @@ on:
permissions:
contents: read
# A newer push to the same branch or pull request replaces the run in progress.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
check:
runs-on: ubuntu-latest
+5
View File
@@ -112,6 +112,11 @@ on:
permissions:
contents: read
# A newer push to the same branch or pull request replaces the run in progress.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
apprise-services:
runs-on: ubuntu-latest
+5
View File
@@ -51,6 +51,11 @@ on:
permissions:
contents: read
# A newer push to the same branch or pull request replaces the run in progress.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# Preserve this check ID for existing branch protection rules. This suite
# includes menu, download and scheduler regressions as well as i18n tests.
@@ -57,6 +57,11 @@ on:
permissions:
contents: read
# A newer push to the same branch or pull request replaces the run in progress.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
offline-python:
runs-on: ubuntu-latest
+1
View File
@@ -54,6 +54,7 @@ Thumbs.db
# Cache
.cache
/oci/.catalog-cache/
/web/.cache
# IDE/editor files
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
5e8afe3b297f21b8646e58eed720ba2eeb5f16681a3d2eb89bcac600065167c9 ProxMenux-1.2.7.AppImage
92084408d97ec3c2c17499960cc77ba603d87affe0a648720d69909b1dee8b95 ProxMenux-1.2.8.AppImage
+9 -1
View File
@@ -397,10 +397,18 @@ const SELFHST_THEME_LOGOS: Record<string, { lightTheme: string; darkTheme: strin
lightTheme: `${SELFHST_WEBP_BASE}/frigate-dark.webp`,
darkTheme: `${SELFHST_WEBP_BASE}/frigate-light.webp`,
},
"llama-cpp": {
lightTheme: `${SELFHST_WEBP_BASE}/llama-cpp.webp`,
darkTheme: `${SELFHST_WEBP_BASE}/llama-cpp-light.webp`,
},
portainer: {
lightTheme: `${SELFHST_WEBP_BASE}/portainer-dark.webp`,
darkTheme: `${SELFHST_WEBP_BASE}/portainer-light.webp`,
},
tailscale: {
lightTheme: `${SELFHST_WEBP_BASE}/tailscale.webp`,
darkTheme: `${SELFHST_WEBP_BASE}/tailscale-light.webp`,
},
vaultwarden: {
lightTheme: `${SELFHST_WEBP_BASE}/vaultwarden.webp`,
darkTheme: `${SELFHST_WEBP_BASE}/vaultwarden-light.webp`,
@@ -409,7 +417,7 @@ const SELFHST_THEME_LOGOS: Record<string, { lightTheme: string; darkTheme: strin
function selfhstThemeLogos(src: string) {
if (!src.toLowerCase().includes("cdn.jsdelivr.net/gh/selfhst/icons")) return null
const match = src.toLowerCase().match(/\/(frigate|portainer|vaultwarden)(?:-(?:dark|light))?\.webp(?:[?#].*)?$/)
const match = src.toLowerCase().match(/\/(frigate|llama-cpp|portainer|tailscale|vaultwarden)(?:-(?:dark|light))?\.webp(?:[?#].*)?$/)
return match ? SELFHST_THEME_LOGOS[match[1]] : null
}
+13 -20
View File
@@ -804,7 +804,7 @@ export function StorageOverview({ disksOnly = false }: { disksOnly?: boolean } =
</div>
)}
{/* Reallocated only meaningful on rotating disks. */}
{disk.reallocated_sectors !== undefined && (disk.rotation_rate ?? 0) > 0 && (
{disk.reallocated_sectors !== undefined && resolveDiskType(disk.name, disk.rotation_rate) === "HDD" && (
<div className="flex items-baseline justify-between gap-3">
<span className="text-[11px] uppercase tracking-wider text-muted-foreground">
{t("storage.reallocatedShort")}
@@ -860,12 +860,7 @@ export function StorageOverview({ disksOnly = false }: { disksOnly?: boolean } =
// Resolve disk class → threshold pair from the user-configurable
// backend (single source of truth). The semantics: temp BELOW warn
// is green, between warn and hot is amber, hot or above is red.
let cls: keyof DiskTempMap = "HDD"
if (diskName?.startsWith("nvme")) {
cls = "NVMe"
} else if (!rotationRate || rotationRate === 0) {
cls = "SSD"
}
const cls: keyof DiskTempMap = resolveDiskType(diskName ?? "", rotationRate)
const t = dtThresholds[cls]
if (temp >= t.hot) return "text-red-500"
if (temp >= t.warn) return "text-yellow-500"
@@ -896,9 +891,9 @@ export function StorageOverview({ disksOnly = false }: { disksOnly?: boolean } =
return t("storage.duration.daysShort", { days: totalDays })
}
const formatRotationRate = (rpm: number | undefined) => {
if (!rpm || rpm === 0) return "SSD"
return `${rpm.toLocaleString()} RPM`
const formatRotationRate = (diskName: string, rpm: number | undefined) => {
if (getDiskType(diskName, rpm) !== "HDD") return "SSD"
return rpm && rpm > 0 ? `${rpm.toLocaleString()} RPM` : t("common.notAvailable")
}
// Thin wrapper over the shared classifier so the rest of the file
@@ -2626,7 +2621,7 @@ export function StorageOverview({ disksOnly = false }: { disksOnly?: boolean } =
</div>
<div>
<p className="text-sm text-muted-foreground">{t("storage.rotationRate")}</p>
<p className="font-medium">{formatRotationRate(selectedDisk.rotation_rate)}</p>
<p className="font-medium">{formatRotationRate(selectedDisk.name, selectedDisk.rotation_rate)}</p>
</div>
<div>
<p className="text-sm text-muted-foreground">{t("storage.powerCycles")}</p>
@@ -2871,14 +2866,12 @@ function openSmartReport(disk: DiskInfo, testStatus: SmartTestStatus, smartAttri
// Determine disk type (SAS detected via backend flag or connection_type)
const isSasDisk = sd?.is_sas === true || disk.connection_type === 'sas'
let diskType = "HDD"
if (disk.name.startsWith("nvme")) {
diskType = "NVMe"
} else if (isSasDisk) {
let diskType: string = resolveDiskType(disk.name, disk.rotation_rate)
if (diskType !== "NVMe" && isSasDisk) {
diskType = "SAS"
} else if (!disk.rotation_rate || disk.rotation_rate === 0) {
diskType = "SSD"
}
const rpm = disk.rotation_rate && disk.rotation_rate > 0 ? disk.rotation_rate : 0
const known = (value?: string) => (value && value !== "Unknown" ? value : undefined)
// Health status styling
const healthStatus = String(testStatus.smart_status || (testStatus.smart_data?.smart_status) || 'unknown')
@@ -3824,11 +3817,11 @@ function pmxPrint(){
<div class="grid-4">
<div class="card">
<div class="card-label">${tSmart("labels.model")}</div>
<div class="card-value" style="font-size:11px;">${disk.model || sd?.model || t("app.unknown")}</div>
<div class="card-value" style="font-size:11px;">${known(disk.model) || known(sd?.model) || t("app.unknown")}</div>
</div>
<div class="card">
<div class="card-label">${tSmart("labels.serial")}</div>
<div class="card-value" style="font-size:11px;font-family:monospace;">${disk.serial || sd?.serial || t("app.unknown")}</div>
<div class="card-value" style="font-size:11px;font-family:monospace;">${known(disk.serial) || known(sd?.serial) || t("app.unknown")}</div>
</div>
<div class="card">
<div class="card-label">${tSmart("labels.capacity")}</div>
@@ -3836,7 +3829,7 @@ function pmxPrint(){
</div>
<div class="card">
<div class="card-label">${tSmart("labels.type")}</div>
<div class="card-value" style="font-size:11px;">${diskType === 'SAS' ? (disk.rotation_rate ? `SAS ${disk.rotation_rate} RPM` : 'SAS SSD') : diskType === 'HDD' && disk.rotation_rate ? `HDD ${disk.rotation_rate} RPM` : diskType}</div>
<div class="card-value" style="font-size:11px;">${diskType === 'SAS' ? (rpm ? `SAS ${rpm} RPM` : disk.rotation_rate === -1 ? 'SAS HDD' : 'SAS SSD') : diskType === 'HDD' && rpm ? `HDD ${rpm} RPM` : diskType}</div>
</div>
</div>
${(modelFamily || formFactor || sataVersion || ifaceSpeed) ? `
+22 -22
View File
@@ -6082,11 +6082,11 @@
},
"nextStep": {
"noJobs": "Vytvor zálohovaciu úlohu na tomto uzle a vyber VM alebo kontajnery s údajmi, ktoré by sa ťažko obnovovali ručne. Vypnutá úloha nezahŕňa do zálohovania žiadne VM ani kontajnery.",
"uncovered": "Rozhodnite sa pre každého z týchto hostí, či má niečo, čo stojí za to udržať. Pridajte tie, ktoré robia prácu; pre tie, ktoré nie, deklarujte, že v politike, takže sa prestanú počítať tu.",
"excludedData": "Otvorte zoznam vylúčených pracovných miest a potvrďte, že vynecháva údaje, ktoré si môžete dovoliť stratiť. Vylúčenie pridané, aby sa práca rýchlejšie chráni nič, čo preskočí.",
"uncoveredExpected": "Politika vyhlasuje, že títo hostia vyžadujú zálohu a žiadna povolená práca si ich vyberie. Buď ich pridajte do práce, alebo zmeňte, čo politika vyhlasuje, takže obaja súhlasia."
"uncovered": "Pre každého z týchto hostí rozhodnite, či obsahuje niečo, čo stojí za to ponechať. Tých, ktorí to obsahujú, pridajte do úlohy; v prípade tých, ktorí to neobsahujú, uveďte to v pravidle, aby sa tu už nezapočítavali.",
"excludedData": "Otvorte zoznam vylúčených položiek každej úlohy a overte si, či sa medzi vylúčenými údajmi nachádzajú len tie, ktorých stratu si môžete dovoliť. Vylúčenie pridané s cieľom urýchliť úlohu nijako nechráni údaje, ktoré sa tým vynechajú.",
"uncoveredExpected": "V rámci tejto politiky sú títo hostia označení ako vyžadujúci zálohovanie, avšak žiadna zapnutá úloha ich nevyberá. Pridajte ich do úlohy alebo upravte nastavenia politiky tak, aby sa tieto dve veci zhodovali."
},
"explanation": "Záloha chráni len to, čo si práca skutočne vyberie. Táto kontrola spáruje hostí na tomto uzle s pracovnými miestami, ktoré tu bežia, takže hosť, ktorý sa nikto neobjaví ako taký, namiesto toho, aby bol považovaný za pokrytý niečím iným."
"explanation": "Záloha chráni len to, čo úloha skutočne vyberie. Táto kontrola spáruje hostí na tomto uzle s úlohami, ktoré sa tu spúšťajú, takže hosť, ktorého nikto nezálohuje, sa zobrazí ako taký, namiesto toho, aby sa predpokladalo, že je zahrnutý v niečom inom."
},
"last_backup_age": {
"title": "Vek uložených záloh",
@@ -6099,11 +6099,11 @@
"evaluationFailed": "Kontrolu sa nepodarilo vyhodnotiť"
},
"nextStep": {
"stale": "Zisti, prečo úloha prestala vytvárať zálohy týchto VM alebo kontajnerov: môže byť vypnutá, nemusí sa spúšťať podľa plánu alebo môže končiť chybou. V prehľade výsledkov skontroluj jej posledné spustenie.",
"noBackups": "Žiadna uložená kópia sa nezhoduje s hosťom v tomto uzle. Ak práce napísať do cieľa, tento uzol nemôže čítať, to sa očakáva, inak sú produkovať nič.",
"attention": "Prezrite si uvedených hostí. Každá z nich nemá žiadnu kópiu alebo je staršia ako vek, ktorý sa používa."
"stale": "Zistite, prečo táto úloha prestala vytvárať kópie pre týchto hostí: mohla byť deaktivovaná, jej plán sa možno nikdy nespustil alebo jej behy zlyhávajú. Kontrola výsledkov behov uvádza, ako sa každá úloha naposledy ukončila.",
"noBackups": "Žiadna uložená kópia nezodpovedá žiadnemu hosťovi na tomto uzle. Ak úlohy zapisujú do cieľového umiestnenia, z ktorého tento uzol nemôže čítať, je to očakávané; inak by totiž nevytvárali žiadne výstupy.",
"attention": "Prezrite si zoznam hostí. Každý z nich buď nemá žiadnu aktuálnu kópiu, alebo má kópiu staršiu, než je požadovaný vek."
},
"explanation": "Práca, ktorá existuje, nie je to isté ako kópia, ktorá existuje. Tento šek číta najnovšie uložené kópie každého hosťa a ako dávno to bolo napísané, čo je, ako ďaleko by ste mali ísť, ak ste museli obnoviť dnes."
"explanation": "Existencia úlohy nie je to isté ako existencia jej kópie. Táto kontrola zisťuje najnovšiu uloženú kópiu každého hosťa a to, kedy bola napísaná – teda ako ďaleko by ste museli siahnuť, keby ste dnes museli vykonať obnovenie."
},
"retention_defined": {
"title": "Retencia záloh",
@@ -6116,11 +6116,11 @@
"evaluationFailed": "Kontrolu sa nepodarilo vyhodnotiť"
},
"nextStep": {
"missing": "Nastavte si držanie na týchto pracovných miestach, alebo na sklade, na ktorý píšu. Proxmox berie nastavenie úlohy ako prvý, potom úložisko je, potom uzol predvolený.",
"notDeclared": "Tieto práce uchovávajú všetky kópie, ktoré robia. To je zámerná voľba pre niektoré destinácie, ale potvrďte, že cieľ má priestor na rast.",
"onServer": "Tieto úlohy ukladajú zálohy na zálohovací server. Ten odstraňuje staré zálohy podľa vlastných pravidiel. Z tohto uzla sa nedá zistiť, ktoré zálohy uchováva; skontroluj ich priamo na zálohovacom serveri."
"missing": "Nastavte dobu uchovávania pre tieto úlohy alebo pre úložisko, do ktorého sa zapisujú. Proxmox uprednostňuje najskôr nastavenie úlohy, potom nastavenie úložiska a nakoniec predvolené nastavenie uzla.",
"notDeclared": "Tieto úlohy uchovávajú každú vytvorenú kópiu. V prípade niektorých cieľových umiestnení ide o zámernú voľbu, avšak je potrebné overiť, či má cieľové umiestnenie dostatok miesta na ďalší rast.",
"onServer": "Tieto úlohy zapisujú údaje na záložný server, ktorý ich odstraňuje podľa vlastných pravidiel. Pravidlá uchovávania sa z tohto uzla nedajú zistiť; skontroluj ich priamo na zálohovacom serveri."
},
"explanation": "O tom, koľko výtlačkov sa uchováva a ako dlho sa uchováva. Bez nej sa cieľ naplní, kým neprestane prijímať nové kópie, a záloha, ktorú nemožno napísať, je tá, o ktorej sa dozviete v deň, keď ju potrebujete."
"explanation": "Doba uchovávania určuje, koľko kópií sa uchováva a ako dlho. Bez nej sa cieľové úložisko zaplní do tej miery, že prestane prijímať nové kópie, a o zálohe, ktorú nie je možné zapísať, sa dozviete práve v deň, keď ju budete potrebovať."
},
"verification_state": {
"title": "Overenie záloh",
@@ -6132,10 +6132,10 @@
"evaluationFailed": "Stav overenia sa nepodarilo prečítať"
},
"nextStep": {
"failed": "Kópiu, ktorá nie je overená, nemožno použiť. Skontrolujte, či skoršia kópia rovnakého hosťa overené, a pozrite sa na skladovanie neúspešné kópie naživo.",
"notVerified": "Nič nepotvrdilo, že tieto kópie sa dajú prečítať späť. Záložný server môže overiť svoj vlastný rozvrh, oddelene od úlohy, ktorá ich napísala."
"failed": "Na kópiu, ktorá neprešla overením, sa nedá spoľahnúť. Skontrolujte, či bola overená skoršia kópia toho istého hosťa, a pozrite sa na úložisko, na ktorom sa nachádzajú neúspešné kópie.",
"notVerified": "Nič nepotvrdilo, že tieto kópie je možné opäť prečítať. Záložný server môže overovať podľa vlastného harmonogramu, nezávisle od úlohy, ktorá ich vytvorila."
},
"explanation": "Overenie číta uložené kópie späť a potvrdzuje, že je neporušený. Je to rozdiel medzi kópiou, ktorá existuje, a kópiou, ktorá môže byť prečítaná, rozdiel, ktorý záleží len na dni, kedy ho potrebujete."
"explanation": "Pri overovaní sa načíta uložená kópia a potvrdí sa, že je neporušená. Ide o rozdiel medzi kópiou, ktorá existuje, a kópiou, ktorú je možné prečítať – toto rozlíšenie má význam až v deň, keď ju budete potrebovať."
},
"job_results": {
"title": "Výsledky zálohovacích behov",
@@ -6147,10 +6147,10 @@
"recovered": "{count} z {total} VM a LXC zlyhalo pri skoršom spustení a odvtedy uspelo"
},
"nextStep": {
"recovered": "Títo hostia zlyhali a odvtedy sa im to podarilo. Predchádzajúca chyba stále stojí za čítanie: zlyhanie, ktoré vyrieši sám často vracia.",
"recovered": "Týmto hosťom sa predchádzajúci pokus nepodaril, ale neskôr uspeli. Stojí za to si prečítať popis tej predchádzajúcej chyby: chyba, ktorá sa sama vyriešila, sa často vráti.",
"someFailed": "Pri týchto behoch si pozrite chybu v zázname úloh. Beh, ktorý skončil chybou, považujte za neúspešný. Skôr než sa na zálohu spoľahnete, overte dostupnú kópiu pre príslušné VM a LXC."
},
"explanation": "Ako sa posledná práca skončila, ako to nahral tento uzol. Práca môže byť nakonfigurovaná dokonale a stále zlyhá každú noc, a to je miesto, kde to ukazuje."
"explanation": "Ako skončilo posledné spustenie každej úlohy, tak ako to zaznamenal tento uzol. Úloha môže byť dokonale nakonfigurovaná a napriek tomu zlyháva každú noc, a práve tu sa to prejaví."
},
"host_recovery": {
"title": "Obnova servera",
@@ -6162,11 +6162,11 @@
"scheduledOnly": "Zálohy nastavení servera sú naplánované cez {count} časovačov, lokálne však nie je uložený žiadny archív"
},
"nextStep": {
"attention": "Prehľadajte uvedené záznamy konfigurácie hostiteľa. Každý má niečo, čo stojí za to pozrieť sa na: beh, ktorý zlyhal, cieľ, ktorý je preč, alebo výtlačok starší ako vek v používaní.",
"scheduledOnly": "Časovač bude produkovať zálohovanie konfigurácie hostiteľa, ale žiadny ešte nie je uložený. Kým prvý beží, uzol vlastné nastavenie nie je chránené.",
"attention": "Prezrite si uvedené konfiguračné záznamy hostiteľov. V každom z nich sa nachádza niečo, čo stojí za pozornosť: neúspešné spustenie, cieľ, ktorý už neexistuje, alebo kópia staršia, než je povolená doba používania.",
"scheduledOnly": "Časovač bude vytvárať zálohy konfigurácie hostiteľa, zatiaľ však nie je uložená žiadna. Pokiaľ sa nespustí prvá záloha, vlastná konfigurácia uzla nie je chránená.",
"noHostBackup": "ProxMenux tu nemá zaznamenanú uloženú zálohu nastavení servera. Ak neexistuje iná záloha, ktorú tento uzol nevidí, pri obnove servera by bolo potrebné úložiská, sieť a používateľské účty nastaviť ručne podľa dostupných poznámok."
},
"explanation": "Zálohovanie hostí neobnoví uzol. Táto kontrola sa pozerá na to, či uzol vlastné konfigurácia"
"explanation": "Zálohovanie hostí nevedie k obnoveniu uzla. Táto kontrola overuje, či je vlastná konfigurácia uzla – jeho definície úložísk, sieťové nastavenia a používatelia – uložená niekde, od čoho závisí samotná obnova hostiteľa."
}
},
"system": {
@@ -6977,8 +6977,8 @@
"withoutLynis": "Spustiť bez Lynisu",
"cancel": "Zrušiť"
},
"noActionNeeded": "Nemám čo robiť. Tento šek našiel to, čo očakáva.",
"couldNotEvaluate": "Tento šek nemohol byť vyhodnotený, takže nič nehlási. Dôkazy zaznamenávajú, čo nebolo možné prečítať."
"noActionNeeded": "Nie je čo robiť. Táto kontrola potvrdila to, čo sa očakávalo.",
"couldNotEvaluate": "Túto kontrolu nebolo možné vyhodnotiť, preto sa v správe neuvádza žiadny výsledok. V zázname je uvedené, čo sa nepodarilo prečítať."
},
"runtime": {
"notifications": {
+7 -1
View File
@@ -27,6 +27,8 @@ import sys
import time
from typing import Any, Optional
import disk_identity
SCHEMA_VERSION = 2
# Disk entries in a guest configuration: rootfs and mpN for containers,
@@ -630,12 +632,16 @@ def _physical_disks(ctx) -> list[dict[str, Any]]:
size = row.get("SIZE", "")
name = row.get("NAME", "")
health = smart.get(name) or {}
# The Monitor's rotation when it read the disk, so both agree.
rate = health.get("rotation_rate")
if not isinstance(rate, int):
rate = -1 if row.get("ROTA") == "1" else 0
disks.append({
"name": name,
"model": (row.get("MODEL") or "").strip(),
"serial": (row.get("SERIAL") or "").strip(),
"size_bytes": int(size) if size.isdigit() else None,
"rotational": row.get("ROTA") == "1",
"rotational": disk_identity.media_type(name, rate) == "HDD",
"bus": (row.get("TRAN") or "").strip(),
"health": health.get("smart_status"),
"temperature": health.get("temperature"),
+22
View File
@@ -15,6 +15,7 @@ import subprocess
from typing import Any, Dict, List
_LSBLK_TIMEOUT = 5
_SYS_BLOCK = "/sys/block"
_FIELD_RE = re.compile(r'(\w+)="([^"]*)"')
_SKIP_PREFIXES = ("loop", "zd", "nbd", "ram", "sr")
@@ -69,6 +70,27 @@ def list_physical_disks() -> List[Dict[str, Any]]:
return disks
def rotation_rate(name: str, reported: Any = None) -> int:
"""The rotation every view of a disk shows: the RPM smartctl reported,
0 meaning solid state, or else the kernel's flag, where -1 is a spinning
disk of unknown speed. What smartctl reported wins, because USB-SATA
bridges mark every disk behind them as rotational."""
if isinstance(reported, int) and not isinstance(reported, bool) and reported >= 0:
return reported
try:
with open(f"{_SYS_BLOCK}/{name}/queue/rotational") as flag:
return -1 if flag.read().strip() == "1" else 0
except OSError:
return 0
def media_type(name: str, rate: int) -> str:
"""NVMe, SSD or HDD, from a rotation as ``rotation_rate`` returns it."""
if name.startswith("nvme"):
return "NVMe"
return "HDD" if rate else "SSD"
def names_for_keys(keys) -> set:
"""Current kernel names of the disks whose identity is in ``keys``."""
if not keys:
+26 -28
View File
@@ -52,6 +52,7 @@ import time
import threading
import urllib.parse
import uuid
import disk_identity
import hardware_monitor
from health_persistence import health_persistence
import xml.etree.ElementTree as ET
@@ -98,6 +99,7 @@ from flask_notification_routes import notification_bp # noqa: E402
from flask_oci_routes import oci_bp # noqa: E402
from flask_audit_routes import audit_bp # noqa: E402
from flask_vm_backup_routes import vm_backup_bp # noqa: E402
from flask_vm_backup_routes import active_vzdump # noqa: E402
from guest_backup_archives import (BackupArchiveError, delete_guest_backups,
guest_backup_deletion_status) # noqa: E402
from notification_manager import notification_manager, resolve_notification_hostname # noqa: E402
@@ -5263,11 +5265,7 @@ def _smart_identity_payload(disk_name):
base['serial'] = value.strip()
except OSError:
pass
try:
if Path(f'/sys/block/{disk_name}/queue/rotational').read_text().strip() == '1':
base['rotation_rate'] = -1 # HDD, RPM unknown
except OSError:
pass
base['rotation_rate'] = disk_identity.rotation_rate(disk_name)
return base
@@ -5327,7 +5325,8 @@ def get_smart_data(disk_name):
retry_at = _smart_fail_backoff.get(disk_name, 0)
if retry_at > now:
return dict(cached[1]) if cached else _smart_default_payload()
# smartctl keeps failing: show what the host knows of the disk.
return dict(cached[1]) if cached else _smart_identity_payload(disk_name)
result = _get_smart_data_uncached(disk_name)
@@ -5801,6 +5800,11 @@ def _get_smart_data_uncached(disk_name):
# print(f"[v0] Health: CRITICAL (SMART failed)")
pass
# Without an answer from smartctl, the kernel's flag; the temperature
# class below depends on it.
if not smart_data['_rotation_known']:
smart_data['rotation_rate'] = disk_identity.rotation_rate(disk_name)
# Temperature-based health (only if we have a valid temperature)
# Thresholds differ by disk class (HDD/SSD/NVMe/SAS) and are
# user-configurable via health_thresholds; the values below are
@@ -5831,27 +5835,6 @@ def _get_smart_data_uncached(disk_name):
smart_data['health'] = 'critical'
elif temp > warn:
smart_data['health'] = 'warning'
# Fallback: ask the kernel only when smartctl had no opinion.
# USB-SATA enclosures (ASM105x family etc.) advertise
# rotational=1 to the kernel even when there's an SSD behind
# them, so trusting /sys here without first checking what
# smartctl said would flip a correctly-identified SSD back to
# HDD. The previous condition (`rotation_rate == 0`) couldn't
# tell "smartctl confirmed SSD" from "smartctl never spoke",
# which is what bit the OCZ-SOLID2 behind an ASM105x dock on
# the lab host (sdd showed as HDD in the UI while smartctl
# was reporting it as SSD).
if not smart_data['_rotation_known']:
try:
rotational_path = f"/sys/block/{disk_name}/queue/rotational"
if os.path.exists(rotational_path):
with open(rotational_path, 'r') as f:
rotational = int(f.read().strip())
if rotational == 1:
smart_data['rotation_rate'] = -1 # HDD, RPM unknown
except Exception:
pass
except FileNotFoundError:
# print(f"[v0] ERROR: smartctl not found - install smartmontools for disk monitoring.")
pass
@@ -11523,7 +11506,7 @@ def api_smart_status(disk_name):
'temperature': temp,
'power_on_hours': poh,
'power_cycles': cycles,
'rotation_rate': data.get('rotation_rate', 0),
'rotation_rate': disk_identity.rotation_rate(disk_name, data.get('rotation_rate')),
'form_factor': form_factor,
'physical_block_size': physical_block_size,
'trim_supported': trim_supported,
@@ -13429,6 +13412,7 @@ def api_create_backup(vmid):
pass
unit = f'proxmenux-vzdump-{vmid}-{uuid.uuid4().hex[:8]}'
out_path = os.path.join(run_dir, f'vzdump-{unit}.out')
since = int(time.time()) - 1
launch = subprocess.run(
['systemd-run', f'--unit={unit}', '--collect', '--quiet',
f'--description=ProxMenux backup of {vm_type.upper()} {vmid}',
@@ -13456,7 +13440,21 @@ def api_create_backup(vmid):
capture_output=True, text=True).stdout.strip()
if state not in ('active', 'activating'):
break
# pvesh prints the UPID only once the backup has ended.
upid = active_vzdump(node, since)
if upid:
break
time.sleep(0.3)
if upid is None:
# A short backup can finish between two reads.
try:
with open(out_path, encoding='utf-8', errors='replace') as handle:
buf = handle.read()
except OSError:
pass
m = upid_re.search(buf)
if m:
upid = m.group(0).rstrip(':')
if upid is None:
tail = buf.strip() or 'pvesh exited without producing a UPID'
return jsonify({
+87 -5
View File
@@ -24,7 +24,10 @@ policy only changes the native storage configuration; it never runs pruning.
import json
import os
import re
import shutil
import subprocess
import time
import uuid
from flask import Blueprint, jsonify, request
@@ -395,6 +398,86 @@ def _run_arguments(job):
return args
# A job of several guests leaves the id of its task empty.
UPID_RE = re.compile(r"UPID:[^:\s]+:[^:\s]+:[^:\s]+:[^:\s]+:vzdump:[^:\s]*:[^:\s]+:")
RUN_DIR = "/run/proxmenux"
def active_vzdump(node, since):
"""The UPID of the first backup task the node started at or after `since`."""
ok, tasks = _pvesh_json(["get", f"/nodes/{node}/tasks", "--source", "active", "--typefilter", "vzdump"])
if not ok or not isinstance(tasks, list):
return None
started = sorted((task for task in tasks if isinstance(task, dict)
and UPID_RE.match(str(task.get("upid") or ""))
and isinstance(task.get("starttime"), int) and task["starttime"] >= since),
key=lambda task: task["starttime"])
return started[0]["upid"].rstrip(":") if started else None
def _start_vzdump(node, arguments, job_id):
"""Start the part of a job that runs on a node and return its task UPID.
pvesh waits for the whole backup and prints the UPID only at the end, and
a child of the Monitor is killed with its service, so vzdump runs in its
own transient unit and its UPID is read from the node's active tasks. The
task then runs to the end on its own. Returns (upid, error)."""
if not shutil.which("systemd-run"):
return None, "systemd-run not found"
run_dir = RUN_DIR
try:
os.makedirs(run_dir, mode=0o700, exist_ok=True)
now = time.time()
for old in os.listdir(run_dir):
old_path = os.path.join(run_dir, old)
if old.startswith("vzdump-") and now - os.path.getmtime(old_path) > 86400:
os.remove(old_path)
except OSError:
pass
unit = f"proxmenux-vzdump-job-{uuid.uuid4().hex[:8]}"
out_path = os.path.join(run_dir, f"vzdump-{unit}.out")
since = int(time.time()) - 1
try:
launch = subprocess.run(
["systemd-run", f"--unit={unit}", "--collect", "--quiet",
f"--description=ProxMenux backup job {job_id}",
f"--property=StandardOutput=file:{out_path}",
"pvesh", "create", f"/nodes/{node}/vzdump", *arguments],
capture_output=True, text=True, timeout=15)
except subprocess.TimeoutExpired:
return None, "systemd-run timed out"
if launch.returncode != 0:
return None, (launch.stderr or launch.stdout).strip()
buf = ""
deadline = time.time() + 10.0
while time.time() < deadline:
try:
with open(out_path, encoding="utf-8", errors="replace") as handle:
buf = handle.read()
except OSError:
buf = ""
found = UPID_RE.search(buf)
if found:
return found.group(0).rstrip(":"), None
state = subprocess.run(["systemctl", "is-active", unit], capture_output=True, text=True).stdout.strip()
if state not in ("active", "activating"):
break
upid = active_vzdump(node, since)
if upid:
return upid, None
time.sleep(0.5)
# A short backup can finish between two reads: its UPID is the last line.
try:
with open(out_path, encoding="utf-8", errors="replace") as handle:
buf = handle.read()
except OSError:
pass
found = UPID_RE.search(buf)
if found:
return found.group(0).rstrip(":"), None
return None, (buf.strip() or "pvesh exited without producing a UPID")[-800:]
@vm_backup_bp.route("/api/vm-backup-jobs/<job_id>/run", methods=["POST"])
@require_admin_scope
def run_job(job_id):
@@ -418,12 +501,11 @@ def run_job(job_id):
for node in nodes:
if not NODE_RE.match(node):
continue
ok, out = _pvesh(["create", f"/nodes/{node}/vzdump", *arguments])
if ok:
found = re.search(r"UPID:[^\s\"']+", out)
tasks.append({"node": node, "upid": found.group(0) if found else ""})
upid, error = _start_vzdump(node, arguments, job_id)
if upid:
tasks.append({"node": node, "upid": upid})
else:
failures.append({"node": node, "error": out})
failures.append({"node": node, "error": error})
if not tasks:
return _err(failures[0]["error"] if failures else "The backup could not be started", 500)
return jsonify({"success": True, "tasks": tasks, "failures": failures})
+4 -1
View File
@@ -3163,7 +3163,10 @@ class NotificationManager:
if not ok:
raise ValueError(f"Invalid ai_ollama_url: {err}")
if short_key == 'ai_openai_base_url' and str(value):
ok, err = validate_external_url(str(value), allow_loopback=False)
# Custom OpenAI-compatible servers can run on the LAN or
# localhost, just like Ollama. Match test-ai/provider-models;
# unsafe schemes, metadata hosts and link-local stay blocked.
ok, err = validate_external_url(str(value), allow_loopback=True)
if not ok:
raise ValueError(f"Invalid ai_openai_base_url: {err}")
@@ -69,6 +69,41 @@ class OpenAICompatibleModelTests(unittest.TestCase):
self.addCleanup(patcher.stop)
return db_path
def test_local_compatible_endpoint_can_be_saved_and_reloaded(self):
db_path = self._temp_db_patch()
# Synthetic addresses cover each RFC1918 range; no network is used.
for url in ('http://10.0.0.10:8080/v1', 'http://172.16.0.10:8080/v1',
'http://192.168.1.10:8080/v1', 'http://localhost:8080/v1',
'http://127.0.0.1:8080/v1'):
with self.subTest(url=url):
manager = self._manager({})
result = manager.save_settings({'ai_openai_base_url': url})
self.assertTrue(result['success'], result)
with sqlite3.connect(db_path) as conn:
saved = conn.execute(
'SELECT setting_value FROM user_settings WHERE setting_key=?',
('notification.ai_openai_base_url',),
).fetchone()
self.assertEqual(saved, (url,))
reloaded = self._manager({})
reloaded._load_config()
self.assertEqual(reloaded._config['ai_openai_base_url'], url)
def test_local_compatible_endpoint_keeps_unsafe_urls_blocked(self):
db_path = self._temp_db_patch()
for url in ('file:///etc/shadow', 'http://169.254.169.254/latest/meta-data/',
'http://metadata.google.internal/', 'http://[fe80::1]/',
'http://0.0.0.0:8080/v1', 'http://224.0.0.1/v1'):
with self.subTest(url=url):
result = self._manager({}).save_settings({'ai_openai_base_url': url})
self.assertFalse(result['success'], result)
with sqlite3.connect(db_path) as conn:
saved = conn.execute(
'SELECT setting_value FROM user_settings WHERE setting_key=?',
('notification.ai_openai_base_url',),
).fetchone()
self.assertIsNone(saved)
def test_custom_openai_endpoint_omits_temperature_for_opaque_alias(self):
provider = CapturingOpenAIProvider(
api_key="token",
+2
View File
@@ -23,6 +23,7 @@ A special thank you goes to [@Vaso73](https://github.com/Vaso73), [@f3rs3n](http
- **The Ollama entry describes what the image provides** ([PR #566](https://github.com/MacRimi/ProxMenux/pull/566), contributed by [@jcastro](https://github.com/jcastro)): its HTTP API on port 11434, with its link and startup check on `/api/version`.
- **An update clears the snapshot an interrupted backup leaves** ([#565](https://github.com/MacRimi/ProxMenux/issues/565), reported by [@kiosvantra](https://github.com/kiosvantra)). A snapshot made by the user stops the update, because a rebuilt container cannot keep it.
- **A container that ignores the shutdown signal is stopped after 60 seconds**, as `docker stop` does, during an update and when an interrupted operation is recovered.
- **Modify and updates accept every application whose image declares a data path**: SearXNG, Tor, Whoogle and BIND9 keep it in a volume of its own, Kanboard keeps its certificates, and Chrony, Jaeger, PlantUML, UrBackup, GoToSocial, AceStream HTTP Proxy and RomM mark the paths that hold no data. When an installation still keeps such a path in the container, the message names it.
## 🖥️ Monitor — Proxmox updates and pending reboots
@@ -59,6 +60,7 @@ A special thank you goes to [@Vaso73](https://github.com/Vaso73), [@f3rs3n](http
- **Bitwarden recognizes the 2FA field on the Monitor login** ([#570](https://github.com/MacRimi/ProxMenux/issues/570), reported by [@shtefko](https://github.com/shtefko)): the backup code hint keeps its text and place, outside the group of the field.
- **Secure Gateway installs on Proxmox hosts on BTRFS** ([#564](https://github.com/MacRimi/ProxMenux/issues/564), reported by [@78v5](https://github.com/78v5)): the Alpine template goes to an active storage that holds container templates.
- **A disk I/O error from the kernel is recorded on its disk**, with its serial number, also when the error names a partition.
- **Every view of a disk shows the same type**: the Storage page, the disk details, the SMART report and the Audit & Report inventory take it from one source. A hard disk smartctl cannot read keeps its type, model and serial number, and a hard disk that reports no speed shows as HDD.
- **The Monitor installs as an app (PWA) from the browser**: it serves its own web app manifest and service worker, with the 192 and 512 px icons Chrome requires.
- **The Y-axis titles stay inside the overview charts** ([PR #539](https://github.com/MacRimi/ProxMenux/pull/539), contributed by [@f3rs3n](https://github.com/f3rs3n)).
- **The application version-tracking catalog builds from the current Helper-Scripts repositories**.
+53
View File
@@ -184,6 +184,7 @@
"A tunneling daemon by Cloudflare that safely exposes your web servers into the internet.": "Ein Tunnel-Daemon von Cloudflare, der Ihre Webserver sicher im Internet aussetzt.",
"A unified email and collaboration server.": "Ein einheitlicher E-Mail- und Kollaborationsserver.",
"A unified platform for logs, metrics and traces.": "Eine einheitliche Plattform für Logs, Metriken und Traces.",
"A validating, recursive DNS resolver for your private network.": "Ein validierender, rekursiver DNS-Resolver für Ihr privates Netzwerk.",
"A versatile file conversion tool that supports multiple formats.": "Ein vielseitiges Dateikonvertierungstool, das mehrere Formate unterstützt.",
"A visual tool for exploring and documenting database schemas.": "Ein visuelles Werkzeug zum Erkunden und Dokumentieren von Datenbankschemata.",
"A web GUI client of Project V which supports VMess, VLESS, SS, SSR, Trojan, Tuic and Juicity protocols": "Ein Web-GUI-Client von Project V, der die Protokolle VMess, VLESS, SS, SSR, Trojan, Tuic und Juicity unterstützt",
@@ -256,6 +257,7 @@
"Acceleration for llama.cpp": "Beschleunigung für llama.cpp",
"Accept routes from other nodes?": "Routen von anderen Knoten akzeptieren?",
"Accept this host monitoring profile?": "Akzeptieren Sie dieses Host Monitoring Profil?",
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Zugriff auf die Movistar- und O2-Cloud über WebDAV-Clients und Backup-Werkzeuge.",
"Access Scope:": "Zugriffsbereich:",
"Access bridge": "Zugangsbrücke",
"Access bridge for Immich": "Access Bridge für Immich",
@@ -410,6 +412,7 @@
"After the reboot, you will only be able to access the Proxmox host via:": "Nach dem Neustart können Sie nur noch auf den Proxmox-Host zugreifen über:",
"After this LXC → VM switch, reboot the host so the new binding state is applied cleanly.": "Starten Sie nach diesem Wechsel von LXC → VM den Host neu, damit der neue Bindungsstatus sauber angewendet wird.",
"Agentless monitoring and observability platform.": "Agentenlose Plattform für Monitoring und Observability.",
"AirDC++ administrator": "AirDC++-Administrator",
"Airsonic Advanced web interface": "Airsonic Advanced Web-Schnittstelle",
"Airsonic-advanced is a free, web-based media streamer, providing ubiquitious access to your music. Use it to share your music with friends, or to listen to your own music while at work. You can stream to multiple players simultaneously, for instance to one player in your kitchen and another in your living room.": "Airsonic-advanced ist ein kostenloser, webbasierter Medienstreamer, der ubiquitious Zugang zu Ihrer Musik bietet. Verwenden Sie es, um Ihre Musik mit Freunden zu teilen oder Ihre eigene Musik während der Arbeit zu hören. Sie können zu mehreren Spielern gleichzeitig streamen, zum Beispiel zu einem Spieler in Ihrer Küche und einem anderen in Ihrem Wohnzimmer.",
"Aliases added to .bashrc": "Aliase wurden zu .bashrc hinzugefügt",
@@ -598,11 +601,15 @@
"Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Achtung: Das Entfernen des Abonnementbanners kann nach einem zukünftigen Update zu Problemen in der Weboberfläche führen.",
"Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity ist ein einfach zu bedienender, mehrspuriger Audio-Editor und Recorder. Entwickelt von einer Gruppe von Freiwilligen als Open Source.",
"Audio device directory": "Audiogeräteverzeichnis",
"Audio recording and mixing in your browser": "Audioaufnahme und -mischung im Browser",
"Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf ist ein selbst gehosteter Hörbuch- und Podcast-Server.",
"Audit completed. Press Enter to continue...": "Prüfung abgeschlossen. Drücken Sie die Eingabetaste, um fortzufahren...",
"Audit socket disabled or not required": "Audit-Socket deaktiviert oder nicht erforderlich",
"Auth key is required.": "Authentifizierungsschlüssel ist erforderlich.",
"Auth:": "Authentifizierung:",
"Authelia Web UI": "Authelia Web-Benutzeroberfläche",
"Authelia administrator": "Authelia-Administrator",
"Authelia session cookie domain for this portal (for example example.com)": "Authelia Sitzungscookie-Domäne für dieses Portal (z. B. example.com)",
"Authentication": "Authentifizierung",
"Authentication & Security": "Authentifizierung und Sicherheit",
"Authentication Error": "Authentifizierungsfehler",
@@ -642,6 +649,7 @@
"Available PVE Version": "Verfügbare PVE-Version",
"Available Shares:": "Verfügbare Aktien:",
"Available action": "Verfügbare Aktion",
"Available applications: {count}": "Verfügbare Anwendungen: {count}",
"Available archives:": "Verfügbare Archive:",
"Available disks detected.": "Verfügbare Festplatten erkannt.",
"Available host backups:": "Verfügbare Host-Backups:",
@@ -873,6 +881,7 @@
"Cannot write the image archive to {storage}. Check storage access and mount status.": "Das Bildarchiv kann nicht in {storage} geschrieben werden. Überprüfen Sie den Speicherzugriff und den Bereitstellungsstatus.",
"Capabilities cannot be kept and all dropped at the same time": "Fähigkeiten können nicht gehalten werden und alle gleichzeitig fallen gelassen werden",
"Catalog options": "Katalogoptionen",
"Catalog refresh unavailable; using the local catalog.": "Der Katalog konnte nicht aktualisiert werden; der lokale Katalog wird verwendet.",
"Category": "Kategorie",
"Caution: Maximum mode generates more heat.": "Achtung: Im Maximalmodus entsteht mehr Wärme.",
"Central server for file and image backups.": "Zentraler Server für Datei- und Bildsicherungen.",
@@ -1159,6 +1168,7 @@
"Compressing": "Komprimieren",
"Compression": "Komprimierung",
"Compression Tools": "Komprimierungswerkzeuge",
"Computer-aided design and drafting in your browser": "Computergestütztes Konstruieren und technisches Zeichnen im Browser",
"Concise output of logical volumes": "Übersichtliche Ausgabe logischer Volumes",
"Concise output of physical volumes": "Übersichtliche Ausgabe physischer Datenträger",
"Concise output of volume groups": "Übersichtliche Ausgabe von Volumengruppen",
@@ -1393,6 +1403,7 @@
"Controller + NVMe": "Controller + NVMe",
"Controller + NVMe assignment will be written now and become active after host reboot.": "Die Controller + NVMe-Zuweisung wird jetzt geschrieben und wird nach dem Neustart des Hosts aktiv.",
"Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.": "Controller + NVMe-Passthrough erfordern Maschinentyp q35. Controller-Zuweisung wird übersprungen.",
"Controller path on the Proxmox host; prefer /dev/serial/by-id/...": "Controller-Pfad auf dem Proxmox-Host;lieber /dev/serial/by-id/...",
"Controller/NVMe Conflict Policy": "Controller-/NVMe-Konfliktrichtlinie",
"Controller/NVMe already present in VM config": "Controller/NVMe bereits in der VM-Konfiguration vorhanden",
"Controller/NVMe already present in VM config (%s)": "Controller/NVMe ist bereits in der VM-Konfiguration vorhanden (%s)",
@@ -1927,6 +1938,7 @@
"Dgraph": "Dgraph",
"Diff: current system vs backup (--- system +++ backup)": "Unterschied: aktuelles System vs. Backup (--- System +++ Backup)",
"Different host. Backup from:": "Anderer Gastgeber. Backup von:",
"Direct Connect file sharing with a web interface": "Direct-Connect-Dateifreigabe mit Weboberfläche",
"Direct conversion completed for container": "Direkte Konvertierung für Container abgeschlossen",
"Directory Exists": "Verzeichnis existiert",
"Directory Not Empty": "Verzeichnis nicht leer",
@@ -3340,6 +3352,7 @@
"Initial Stirling-PDF account": "Erstes Stirling-PDF-Konto",
"Initial Tandoor administrator": "Initial Tandoor Administrator",
"Initial Umami administrator": "Erster Administrator für Umami",
"Initial Z-Wave JS UI admin password": "Ursprüngliches Z-Wave JS UI-Administratorkennwort",
"Initial administrator created:": "Erster Administrator erstellt:",
"Initial administrator user": "Erster Administrator",
"Initializing Borg repository if needed...": "Initialisierung des Borg-Repositorys bei Bedarf ...",
@@ -3525,6 +3538,7 @@
"Interface MTU": "Schnittstellen-MTU",
"Interface Names (persistent)": "Schnittstellennamen (persistent)",
"Interface Type": "Schnittstellentyp",
"Interface design and prototyping in your browser": "Oberflächendesign und Prototyping im Browser",
"Interface names will return to default systemd behavior.": "Schnittstellennamen kehren zum Standardverhalten von systemd zurück.",
"Interface type:": "Schnittstellentyp:",
"Interfaces configured": "Schnittstellen konfiguriert",
@@ -3740,6 +3754,7 @@
"Jupyter Lab (token only)": "Jupyter Lab (nur Token)",
"JupyterLab": "JupyterLab",
"JupyterLab access token": "Zugriffstoken für JupyterLab",
"KDE's twin-panel file manager in a browser-based desktop.": "Der Twin-Panel-Dateimanager von KDE in einem browserbasierten Desktop.",
"KDF:": "KDF:",
"KROMA": "KROMA",
"KVM MSR options added to /etc/modprobe.d/kvm.conf": "KVM-MSR-Optionen zu /etc/modprobe.d/kvm.conf hinzugefügt",
@@ -3787,12 +3802,14 @@
"KiCad - A Cross Platform and Open Source Electronics Design Automation Suite.": "KiCad - Eine Cross-Plattform und Open Source Electronics Design Automation Suite.",
"Kimai has no default account. Enter the container with: pct enter {main_vmid}": "Kimai hat kein Standardkonto. Öffnen Sie eine Shell im Container mit: pct enter {main_vmid}",
"Kimai is a professional grade time-tracking application, free and open-source.": "Kimai ist eine professionelle Time-Tracking-Anwendung, kostenlos und Open-Source.",
"KitchenOwl": "KitchenOwl",
"Kometa is a powerful tool designed to give you complete control over your media libraries. With Kometa, you can take your customization to the next level, with granular control over metadata, collections, overlays, and much more.": "Kometa ist ein leistungsstarkes Tool, das Ihnen die vollständige Kontrolle über Ihre Medienbibliotheken gibt. Mit Kometa können Sie Ihre Anpassung auf die nächste Ebene bringen, mit granularer Kontrolle über Metadaten, Sammlungen, Overlays und vielem mehr.",
"Kometa reads its configuration from /config/config.yml and the container only ships /config/config.yml.template. Copy the template to config.yml, fill in the required Plex and TMDb connections, then restart the container.": "Kometa liest seine Konfiguration aus /config/config.yml und der Container liefert nur /config/config.yml.template. Kopieren Sie die Vorlage auf config.yml, füllen Sie die required Plex und TMDb-Verbindungen aus und starten Sie dann den Container neu.",
"Komga is a media server for your comics, mangas, BDs, magazines and eBooks.": "Komga ist ein Medienserver für Ihre Comics, Mangas, BDs, Magazine und eBooks.",
"Kopia Web UI": "Kopia-Weboberfläche",
"Kopia Web UI login": "Anmeldung an der Kopia-Weboberfläche",
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita ist ein professionelles kostenloses und Open-Source-Malprogramm. Es wird von Künstlern gemacht, die erschwingliche Kunstwerkzeuge für alle sehen wollen.",
"Krusader Web UI": "Krusader Web-Benutzeroberfläche",
"LAN access to the kept containers (stack configuration incomplete):": "LAN-Zugriff auf die aufbewahrten Container (Stack-Konfiguration unvollständig):",
"LAN address applied to the application URLs": "LAN-Adresse für die Anwendungs-URLs",
"LLDAP": "LLDAP",
@@ -4020,6 +4037,7 @@
"Manage OCI stack": "Verwalten des OCI-Stacks",
"Manage PBS encryption keyfile": "PBS-Verschlüsselungsschlüsseldatei verwalten",
"Manage Secure Gateway": "Secure Gateway verwalten",
"Manage a Z-Wave network from a web dashboard and WebSocket gateway.": "Verwalten Sie ein Z-Wave-Netzwerk über ein Web-Dashboard und ein WebSocket-Gateway.",
"Manage and inspect VM disk images": "Verwalten und überprüfen Sie VM-Festplatten-Images",
"Manage custom backup paths": "Benutzerdefinierte Sicherungspfade verwalten",
"Manage custom paths (add / remove your folders)": "Benutzerdefinierte Pfade verwalten (Ordner hinzufügen/entfernen)",
@@ -4029,6 +4047,7 @@
"Manage local backup target": "Lokales Backup-Ziel verwalten",
"Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Private Bildregister verwalten.\nGespeicherte Anmeldeinformationen ermöglichen ProxMenux den Zugriff auf Ihre privaten Bilder.",
"Manage registry accounts as root on the Proxmox node.": "Registrierungskonten als Root auf dem Proxmox-Knoten verwalten.",
"Manage teams of AI agents from a web dashboard.": "Verwalte Teams von KI-Agenten über ein Web-Dashboard.",
"Managed disks must have backup enabled and a valid size": "Managed Disks müssen Backup aktiviert und eine gültige Größe haben",
"Managed public route include is missing": "Die Konfigurationsdatei für die verwalteten öffentlichen Routen fehlt",
"Managed public route installation failed": "Die verwalteten öffentlichen Routen konnten nicht eingerichtet werden",
@@ -4134,6 +4153,7 @@
"Monitoring": "Überwachung",
"Monitoring & Analytics": "Überwachung und Auswertung",
"Most common cause: the archive is corrupted (interrupted write, partial copy, or storage issue).": "Häufigste Ursache: Das Archiv ist beschädigt (unterbrochener Schreibvorgang, teilweises Kopieren oder Speicherproblem).",
"Motion graphics and compositing in your browser": "Motion-Design und Compositing im Browser",
"Mount Added Successfully:": "Mount erfolgreich hinzugefügt:",
"Mount CIFS share:": "CIFS-Freigabe bereitstellen:",
"Mount Configuration Summary:": "Zusammenfassung der Mount-Konfiguration:",
@@ -4434,6 +4454,7 @@
"New Search": "Neue Suche",
"New VM:": "Neue VM:",
"New Virtual Machine": "Neue virtuelle Maschine",
"New applications since your last visit: {count}": "Neue Anwendungen seit Ihrem letzten Besuch: {count}",
"New backup job": "Neuer Sicherungsauftrag",
"New backups on this host will be unencrypted until a new keyfile is set up.": "Neue Backups auf diesem Host werden unverschlüsselt sein, bis eine neue Schlüsseldatei eingerichtet wird.",
"New image compatible:": "Neues Bild kompatibel:",
@@ -4896,6 +4917,8 @@
"Open the page of an application in the menu": "Die Seite einer Anwendung im Menü öffnen",
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Öffne die Webadresse und erstelle das erste Konto: Der Daemon registriert sich selbst und startet den ersten Scan.",
"Open the web address and create the password of the akadmin user in the first-run setup.": "Öffnen Sie die Webadresse und erstellen Sie im ersten Setup das Passwort des akadmin-Benutzers.",
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured.": "Öffnen Sie die Webadresse und befolgen Sie die Onboarding-Anweisungen von KitchenOwl, um das erste Konto zu erstellen. Es ist kein Standardkonto konfiguriert.",
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Öffnen Sie das Web-Dashboard und verknüpfen Sie Ihr Movistar/O2-Konto über die SMS-Bestätigung.",
"Open-source AI-powered coding assistant": "Open-Source AI-powered Coding Assistant",
"Open-source UI for building and debugging multi-agent and RAG applications": "Open-Source-Benutzeroberfläche zum Erstellen und Debuggen von Multi-Agenten- und RAG-Anwendungen",
"Open-source in-memory data store.": "Open-Source-Datenspeicher im Arbeitsspeicher.",
@@ -5018,6 +5041,7 @@
"Packages:": "Pakete:",
"Packaging OVA file...": "OVA-Datei verpacken...",
"Packing installer archive...": "Installationsarchiv packen...",
"Page layout and publishing in your browser": "Seitenlayout und Publizieren im Browser",
"PairDrop is a sublime alternative to AirDrop that works on all platforms. Send images, documents or text via peer to peer connection to devices in the same local network/Wi-Fi or to paired devices.": "PairDrop ist eine großartige Alternative zu AirDrop, die auf allen Plattformen funktioniert. Senden Sie Bilder, Dokumente oder Text per Peer-to-Peer-Verbindung an Geräte im gleichen lokalen Netzwerk / WLAN oder an gekoppelte Geräte.",
"Paperless configuration cancelled": "Papierlose Konfiguration abgesagt",
"Paperless-ngx WebUI": "Paperless-ngx WebUI",
@@ -5036,6 +5060,7 @@
"Pass /dev/video12 to the LXC": "Pass /dev/video12 zum LXC",
"Pass a host device to the LXC": "Übergeben Sie ein Host-Gerät an den LXC",
"Pass the UPS to the LXC": "Übergeben Sie die USV an LXC",
"Pass through a Z-Wave USB or serial controller": "Durchlaufen eines Z-Wave-USB- oder seriellen Controllers",
"Passing NVIDIA does not enable acceleration inside the application. The host needs NVIDIA Container Toolkit and a compatible image. Continue?": "Durch die Übergabe von NVIDIA wird keine Beschleunigung innerhalb der Anwendung aktiviert. Der Host benötigt NVIDIA Container Toolkit und ein kompatibles Image. Weitermachen?",
"Passkey-based identity provider for self-hosted apps.": "Passkey-basierter Identitätsanbieter für selbst gehostete Apps.",
"Passphrase used to unlock the imported keyfile (leave blank if the keyfile is unencrypted / kdf=none):": "Passphrase, die zum Entsperren der importierten Schlüsseldatei verwendet wird (leer lassen, wenn die Schlüsseldatei unverschlüsselt ist / kdf=none):",
@@ -5143,6 +5168,8 @@
"Personal finance management application": "Persönliche Finanzverwaltung Anwendung",
"Personal media server for browsing and playing a local video library, with direct play and optional modules.": "Persönlicher Medienserver zum Durchsuchen und Abspielen einer lokalen Videosammlung, mit Direktwiedergabe und optionalen Modulen.",
"Photo and video library with optional GPU transcoding and machine learning": "Foto- und Videobibliothek mit optionaler GPU-Transcodierung und maschinellem Lernen",
"Photo editing in your browser": "Fotobearbeitung im Browser",
"Photo library and RAW development in your browser": "Fotoverwaltung und RAW-Entwicklung im Browser",
"PhotoPrism": "PhotoPrism",
"Photofield": "Photofield",
"Phpmyadmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB.": "Phpmyadmin ist ein in PHP geschriebenes kostenloses Software-Tool, das die Verwaltung von MySQL über das Web übernehmen soll. phpMyAdmin unterstützt eine breite Palette von operationen auf MySQL und MariaDB.",
@@ -5235,6 +5262,7 @@
"Preparing the machine learning container for the new choice...": "Container für maschinelles Lernen wird für die neue Auswahl vorbereitet...",
"Preparing the recreation...": "Vorbereitung der Erholung...",
"Preparing the update...": "Vorbereitung des Updates...",
"Presentations and slide decks in your browser": "Präsentationen und Folien im Browser",
"Preserving logs to /var/log.hdd before unmounting...": "Protokolle werden vor dem Aufheben der Bereitstellung in /var/log.hdd beibehalten ...",
"Press 'q' to exit": "Drücken Sie „q“, um den Vorgang zu beenden",
"Press Ctrl+C to stop the server and return to menu.": "Drücken Sie Strg+C, um den Server zu stoppen und zum Menü zurückzukehren.",
@@ -5395,6 +5423,7 @@
"Proxmox web interface: Datacenter > Storage > Add > ZFS": "Proxmox-Weboberfläche: Datencenter > Speicher > Hinzufügen > ZFS",
"Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Proxmox-Weboberfläche: Rechenzentrum > Speicher > Hinzufügen > iSCSI",
"Proxy address to reach the API (optional)": "Proxy-Adresse zum Erreichen der API (optional)",
"Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)": "Öffentliche HTTPS-URL, die zum Öffnen dieses Authelia-Portals verwendet wird (zum Beispiel https://auth.example.com)",
"Public UDP port clients connect to": "Öffentliche UDP Port Clients verbinden sich mit",
"Public UDP port peers connect to": "Öffentliche UDP-Port Peers verbinden sich mit",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "Öffentliche URL von phpMyAdmin, wenn sie hinter einem Reverse-Proxy bereitgestellt wird",
@@ -5455,6 +5484,7 @@
"Re-running pre-check after repairs...": "Nach der Reparatur wird die Vorkontrolle erneut durchgeführt...",
"Reachable": "Erreichbar",
"Read an oci-compose from a file of this host": "Lesen Sie ein oci-compose aus einer Datei dieses Hosts",
"Read and edit PDF documents in your browser": "PDF-Dokumente im Browser lesen und bearbeiten",
"Read its Compose file from a file of this host": "Lesen Sie die Compose-Datei aus einer Datei dieses Hosts",
"Read manga through a self-hosted server and web UI.": "Manga über einen selbst gehosteten Server mit Weboberfläche lesen.",
"Read the link with pct console CTID on the Proxmox host, or from the Console panel of the container in the Proxmox web interface, then open the https://playit.gg/claim/ address it shows in a browser and sign in to playit.gg. Ctrl+a q leaves pct console.": "Lesen Sie den Link mit pct-Konsole CTID auf dem Proxmox-Host oder vom Konsolen-Panel des Containers in der Proxmox-Weboberfläche, öffnen Sie dann die https://playit.gg/claim/Adresse, die in einem Browser angezeigt wird, und melden Sie sich bei playit.gg an. Strg + a q verlässt pct Konsole.",
@@ -5560,6 +5590,7 @@
"Recursive and authoritative DNS server.": "Rekursiver und autoritativer DNS-Server.",
"Redmine": "Redmine",
"Refresh APT index and verify repositories:": "APT-Index aktualisieren und Repositorys überprüfen:",
"Refresh catalog": "Katalog aktualisieren",
"Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.": "Die konfigurierten APT-Repositories aktualisieren und die PBS-Paketaktualisierung prüfen? Repository-Dateien bleiben erhalten.",
"Refresh the index from the image sources": "Den Index aus den Image-Quellen aktualisieren",
"Refresh token of the connector, from the Twingate admin console": "Aktualisierungstoken des Connectors aus der Twingate-Verwaltungskonsole",
@@ -5567,6 +5598,7 @@
"Refresh your browser to see changes (server restart may be required)": "Aktualisieren Sie Ihren Browser, um Änderungen zu sehen (möglicherweise ist ein Neustart des Servers erforderlich).",
"Refreshing apt cache...": "Apt-Cache wird aktualisiert...",
"Refreshing the NVIDIA runtime...": "Erfrischung der NVIDIA Runtime...",
"Refreshing the application catalog...": "Anwendungskatalog wird aktualisiert...",
"Refusing an unexpected rootfs path:": "Ablehnung eines unerwarteten Rootfs-Pfades:",
"Regenerate the catalog templates": "Die Katalogvorlagen neu erstellen",
"Regenerate the template of one application": "Die Vorlage einer Anwendung neu erstellen",
@@ -6258,6 +6290,7 @@
"Self-hosted file sync and sharing.": "Selbst gehostete Dateisynchronisierung und -freigabe.",
"Self-hosted file toolkit for images, video, audio, PDFs, and files": "Selbst gehostetes Datei-Toolkit für Bilder, Video, Audio, PDFs und Dateien",
"Self-hosted forms and workflows.": "Selbst gehostete Formulare und Arbeitsabläufe.",
"Self-hosted grocery list and recipe manager": "Selbstgehostete Einkaufsliste und Rezeptmanager",
"Self-hosted household plant-care tracker with reminders, photos, and multiple user accounts.": "Selbst gehostete Pflegeverwaltung für Zimmerpflanzen mit Erinnerungen, Fotos und mehreren Benutzerkonten.",
"Self-hosted image-hosting service with authenticated uploads, image processing, public links, and local storage.": "Selbst gehosteter Bildhosting-Dienst mit authentifizierten Uploads, Bildverarbeitung, öffentlichen Links und lokalem Speicher.",
"Self-hosted internet archiving solution": "Selbst gehostete Internet-Archivierungslösung",
@@ -6452,6 +6485,7 @@
"Simple and easy to use DDNS": "Einfach und einfach zu bedienen DDNS",
"Simple self-hosted file sharing.": "Einfacher, selbst gehosteter Dateiaustausch.",
"Single GPU Warning": "Warnung vor einer einzelnen GPU",
"Single sign-on and multi-factor authentication": "Single Sign-On und Multi-Faktor-Authentifizierung",
"Single target found — selected automatically:": "Einzelnes Ziel gefunden – automatisch ausgewählt:",
"Single-node log storage and query UI.": "Logspeicher mit Abfrageoberfläche für einen einzelnen Knoten.",
"Single-node observability database for metrics, logs and traces.": "Einzelknoten-Datenbank für Metriken, Protokolle und Traces.",
@@ -6520,7 +6554,9 @@
"Specific subnet (enter manually)": "Spezifisches Subnetz (manuell eingeben)",
"Speedtest Tracker web interface": "Speedtest Tracker Web-Schnittstelle",
"Speedtest-tracker is a self-hosted internet performance tracking application that runs speedtest checks against Ookla's Speedtest service.": "Speedtest-Tracker ist eine selbst gehostete Internet-Performance-Tracking-Anwendung, die Speedtest-Checks gegen den Speedtest-Service von Ookla durchführt.",
"Spoolman web interface": "Spoolman-Weboberfläche",
"Spotube is an open source, cross-platform Spotify client compatible across multiple platforms utilizing Spotify's data API and YouTube, Piped.video or JioSaavn as an audio source, eliminating the need for Spotify Premium": "Spotube ist ein Open-Source-, plattformübergreifender Spotify-Client, der auf mehreren Plattformen mit Spotifys Daten-API und YouTube, Piped, kompatibel ist. Video oder JioSaavn als Audioquelle, wodurch Spotify Premium entfällt",
"Spreadsheets in your browser": "Tabellenkalkulation im Browser",
"Sshwifty": "Sshwifty",
"Sshwifty web access (password only)": "Sshwifty-Webzugriff (nur Passwort)",
"Stable (main branch)": "Stabil (Hauptzweig)",
@@ -7417,6 +7453,7 @@
"Then bind-mount to container": "Dann bind-mounten Sie es an den Container",
"Then change the VM display to none (vga: none) when the guest is stable.": "Ändern Sie dann die VM-Anzeige auf „Keine“ (vga: none), wenn der Gast stabil ist.",
"Then change the VM display to none (vga: none) when the system is stable.": "Ändern Sie dann die VM-Anzeige auf „Keine“ (vga: none), wenn das System stabil ist.",
"Then restart the container so the new model appears in the list.": "Starten Sie den Container anschließend neu, damit das neue Modell in der Liste erscheint.",
"Then run this option again:": "Führen Sie dann diese Option erneut aus:",
"Then update /etc/fstab on the host with the same options.": "Aktualisieren Sie dann /etc/fstab auf dem Host mit denselben Optionen.",
"There are extra disks or bind mounts outside the journal; the rootfs is not replaced": "Es gibt zusätzliche Festplatten oder Bindehalterungen außerhalb des Journals; die Rootfs werden nicht ersetzt",
@@ -7464,6 +7501,7 @@
"This container does not have apt-get. NFS client installation only supports Debian/Ubuntu containers.": "Dieser Container verfügt nicht über apt-get. Die NFS-Client-Installation unterstützt nur Debian/Ubuntu-Container.",
"This container does not have apt-get. Samba client installation only supports Debian/Ubuntu containers.": "Dieser Container verfügt nicht über apt-get. Die Samba-Client-Installation unterstützt nur Debian/Ubuntu-Container.",
"This container has no GPU configured. Coral TPU works best alongside hardware video decoding (Quick Sync, VA-API, NVENC) for apps like Frigate.": "Für diesen Container ist keine GPU konfiguriert. Coral TPU funktioniert am besten zusammen mit der Hardware-Videodekodierung (Quick Sync, VA-API, NVENC) für Apps wie Frigate.",
"This container is managed by high availability. Remove ct:{vmid} from HA (Datacenter → HA, or ha-manager remove ct:{vmid}), repeat the operation and add it back to HA with the same settings.": "Dieser Container wird von der Hochverfügbarkeit verwaltet. Entfernen Sie ct:{vmid} aus HA (Rechenzentrum → HA oder ha-manager remove ct:{vmid}), wiederholen Sie den Vorgang und fügen Sie ihn mit denselben Einstellungen wieder zu HA hinzu.",
"This container is not a member of a multi-container application": "Dieser Container ist kein Mitglied einer Multi-Container-Anwendung",
"This container is not a registered OCI instance.": "Dieser Container ist keine registrierte OCI-Instanz.",
"This container was restored or came back from another host after its record on this host was written. Open this menu again to recover it; nothing was changed.": "Dieser Container wurde wiederhergestellt oder kam von einem anderen Host zurück, nachdem sein Datensatz auf diesem Host geschrieben wurde. Öffnen Sie dieses Menü erneut, um ihn zu registrieren; es wurde nichts geändert.",
@@ -7582,6 +7620,7 @@
"Tip: You can install the QEMU Guest Agent inside the VM with:": "Tipp: Sie können den QEMU Guest Agent in der VM installieren mit:",
"Tip: zfs set acltype=posixacl xattr=sa <pool>/<dataset> enables full ACL support.": "Tipp: zfs set acltype=posixacl xattr=sa <pool>/<dataset> aktiviert die vollständige ACL-Unterstützung.",
"Tmpfs size in MiB for": "Tmpfs Größe in MiB für",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:": "Um ein Modell hinzuzufügen, öffnen Sie die Konsole des Containers in Proxmox und laden Sie es nach /models herunter, zum Beispiel:",
"To allow LXC write access, change the NFS export on the server to include:": "Um LXC-Schreibzugriff zu ermöglichen, ändern Sie den NFS-Export auf dem Server so, dass er Folgendes enthält:",
"To apply it to the current shell now, run:": "Um sie jetzt auf die aktuelle Shell anzuwenden, führen Sie Folgendes aus:",
"To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.": "Um VFs VMs oder LXCs zuzuweisen, bearbeiten Sie die Konfiguration manuell über die Proxmox-Weboberfläche. Die physische Funktion bleibt an den nativen Treiber gebunden.",
@@ -7621,6 +7660,7 @@
"Total routes": "Gesamtrouten",
"Total size:": "Gesamtgröße:",
"Toxiproxy": "Toxiproxy",
"Track 3D printer filament spools and usage.": "Verfolgen Sie die Filamentspulen und den Verbrauch von 3D-Druckern.",
"Track movies, television, anime and games you want to enjoy.": "Behalten Sie Filme, Serien, Anime und Spiele im Blick, die Sie ansehen oder spielen möchten.",
"Track subscriptions and recurring expenses.": "Abonnements und wiederkehrende Ausgaben verwalten.",
"Track your music listening history on your own server.": "Hörverlauf für Musik auf dem eigenen Server erfassen.",
@@ -7855,6 +7895,7 @@
"Update the whole stack?": "Aktualisieren Sie den gesamten Stack?",
"Update, modify or recreate one installed OCI instance": "Eine installierte OCI-Instanz aktualisieren, ändern oder neu erstellen",
"Updated": "Aktualisiert",
"Updated recipes since your last visit: {count}": "Aktualisierte Rezepte seit Ihrem letzten Besuch: {count}",
"Updated sharedfiles group to GID: 101000": "Sharedfiles-Gruppe auf GID aktualisiert: 101000",
"Updated stack checked": "Aktualisierter Stapel geprüft",
"Updated:": "Aktualisiert:",
@@ -8060,6 +8101,7 @@
"Variables": "Variablen",
"Variables the installation asks for:": "Variablen, die von der Anlage verlangt werden:",
"Vaultwarden Web Vault": "Vaultwarden Web Vault",
"Vector illustration in your browser": "Vektorillustrationen im Browser",
"Vector search engine with a built-in dashboard.": "Vektorsuchmaschine mit integriertem Dashboard.",
"Verbose pool status": "Ausführlicher Poolstatus",
"Verification": "Überprüfung",
@@ -8090,6 +8132,7 @@
"Versions shown belong to maintained NVIDIA branches that list your GPU PCI ID and are new enough to build against the running kernel. DKMS compilation is the final validation. The recommended version keeps the current branch, or uses the NVIDIA Production Branch on a fresh install.": "Die angezeigten Versionen gehören zu gepflegten NVIDIA-Zweigen, die Ihre GPU-PCI-ID auflisten und neu genug sind, um auf dem laufenden Kernel zu erstellen. Die DKMS-Kompilierung ist die endgültige Validierung. Die empfohlene Version behält den aktuellen Zweig bei oder verwendet den NVIDIA Production Branch bei einer Neuinstallation.",
"VictoriaLogs": "VictoriaLogs",
"Video acceleration and object detection are independent choices; the installer does not write camera or detector YAML.": "Videobeschleunigung und Objekterkennung sind unabhängige Entscheidungen; der Installer schreibt keine Kamera oder Detektor YAML.",
"Video editing in your browser": "Videoschnitt im Browser",
"Video transcoding acceleration": "Videotranscodierungsbeschleunigung",
"Video transcoding profile not implemented:": "Videotranskodierungsprofil nicht implementiert:",
"View CIFS Mounts (pvesm + fstab)": "CIFS-Mounts anzeigen (pvesm + fstab)",
@@ -8199,12 +8242,17 @@
"Web access": "Webzugang",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Webadresse des AdGuard Home, der die Einstellungen erhält (z. B. http://192.168.1.3)",
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Webadresse des AdGuard Home, dessen Einstellungen kopiert sind (z. B. http://192.168.1.2)",
"Web dashboard": "Web-Dashboard",
"Web dashboard and WebDAV": "Web-Dashboard und WebDAV",
"Web interface": "Weboberfläche",
"Web interface for Borg Backup repositories and jobs.": "Weboberfläche für Borg-Backup-Repositories und -Jobs.",
"Web interface for managing 3D printers.": "Weboberfläche zur Verwaltung von 3D-Druckern.",
"Web interface to manage devices running Tasmota firmware.": "Web-Schnittstelle zur Verwaltung von Geräten mit Tasmota-Firmware.",
"Web reverse proxy with an administration interface.": "Web-Reverse-Proxy mit Administrationsoberfläche.",
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord kann als ein Paket von Sicherheits- und Datenschutz-Härtungen, Discord-Features-Reimplementierungen, Electron / Chromium / Discord-Bugs-Workarounds, Stylesheets, interne Seiten und verpackte https://discord.com-Seite zusammengefasst werden, die so weit wie möglich mit ToS konform sind (oder die Änderungen, die es verletzen könnten, vor Discords Augen verbergen).",
"WebDAV": "WebDAV",
"WebDAV and dashboard password (leave empty to generate)": "Passwort für WebDAV und Dashboard (leer = generiert)",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV ist auf Port 8080 des Containers verfügbar. Vor Dateioperationen in der Cloud muss das Konto verknüpft werden.",
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus ist ein multi-site inkrementeller xmltv epg grabber. Es sammelt tv-programm-guide-daten von ausgewählten tvguide-seiten für ihre lieblingskanäle.",
"Webservers & Proxies": "Webserver und Proxys",
"Website": "Webseite",
@@ -8262,6 +8310,7 @@
"Without a usable reset path, passthrough reliability is poor and VM": "Ohne einen nutzbaren Reset-Pfad ist die Passthrough-Zuverlässigkeit schlecht und VM",
"Wizard cancelled": "Assistent abgebrochen",
"Wolfenstein: Blade of Agony is a story-driven WWII shooter inspired by Wolfenstein and Doom.": "Wolfenstein: Blade of Agony ist ein Story-basierter WWII-Shooter, inspiriert von Wolfenstein und Doom.",
"Word processing in your browser": "Textverarbeitung im Browser",
"Workflow automation tool": "Workflow Automation Tool",
"Working directory:": "Arbeitsverzeichnis:",
"Works with LVM, ZFS, and BTRFS storage types": "Funktioniert mit LVM-, ZFS- und BTRFS-Speichertypen",
@@ -8312,6 +8361,8 @@
"Your machine learning Env work with Jupyter Lab": "Ihre Machine Learning Env arbeitet mit Jupyter Lab",
"Your next YouTube media manager": "Dein nächster YouTube Media Manager",
"Your_spotify is a self-hosted application that tracks what you listen and offers you a dashboard to explore statistics about it! It's composed of a web server which polls the Spotify API every now and then and a web application on which you can explore your statistics.": "Your_spotify ist eine selbst gehostete Anwendung, die verfolgt, was Sie hören und bietet Ihnen ein Dashboard, um Statistiken darüber zu erkunden! Es besteht aus einem Webserver, der hin und wieder die Spotify-API abfragt, und einer Webanwendung, auf der Sie Ihre Statistiken erkunden können.",
"Z-Wave JS UI": "Z-Wave JS UI",
"Z-Wave JS UI admin login": "Z-Wave JS UI Admin-Login",
"ZFS ARC config removed (kernel defaults will apply on reboot)": "ZFS ARC-Konfiguration entfernt (Kernel-Standardeinstellungen gelten beim Neustart)",
"ZFS ARC maximum configured:": "ZFS ARC maximal konfiguriert:",
"ZFS ARC optimization completed": "ZFS ARC-Optimierung abgeschlossen",
@@ -8425,6 +8476,7 @@
"could not be compiled for kernel": "konnte nicht für den Kernel kompiliert werden",
"could not validate NVIDIA; exit code": "konnte NVIDIA nicht validieren; Exit-Code",
"cpuunits must be between 8 and 10000": "cpuunits müssen zwischen 8 und 10000 sein",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf": "curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"custom": "Custom",
"custom dependency commands are not yet supported": "Custom Dependency Commands werden noch nicht unterstützt",
"custom path(s) saved.": "Benutzerdefinierte(r) Pfad(e) gespeichert.",
@@ -8631,6 +8683,7 @@
"kexec-tools is not installed or already removed.": "kexec-tools ist nicht installiert oder bereits entfernt.",
"layers": "Schichten",
"legacy .link file(s) to the ProxMenux-managed format": "ältere .link-Dateien in das von ProxMenux verwaltete Format",
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.": "llama.cpp zeigt in seiner Weboberfläche alle in /models gespeicherten GGUF-Modelle an und lädt das ausgewählte.",
"log2ram completely removed from system": "log2ram vollständig aus dem System entfernt",
"main container of the application": "Hauptcontainer der Anwendung",
"make cloned mount tree read-only": "geklonten Mount-Baum schreibgeschützt machen",
+53
View File
@@ -183,6 +183,7 @@
"A tunneling daemon by Cloudflare that safely exposes your web servers into the internet.": "Un daemon de túneles de Cloudflare que expone tus servidores web a Internet de forma segura.",
"A unified email and collaboration server.": "Un servidor unificado de correo electrónico y colaboración.",
"A unified platform for logs, metrics and traces.": "Una plataforma unificada para registros, métricas y trazas.",
"A validating, recursive DNS resolver for your private network.": "un solucionador de DNS recursivo y de validación para su red privada.",
"A versatile file conversion tool that supports multiple formats.": "Una herramienta versátil de conversión de archivos compatible con múltiples formatos.",
"A visual tool for exploring and documenting database schemas.": "Una herramienta visual para explorar y documentar esquemas de bases de datos.",
"A web GUI client of Project V which supports VMess, VLESS, SS, SSR, Trojan, Tuic and Juicity protocols": "Un cliente web de Project V compatible con los protocolos VMess, VLESS, SS, SSR, Trojan, Tuic y Juicity",
@@ -255,6 +256,7 @@
"Acceleration for llama.cpp": "Aceleración para llama.cpp",
"Accept routes from other nodes?": "¿Aceptar rutas de otros nodos?",
"Accept this host monitoring profile?": "¿Aceptar este perfil de monitorización del host?",
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Accede a la nube de Movistar y O2 desde clientes WebDAV y herramientas de backup.",
"Access Scope:": "Ámbito de acceso:",
"Access bridge": "Puente de acceso",
"Access bridge for Immich": "Puente de acceso para Immich",
@@ -408,6 +410,7 @@
"After the reboot, you will only be able to access the Proxmox host via:": "Después del reinicio, solo podrá acceder al host Proxmox a través de:",
"After this LXC → VM switch, reboot the host so the new binding state is applied cleanly.": "Después de este cambio LXC → VM, reinicia el host para que el nuevo estado de enlace se aplique limpiamente.",
"Agentless monitoring and observability platform.": "Plataforma de monitorización y observabilidad sin agentes.",
"AirDC++ administrator": "Administrador de AirDC++",
"Airsonic Advanced web interface": "Interfaz web de Airsonic Advanced",
"Airsonic-advanced is a free, web-based media streamer, providing ubiquitious access to your music. Use it to share your music with friends, or to listen to your own music while at work. You can stream to multiple players simultaneously, for instance to one player in your kitchen and another in your living room.": "Airsonic-advanced es un servidor de streaming multimedia gratuito y basado en web que da acceso a tu música desde cualquier lugar. Úsalo para compartir tu música con amigos o para escuchar la tuya en el trabajo. Puede transmitir a varios reproductores a la vez, por ejemplo a uno en la cocina y a otro en el salón.",
"Aliases added to .bashrc": "Alias añadidos a .bashrc",
@@ -595,12 +598,16 @@
"Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Atención: Eliminar el banner de suscripción puede causar problemas en la interfaz web después de una actualización futura.",
"Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity es un editor y grabador de audio multipista fácil de usar, desarrollado como código abierto por un grupo de voluntarios.",
"Audio device directory": "Directorio de dispositivos de audio",
"Audio recording and mixing in your browser": "Grabación y mezcla de audio en el navegador",
"Audio/Video": "Audio/vídeo",
"Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf es un servidor autoalojado de audiolibros y podcasts.",
"Audit completed. Press Enter to continue...": "Auditoría completada. Pulsa Intro para continuar...",
"Audit socket disabled or not required": "Socket de auditoría deshabilitado o no requerido",
"Auth key is required.": "Se requiere clave de autenticación.",
"Auth:": "Autenticación:",
"Authelia Web UI": "Authelia Interfaz de usuario web",
"Authelia administrator": "administrador Authelia",
"Authelia session cookie domain for this portal (for example example.com)": "dominio de cookie de sesión Authelia para este portal (por ejemplo, ejemplo.com)",
"Authentication": "Autenticación",
"Authentication & Security": "Authentication & Security",
"Authentication Error": "Error de autenticación",
@@ -640,6 +647,7 @@
"Available PVE Version": "Versión PVE disponible",
"Available Shares:": "Recursos compartidos disponibles:",
"Available action": "Acción disponible",
"Available applications: {count}": "Aplicaciones disponibles: {count}",
"Available archives:": "Archivos disponibles:",
"Available disks detected.": "Discos disponibles detectados.",
"Available host backups:": "Backups de host disponibles:",
@@ -872,6 +880,7 @@
"Cannot write the image archive to {storage}. Check storage access and mount status.": "No se puede escribir el archivo de la imagen en {storage}. Comprueba el acceso al almacenamiento y que esté montado.",
"Capabilities cannot be kept and all dropped at the same time": "No se pueden mantener las capacidades y todas se disminuyen al mismo tiempo",
"Catalog options": "Opciones del catálogo",
"Catalog refresh unavailable; using the local catalog.": "No se pudo actualizar el catálogo; se está usando la copia local.",
"Category": "Categoría",
"Caution: Maximum mode generates more heat.": "Precaución: el modo máximo genera más calor.",
"Central server for file and image backups.": "Servidor central para copias de seguridad de archivos e imágenes.",
@@ -1159,6 +1168,7 @@
"Compressing": "Comprimiendo",
"Compression": "Compresión",
"Compression Tools": "Herramientas de compresión",
"Computer-aided design and drafting in your browser": "Diseño CAD y dibujo técnico en el navegador",
"Concise output of logical volumes": "Salida concisa de volúmenes lógicos",
"Concise output of physical volumes": "Salida concisa de volúmenes físicos",
"Concise output of volume groups": "Salida concisa de grupos de volúmenes",
@@ -1391,6 +1401,7 @@
"Controller + NVMe": "Controlador + NVMe",
"Controller + NVMe assignment will be written now and become active after host reboot.": "La asignación de controlador + NVMe se escribirá ahora y se activará después de reiniciar el host.",
"Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.": "El passthrough de controlador + NVMe requiere el tipo de máquina q35. Se omite la asignación del controlador.",
"Controller path on the Proxmox host; prefer /dev/serial/by-id/...": "Ruta del controlador en el host Proxmox;prefiero /dev/serial/by-id/...",
"Controller/NVMe Conflict Policy": "Política de conflictos entre controlador y NVMe",
"Controller/NVMe already present in VM config": "Controlador/NVMe ya presente en la configuración de VM",
"Controller/NVMe already present in VM config (%s)": "El controlador/NVMe ya está en la configuración de la VM (%s)",
@@ -1925,6 +1936,7 @@
"Dgraph": "Dgraph",
"Diff: current system vs backup (--- system +++ backup)": "Diferencias: sistema actual frente al backup (--- sistema +++ backup)",
"Different host. Backup from:": "Host diferente. Backup procedente de:",
"Direct Connect file sharing with a web interface": "Intercambio de archivos Direct Connect con interfaz web",
"Direct conversion completed for container": "Conversión directa completada para el contenedor",
"Directory Exists": "El directorio existe",
"Directory Not Empty": "Directorio no vacío",
@@ -3336,6 +3348,7 @@
"Initial Stirling-PDF account": "Cuenta inicial de Stirling-PDF",
"Initial Tandoor administrator": "Administrador inicial de Tandoor",
"Initial Umami administrator": "Administrador inicial de Umami",
"Initial Z-Wave JS UI admin password": "Contraseña de administrador inicial Z-Wave JS UI",
"Initial administrator created:": "Administrador inicial creado:",
"Initial administrator user": "Usuario administrador inicial",
"Initializing Borg repository if needed...": "Inicializando el repositorio de Borg si es necesario...",
@@ -3521,6 +3534,7 @@
"Interface MTU": "MTU de interfaz",
"Interface Names (persistent)": "Nombres de interfaces persistentes",
"Interface Type": "Tipo de interfaz",
"Interface design and prototyping in your browser": "Diseño de interfaces y prototipos en el navegador",
"Interface names will return to default systemd behavior.": "Los nombres de las interfaces volverán al comportamiento predeterminado de systemd.",
"Interface type:": "Tipo de interfaz:",
"Interfaces configured": "Interfaces configuradas",
@@ -3736,6 +3750,7 @@
"Jupyter Lab (token only)": "Jupyter Lab (solo token)",
"JupyterLab": "JupyterLab",
"JupyterLab access token": "Token de acceso de JupyterLab",
"KDE's twin-panel file manager in a browser-based desktop.": "administrador de archivos de panel doble de KDE en un escritorio basado en navegador.",
"KDF:": "KDF:",
"KROMA": "KROMA",
"KVM MSR options added to /etc/modprobe.d/kvm.conf": "Opciones de KVM MSR añadidas a /etc/modprobe.d/kvm.conf",
@@ -3783,12 +3798,14 @@
"KiCad - A Cross Platform and Open Source Electronics Design Automation Suite.": "KiCad - Una suite de automatización de diseño electrónico multiplataforma y de código abierto.",
"Kimai has no default account. Enter the container with: pct enter {main_vmid}": "Kimai no tiene una cuenta predeterminada. Entra en el contenedor con: pct enter {main_vmid}",
"Kimai is a professional grade time-tracking application, free and open-source.": "Kimai es una aplicación profesional de control de tiempo, gratuita y de código abierto.",
"KitchenOwl": "KitchenOwl",
"Kometa is a powerful tool designed to give you complete control over your media libraries. With Kometa, you can take your customization to the next level, with granular control over metadata, collections, overlays, and much more.": "Kometa es una potente herramienta que te da control total sobre tus bibliotecas multimedia. Con Kometa llevas la personalización al siguiente nivel, con control detallado de metadatos, colecciones, overlays y mucho más.",
"Kometa reads its configuration from /config/config.yml and the container only ships /config/config.yml.template. Copy the template to config.yml, fill in the required Plex and TMDb connections, then restart the container.": "Kometa lee su configuración de /config/config.yml y el contenedor solo incluye /config/config.yml.template. Copia la plantilla a config.yml, rellena las conexiones obligatorias de Plex y TMDb y reinicia el contenedor.",
"Komga is a media server for your comics, mangas, BDs, magazines and eBooks.": "Komga es un servidor multimedia para tus cómics, mangas, BDs, revistas y eBooks.",
"Kopia Web UI": "Interfaz web de Kopia",
"Kopia Web UI login": "Acceso a la interfaz web de Kopia",
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita es un programa de pintura profesional, GRATUITO y de código abierto. Lo hacen artistas que quieren herramientas de arte asequibles para todos.",
"Krusader Web UI": "Krusader Interfaz de usuario web",
"LAN access to the kept containers (stack configuration incomplete):": "Acceso LAN a los contenedores conservados (configuración de la pila incompleta):",
"LAN address applied to the application URLs": "Dirección LAN aplicada a las URL de la aplicación",
"LLDAP": "LLDAP",
@@ -4015,6 +4032,7 @@
"Manage OCI stack": "Administrar la pila de OCI",
"Manage PBS encryption keyfile": "Administrar el archivo de claves de cifrado PBS",
"Manage Secure Gateway": "Administrar Secure Gateway",
"Manage a Z-Wave network from a web dashboard and WebSocket gateway.": "administre una red Z-Wave desde un panel web y una puerta de enlace WebSocket.",
"Manage and inspect VM disk images": "Administrar e inspeccionar imágenes de disco de VM",
"Manage custom backup paths": "Configurar rutas de backup personalizadas",
"Manage custom paths (add / remove your folders)": "Configurar rutas personalizadas (añadir/eliminar carpetas)",
@@ -4024,6 +4042,7 @@
"Manage local backup target": "Configurar el destino del backup local",
"Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Gestiona los registros de imágenes privadas.\nCon las credenciales guardadas, ProxMenux puede acceder a tus imágenes privadas.",
"Manage registry accounts as root on the Proxmox node.": "Gestiona las cuentas de registro como root en el nodo Proxmox.",
"Manage teams of AI agents from a web dashboard.": "Gestiona equipos de agentes de IA desde un panel web.",
"Managed disks must have backup enabled and a valid size": "Los discos gestionados deben tener habilitado backup y un tamaño válido",
"Managed public route include is missing": "Falta el archivo de configuración de las rutas públicas gestionadas",
"Managed public route installation failed": "No se han podido configurar las rutas públicas gestionadas",
@@ -4129,6 +4148,7 @@
"Monitoring": "Monitorización",
"Monitoring & Analytics": "Monitoring & Analytics",
"Most common cause: the archive is corrupted (interrupted write, partial copy, or storage issue).": "Causa más común: el archivo está dañado (escritura interrumpida, copia parcial o problema de almacenamiento).",
"Motion graphics and compositing in your browser": "Animación gráfica y composición en el navegador",
"Mount Added Successfully:": "Montaje añadido correctamente:",
"Mount CIFS share:": "Monta el recurso compartido CIFS:",
"Mount Configuration Summary:": "Resumen de configuración de montaje:",
@@ -4429,6 +4449,7 @@
"New Search": "Nueva búsqueda",
"New VM:": "Nueva máquina virtual:",
"New Virtual Machine": "Nueva máquina virtual",
"New applications since your last visit: {count}": "Aplicaciones nuevas desde tu última visita: {count}",
"New backup job": "Nuevo trabajo de backup",
"New backups on this host will be unencrypted until a new keyfile is set up.": "Los nuevos backups de este host no se cifrarán hasta que se configure un nuevo archivo de claves.",
"New image compatible:": "Nueva imagen compatible:",
@@ -4887,6 +4908,8 @@
"Open the page of an application in the menu": "Abrir la página de una aplicación en el menú",
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Abre la dirección web y crea la primera cuenta: el daemon se registra solo y empieza el primer escaneo.",
"Open the web address and create the password of the akadmin user in the first-run setup.": "abra la dirección web y cree la contraseña del usuario akaadmin en la configuración de primera ejecución.",
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured.": "abra la dirección web y siga la incorporación de KitchenOwl para crear la primera cuenta;no hay ninguna cuenta predeterminada configurada.",
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Abre el panel web y vincula tu cuenta de Movistar/O2 con su verificación por SMS.",
"Open-source AI-powered coding assistant": "Asistente de programación con IA de código abierto",
"Open-source UI for building and debugging multi-agent and RAG applications": "Interfaz de código abierto para crear y depurar aplicaciones multiagente y RAG",
"Open-source in-memory data store.": "Almacén de datos en memoria de código abierto.",
@@ -5009,6 +5032,7 @@
"Packages:": "Paquetes:",
"Packaging OVA file...": "Embalaje archivo OVA...",
"Packing installer archive...": "Empaquetando el archivo del instalador...",
"Page layout and publishing in your browser": "Maquetación y publicación en el navegador",
"PairDrop is a sublime alternative to AirDrop that works on all platforms. Send images, documents or text via peer to peer connection to devices in the same local network/Wi-Fi or to paired devices.": "PairDrop es una magnífica alternativa a AirDrop que funciona en todas las plataformas. Envía imágenes, documentos o texto mediante una conexión entre pares a dispositivos de la misma red local/Wi-Fi o a dispositivos emparejados.",
"Paperless configuration cancelled": "Configuración de Paperless cancelada",
"Paperless-ngx WebUI": "Paperless-ngx WebUI",
@@ -5027,6 +5051,7 @@
"Pass /dev/video12 to the LXC": "Pasar /dev/video12 al LXC",
"Pass a host device to the LXC": "Pasar un dispositivo del host al LXC",
"Pass the UPS to the LXC": "Pase el UPS al LXC",
"Pass through a Z-Wave USB or serial controller": "pasar a través de un controlador serie o USB Z-Wave",
"Passing NVIDIA does not enable acceleration inside the application. The host needs NVIDIA Container Toolkit and a compatible image. Continue?": "Pasar NVIDIA no habilita la aceleración dentro de la aplicación. El host necesita NVIDIA Container Toolkit y una imagen compatible. ¿Continuar?",
"Passkey-based identity provider for self-hosted apps.": "Proveedor de identidad basado en passkeys para aplicaciones autoalojadas.",
"Passphrase used to unlock the imported keyfile (leave blank if the keyfile is unencrypted / kdf=none):": "Frase de contraseña utilizada para desbloquear el archivo de claves importado (déjalo en blanco si el archivo de claves no está cifrado/kdf=none):",
@@ -5134,6 +5159,8 @@
"Personal finance management application": "Aplicación de gestión de finanzas personales",
"Personal media server for browsing and playing a local video library, with direct play and optional modules.": "Servidor multimedia personal para explorar y reproducir una biblioteca local de vídeos, con reproducción directa y módulos opcionales.",
"Photo and video library with optional GPU transcoding and machine learning": "Biblioteca de fotos y vídeos con transcodificación por GPU y aprendizaje automático opcionales",
"Photo editing in your browser": "Edición de fotos en el navegador",
"Photo library and RAW development in your browser": "Biblioteca de fotos y revelado RAW en el navegador",
"PhotoPrism": "PhotoPrism",
"Photofield": "Photofield",
"Phpmyadmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB.": "Phpmyadmin es una herramienta de software libre escrita en PHP para administrar MySQL por la web. phpMyAdmin admite una amplia gama de operaciones en MySQL y MariaDB.",
@@ -5225,6 +5252,7 @@
"Preparing the changes...": "Preparando los cambios...",
"Preparing the machine learning container for the new choice...": "Preparando el contenedor Machine learning para la nueva opción...",
"Preparing the update...": "Preparando la actualización...",
"Presentations and slide decks in your browser": "Presentaciones y diapositivas en el navegador",
"Preserving logs to /var/log.hdd before unmounting...": "Preservando logs en /var/log.hdd antes de desmontar...",
"Press 'q' to exit": "Pulsa 'q' para salir",
"Press Ctrl+C to stop the server and return to menu.": "Pulsa Ctrl+C para detener el servidor y volver al menú.",
@@ -5385,6 +5413,7 @@
"Proxmox web interface: Datacenter > Storage > Add > ZFS": "Interfaz web de Proxmox: Datacenter > Storage > Add > ZFS",
"Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Interfaz web de Proxmox: Datacenter > Storage > Add > iSCSI",
"Proxy address to reach the API (optional)": "Dirección del proxy para llegar a la API (opcional)",
"Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)": "URL HTTPS pública utilizada para abrir este portal Authelia (por ejemplo, https://auth.example.com)",
"Public UDP port clients connect to": "Puerto UDP público al que se conectan los clientes",
"Public UDP port peers connect to": "Puerto UDP público al que se conectan los peers",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "URL pública de phpMyAdmin cuando se sirve detrás de un proxy inverso",
@@ -5445,6 +5474,7 @@
"Re-running pre-check after repairs...": "Volviendo a ejecutar la verificación previa después de las reparaciones...",
"Reachable": "Accesible",
"Read an oci-compose from a file of this host": "Leer un oci-compose desde un archivo de este host",
"Read and edit PDF documents in your browser": "Lectura y edición de documentos PDF en el navegador",
"Read its Compose file from a file of this host": "Leer su archivo Compose desde un archivo de este host",
"Read manga through a self-hosted server and web UI.": "Lee manga desde un servidor autoalojado con interfaz web.",
"Read the link with pct console CTID on the Proxmox host, or from the Console panel of the container in the Proxmox web interface, then open the https://playit.gg/claim/ address it shows in a browser and sign in to playit.gg. Ctrl+a q leaves pct console.": "Lee el enlace con pct console CTID en el host Proxmox, o desde el panel Console del contenedor en la interfaz web de Proxmox; después abre en un navegador la dirección https://playit.gg/claim/ que muestra e inicia sesión en playit.gg. Ctrl+a q sale de pct console.",
@@ -5543,6 +5573,7 @@
"Recursive and authoritative DNS server.": "Servidor DNS recursivo y autoritativo.",
"Redmine": "Redmine",
"Refresh APT index and verify repositories:": "Actualizar el índice APT y verificar los repositorios:",
"Refresh catalog": "Actualizar catálogo",
"Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.": "¿Actualizar los índices de los repositorios de APT configurados y revisar la actualización de paquetes de PBS? Se conservarán los archivos de los repositorios.",
"Refresh the index from the image sources": "Actualizar el índice desde las fuentes de imágenes",
"Refresh token of the connector, from the Twingate admin console": "Token de renovación del conector, de la consola de administración de Twingate",
@@ -5550,6 +5581,7 @@
"Refresh your browser to see changes (server restart may be required)": "Actualiza tu navegador para ver los cambios (es posible que sea necesario reiniciar el servidor)",
"Refreshing apt cache...": "Actualizando caché de apt...",
"Refreshing the NVIDIA runtime...": "Refrescando el tiempo de ejecución de NVIDIA...",
"Refreshing the application catalog...": "Actualizando el catálogo de aplicaciones...",
"Refusing an unexpected rootfs path:": "Refusing an inesperado rootfs path:",
"Regenerate the catalog templates": "Regenerar las plantillas del catálogo",
"Regenerate the template of one application": "Regenerar la plantilla de una aplicación",
@@ -6241,6 +6273,7 @@
"Self-hosted file sync and sharing.": "Sincronización y uso compartido de archivos autoalojados.",
"Self-hosted file toolkit for images, video, audio, PDFs, and files": "Kit de herramientas autoalojado para imágenes, vídeo, audio, PDF y archivos",
"Self-hosted forms and workflows.": "Formularios y flujos de trabajo autoalojados.",
"Self-hosted grocery list and recipe manager": "lista de compras y administrador de recetas autohospedado",
"Self-hosted household plant-care tracker with reminders, photos, and multiple user accounts.": "Gestor autoalojado del cuidado de plantas domésticas, con recordatorios, fotos y varias cuentas de usuario.",
"Self-hosted image-hosting service with authenticated uploads, image processing, public links, and local storage.": "Servicio autoalojado para alojar imágenes, con subidas autenticadas, procesamiento de imágenes, enlaces públicos y almacenamiento local.",
"Self-hosted internet archiving solution": "Solución autoalojada de archivado de Internet",
@@ -6435,6 +6468,7 @@
"Simple and easy to use DDNS": "DDNS simple y fácil de usar",
"Simple self-hosted file sharing.": "Servicio sencillo y autoalojado para compartir archivos.",
"Single GPU Warning": "Advertencia de GPU única",
"Single sign-on and multi-factor authentication": "inicio de sesión único y autenticación multifactor",
"Single target found — selected automatically:": "Destino único encontrado: seleccionado automáticamente:",
"Single-node log storage and query UI.": "Almacenamiento de logs para un solo nodo con interfaz de consulta.",
"Single-node observability database for metrics, logs and traces.": "Base de datos de observabilidad de un solo nodo para métricas, registros y trazas.",
@@ -6504,7 +6538,9 @@
"Specific subnet (enter manually)": "Subred específica (introducir manualmente)",
"Speedtest Tracker web interface": "Interfaz web de Speedtest Tracker",
"Speedtest-tracker is a self-hosted internet performance tracking application that runs speedtest checks against Ookla's Speedtest service.": "Speedtest-tracker es una aplicación autoalojada de seguimiento del rendimiento de Internet que ejecuta pruebas de velocidad contra el servicio Speedtest de Ookla.",
"Spoolman web interface": "interfaz web Spoolman",
"Spotube is an open source, cross-platform Spotify client compatible across multiple platforms utilizing Spotify's data API and YouTube, Piped.video or JioSaavn as an audio source, eliminating the need for Spotify Premium": "Spotube es un cliente de Spotify de código abierto y multiplataforma que usa la API de datos de Spotify y YouTube, Piped.video o JioSaavn como fuente de audio, sin necesidad de Spotify Premium",
"Spreadsheets in your browser": "Hojas de cálculo en el navegador",
"Sshwifty": "Sshwifty",
"Sshwifty web access (password only)": "Acceso web a Sshwifty (solo con contraseña)",
"Stable (main branch)": "Estable (rama main)",
@@ -7392,6 +7428,7 @@
"Then bind-mount to container": "Luego vincule el montaje al contenedor",
"Then change the VM display to none (vga: none) when the guest is stable.": "Después cambia la pantalla de la VM a none (vga: none) cuando el sistema de la VM sea estable.",
"Then change the VM display to none (vga: none) when the system is stable.": "Luego cambia la visualización de VM a ninguno (vga: ninguno) cuando el sistema esté estable.",
"Then restart the container so the new model appears in the list.": "Después reinicia el contenedor para que el modelo nuevo aparezca en la lista.",
"Then run this option again:": "Luego ejecuta esta opción nuevamente:",
"Then update /etc/fstab on the host with the same options.": "Luego actualiza /etc/fstab en el host con las mismas opciones.",
"There are extra disks or bind mounts outside the journal; the rootfs is not replaced": "Hay discos o bind mounts adicionales fuera del diario de la operación; el rootfs no se reemplaza",
@@ -7438,6 +7475,7 @@
"This container does not have apt-get. NFS client installation only supports Debian/Ubuntu containers.": "Este contenedor no tiene apt-get. La instalación del cliente NFS solo admite contenedores Debian/Ubuntu.",
"This container does not have apt-get. Samba client installation only supports Debian/Ubuntu containers.": "Este contenedor no tiene apt-get. La instalación del cliente Samba solo admite contenedores Debian/Ubuntu.",
"This container has no GPU configured. Coral TPU works best alongside hardware video decoding (Quick Sync, VA-API, NVENC) for apps like Frigate.": "Este contenedor no tiene GPU configurada. Coral TPU funciona mejor junto con la decodificación de video por hardware (Quick Sync, VA-API, NVENC) para aplicaciones como Frigate.",
"This container is managed by high availability. Remove ct:{vmid} from HA (Datacenter → HA, or ha-manager remove ct:{vmid}), repeat the operation and add it back to HA with the same settings.": "Este contenedor está gestionado por alta disponibilidad. Elimina ct:{vmid} de HA (Centro de datos → HA, o ha-manager remove ct:{vmid}), repite la operación y vuelve a añadirlo a HA con la misma configuración.",
"This container is not a member of a multi-container application": "Este contenedor no forma parte de una aplicación de varios contenedores",
"This container is not a registered OCI instance.": "Este contenedor no es una instancia OCI registrada.",
"This container was restored or came back from another host after its record on this host was written. Open this menu again to recover it; nothing was changed.": "Este contenedor se restauró o volvió de otro host después de que se escribiera su registro en este host. Abre de nuevo este menú para recuperarlo; no se ha cambiado nada.",
@@ -7555,6 +7593,7 @@
"Tip: You can install the QEMU Guest Agent inside the VM with:": "Consejo: Puede instalar el Agente Invitado QEMU dentro de la VM con:",
"Tip: zfs set acltype=posixacl xattr=sa <pool>/<dataset> enables full ACL support.": "Consejo: zfs set acltype=posixacl xattr=sa <pool>/<dataset> habilita la compatibilidad total con ACL.",
"Tmpfs size in MiB for": "Tamaño de tmpfs en MiB para",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:": "Para añadir un modelo, abre la consola del contenedor en Proxmox y descárgalo en /models, por ejemplo:",
"To allow LXC write access, change the NFS export on the server to include:": "Para permitir el acceso de escritura a LXC, cambia la exportación NFS en el servidor para incluir:",
"To apply it to the current shell now, run:": "Para aplicarlo ahora en la sesión actual, ejecuta:",
"To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.": "Para asignar VF a VM o LXC, edita la configuración manualmente a través de la interfaz web de Proxmox. La Función Física permanecerá ligada al controlador nativo.",
@@ -7594,6 +7633,7 @@
"Total routes": "Rutas totales",
"Total size:": "Tamaño total:",
"Toxiproxy": "Toxiproxy",
"Track 3D printer filament spools and usage.": "realice un seguimiento de los carretes de filamentos de las impresoras 3D y su uso.",
"Track movies, television, anime and games you want to enjoy.": "Lleva un registro de películas, series, anime y videojuegos que quieras disfrutar.",
"Track subscriptions and recurring expenses.": "Seguimiento de suscripciones y gastos recurrentes.",
"Track your music listening history on your own server.": "Registra tu historial de reproducción musical en tu propio servidor.",
@@ -7826,6 +7866,7 @@
"Update the whole stack?": "¿Actualizar toda la pila?",
"Update, modify or recreate one installed OCI instance": "Actualizar, modificar o recrear una instancia OCI instalada",
"Updated": "Actualizado",
"Updated recipes since your last visit: {count}": "Recetas actualizadas desde tu última visita: {count}",
"Updated sharedfiles group to GID: 101000": "Grupo de archivos compartidos actualizado a GID: 101000",
"Updated stack checked": "Pila actualizada comprobada",
"Updated:": "Actualizado:",
@@ -8031,6 +8072,7 @@
"Variables": "Variables",
"Variables the installation asks for:": "Variables que pide la instalación:",
"Vaultwarden Web Vault": "Vaultwarden Web Vault",
"Vector illustration in your browser": "Ilustración vectorial en el navegador",
"Vector search engine with a built-in dashboard.": "Motor de búsqueda vectorial con panel integrado.",
"Vendor Specific": "Específico del proveedor",
"Verbose pool status": "Estado detallado del grupo",
@@ -8063,6 +8105,7 @@
"VictoriaLogs": "VictoriaLogs",
"Video": "Vídeo",
"Video acceleration and object detection are independent choices; the installer does not write camera or detector YAML.": "La aceleración de vídeo y la detección de objetos se eligen por separado; el instalador no escribe el YAML de cámaras ni de detectores.",
"Video editing in your browser": "Edición de vídeo en el navegador",
"Video transcoding acceleration": "Aceleración de transcodificación de vídeo",
"Video transcoding profile not implemented:": "Perfil de transcodificación de vídeo no implementado:",
"View CIFS Mounts (pvesm + fstab)": "Ver montajes CIFS (pvesm + fstab)",
@@ -8172,12 +8215,17 @@
"Web access": "Acceso web",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Dirección web del AdGuard Home que recibe los ajustes (por ejemplo, http://192.168.1.3)",
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Dirección web del AdGuard Home principal, cuyos ajustes se copian (por ejemplo, http://192.168.1.2)",
"Web dashboard": "Panel web",
"Web dashboard and WebDAV": "Panel web y WebDAV",
"Web interface": "interfaz web",
"Web interface for Borg Backup repositories and jobs.": "Interfaz web para gestionar repositorios y tareas de Borg Backup.",
"Web interface for managing 3D printers.": "Interfaz web para gestionar impresoras 3D.",
"Web interface to manage devices running Tasmota firmware.": "Interfaz web para gestionar dispositivos con firmware Tasmota.",
"Web reverse proxy with an administration interface.": "Proxy inverso web con interfaz de administración.",
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord puede resumirse como un conjunto de medidas de hardening de seguridad y privacidad, reimplementaciones de funciones de Discord, soluciones a fallos de Electron / Chromium / Discord, hojas de estilo, páginas internas y la página https://discord.com encapsulada, diseñado para cumplir los ToS en lo posible (u ocultar a Discord los cambios que podrían incumplirlos).",
"WebDAV": "WebDAV",
"WebDAV and dashboard password (leave empty to generate)": "Contraseña de WebDAV y del panel (vacío = generada)",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV está disponible en el puerto 8080 del contenedor. Hay que vincular la cuenta antes de trabajar con los archivos de la nube.",
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus es un capturador incremental de EPG xmltv para múltiples sitios. Recoge los datos de la guía de programación de los sitios de guías de TV seleccionados para tus canales favoritos.",
"Webservers & Proxies": "Webservers & Proxies",
"Website": "Sitio web",
@@ -8234,6 +8282,7 @@
"Without a usable reset path, passthrough reliability is poor and VM": "Sin una ruta de reset utilizable, la fiabilidad del passthrough es baja y la VM",
"Wizard cancelled": "Asistente cancelado",
"Wolfenstein: Blade of Agony is a story-driven WWII shooter inspired by Wolfenstein and Doom.": "Wolfenstein: Blade of Agony es un shooter de la Segunda Guerra Mundial con historia, inspirado en Wolfenstein y Doom.",
"Word processing in your browser": "Procesador de textos en el navegador",
"Workflow automation tool": "Herramienta de automatización de flujos de trabajo",
"Working directory:": "Directorio de trabajo:",
"Works with LVM, ZFS, and BTRFS storage types": "Funciona con tipos de almacenamiento LVM, ZFS y BTRFS",
@@ -8284,6 +8333,8 @@
"Your machine learning Env work with Jupyter Lab": "Tu entorno de machine learning con Jupyter Lab",
"Your next YouTube media manager": "Tu próximo gestor multimedia de YouTube",
"Your_spotify is a self-hosted application that tracks what you listen and offers you a dashboard to explore statistics about it! It's composed of a web server which polls the Spotify API every now and then and a web application on which you can explore your statistics.": "¡Your_spotify es una aplicación autoalojada que registra lo que escuchas y te ofrece un panel para explorar tus estadísticas! Consta de un servidor web que consulta la API de Spotify cada cierto tiempo y una aplicación web donde explorar tus estadísticas.",
"Z-Wave JS UI": "Z-Wave JS UI",
"Z-Wave JS UI admin login": "Z-Wave JS UI inicio de sesión de administrador",
"ZFS ARC config removed (kernel defaults will apply on reboot)": "Se eliminó la configuración de ZFS ARC (los valores predeterminados del kernel se aplicarán al reiniciar)",
"ZFS ARC maximum configured:": "ZFS ARC máximo configurado:",
"ZFS ARC optimization completed": "Optimización ZFS ARC completada",
@@ -8397,6 +8448,7 @@
"could not be compiled for kernel": "no se pudo compilar para el kernel",
"could not validate NVIDIA; exit code": "no puede validar NVIDIA; código de salida",
"cpuunits must be between 8 and 10000": "cpuunits debe ser entre 8 y 10000",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf": "curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"custom": "personalizado",
"custom dependency commands are not yet supported": "los comandos de dependencia personalizados todavía no son compatibles",
"custom path(s) saved.": "rutas personalizadas guardadas.",
@@ -8602,6 +8654,7 @@
"kexec-tools is not installed or already removed.": "kexec-tools no está instalado o ya se ha eliminado.",
"layers": "capas",
"legacy .link file(s) to the ProxMenux-managed format": "archivo(s) .link antiguos al formato gestionado por ProxMenux",
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.": "llama.cpp muestra en su interfaz web todos los modelos GGUF guardados en /models y carga el que elijas.",
"log2ram completely removed from system": "log2ram completamente eliminado del sistema",
"main container of the application": "contenedor principal de la aplicación",
"make cloned mount tree read-only": "hacer de solo lectura el árbol de montaje clonado",
+53
View File
@@ -184,6 +184,7 @@
"A tunneling daemon by Cloudflare that safely exposes your web servers into the internet.": "Un démon de tunnel par Cloudflare qui expose en toute sécurité vos serveurs web dans Internet.",
"A unified email and collaboration server.": "Un serveur unifié de messagerie et de collaboration.",
"A unified platform for logs, metrics and traces.": "Une plateforme unifiée pour les journaux, les métriques et les traces.",
"A validating, recursive DNS resolver for your private network.": "Un résolveur DNS récursif de validation pour votre réseau privé.",
"A versatile file conversion tool that supports multiple formats.": "Un outil de conversion de fichiers polyvalent qui prend en charge plusieurs formats.",
"A visual tool for exploring and documenting database schemas.": "Un outil visuel pour explorer et documenter les schémas de bases de données.",
"A web GUI client of Project V which supports VMess, VLESS, SS, SSR, Trojan, Tuic and Juicity protocols": "Un client web GUI du Projet V qui prend en charge les protocoles VMess, VLESS, SS, SSR, Trojan, Tuic et Juicity",
@@ -256,6 +257,7 @@
"Acceleration for llama.cpp": "Accélération pour llama.cpp",
"Accept routes from other nodes?": "Accepter les routes d'autres nœuds ?",
"Accept this host monitoring profile?": "Accepter ce profil de surveillance de l'hôte?",
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Accédez au cloud Movistar et O2 depuis des clients WebDAV et des outils de sauvegarde.",
"Access Scope:": "Portée d'accès :",
"Access bridge": "Pont d'accès",
"Access bridge for Immich": "Pont d'accès pour Immich",
@@ -410,6 +412,7 @@
"After the reboot, you will only be able to access the Proxmox host via:": "Après le redémarrage, vous ne pourrez accéder à l'hôte Proxmox que via :",
"After this LXC → VM switch, reboot the host so the new binding state is applied cleanly.": "Après ce commutateur LXC → VM, redémarrez l'hôte afin que le nouvel état de liaison soit appliqué proprement.",
"Agentless monitoring and observability platform.": "Plateforme de supervision et d’observabilité sans agent.",
"AirDC++ administrator": "Administrateur AirDC++",
"Airsonic Advanced web interface": "Interface web Airsonic Advanced",
"Airsonic-advanced is a free, web-based media streamer, providing ubiquitious access to your music. Use it to share your music with friends, or to listen to your own music while at work. You can stream to multiple players simultaneously, for instance to one player in your kitchen and another in your living room.": "Airsonic-Advanced est un flux multimédia gratuit, basé sur le web, offrant un accès ubiquitious à votre musique. Utilisez-le pour partager votre musique avec des amis, ou pour écouter votre propre musique au travail. Vous pouvez diffuser simultanément vers plusieurs joueurs, par exemple vers un joueur dans votre cuisine et un autre dans votre salon.",
"Aliases added to .bashrc": "Alias ajoutés à .bashrc",
@@ -598,11 +601,15 @@
"Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Attention : La suppression de la bannière d'abonnement peut entraîner des problèmes dans l'interface Web après une future mise à jour.",
"Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity est un éditeur et un enregistreur audio facile à utiliser. Développé par un groupe de volontaires comme source ouverte.",
"Audio device directory": "Répertoire des périphériques audio",
"Audio recording and mixing in your browser": "Enregistrement et mixage audio dans le navigateur",
"Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf est un livre audio et un serveur podcast auto-organisé.",
"Audit completed. Press Enter to continue...": "Vérification terminée. Appuyez sur Entrée pour continuer...",
"Audit socket disabled or not required": "Socket d'audit désactivé ou non requis",
"Auth key is required.": "La clé d'authentification est requise.",
"Auth:": "Authentification :",
"Authelia Web UI": "interface utilisateur Web Authelia",
"Authelia administrator": "Administrateur Authelia",
"Authelia session cookie domain for this portal (for example example.com)": "domaine de cookie de session Authelia pour ce portail (par exemple exemple.com)",
"Authentication": "Authentification",
"Authentication & Security": "Authentification et sécurité",
"Authentication Error": "Erreur d'authentification",
@@ -642,6 +649,7 @@
"Available PVE Version": "Version PVE disponible",
"Available Shares:": "Actions disponibles :",
"Available action": "Action disponible",
"Available applications: {count}": "Applications disponibles : {count}",
"Available archives:": "Archives disponibles :",
"Available disks detected.": "Disques disponibles détectés.",
"Available host backups:": "Sauvegardes d'hôte disponibles :",
@@ -873,6 +881,7 @@
"Cannot write the image archive to {storage}. Check storage access and mount status.": "Impossible d'écrire l'archive d'images sur {storage}. Vérifiez l'accès au stockage et l'état du montage.",
"Capabilities cannot be kept and all dropped at the same time": "Les capacités ne peuvent être conservées et toutes abandonnées en même temps",
"Catalog options": "Options du catalogue",
"Catalog refresh unavailable; using the local catalog.": "Impossible de mettre à jour le catalogue ; le catalogue local est utilisé.",
"Category": "Catégorie",
"Caution: Maximum mode generates more heat.": "Attention : le mode maximum génère plus de chaleur.",
"Central server for file and image backups.": "Serveur central pour les sauvegardes de fichiers et d’images.",
@@ -1159,6 +1168,7 @@
"Compressing": "Compression",
"Compression": "Compression",
"Compression Tools": "Outils de compression",
"Computer-aided design and drafting in your browser": "Conception assistée par ordinateur et dessin technique dans le navigateur",
"Concise output of logical volumes": "Sortie concise des volumes logiques",
"Concise output of physical volumes": "Sortie concise des volumes physiques",
"Concise output of volume groups": "Sortie concise des groupes de volumes",
@@ -1393,6 +1403,7 @@
"Controller + NVMe": "Contrôleur + NVMe",
"Controller + NVMe assignment will be written now and become active after host reboot.": "L'affectation Contrôleur + NVMe sera écrite maintenant et deviendra active après le redémarrage de l'hôte.",
"Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.": "Le contrôleur + le relais NVMe nécessite une machine de type q35. Ignorer l'affectation du contrôleur.",
"Controller path on the Proxmox host; prefer /dev/serial/by-id/...": "Chemin du contrôleur sur l’hôte Proxmox ;préférez /dev/serial/by-id/...",
"Controller/NVMe Conflict Policy": "Politique de conflit contrôleur/NVMe",
"Controller/NVMe already present in VM config": "Contrôleur/NVMe déjà présent dans la configuration de la VM",
"Controller/NVMe already present in VM config (%s)": "Contrôleur/NVMe déjà présent dans la configuration de la VM (%s)",
@@ -1927,6 +1938,7 @@
"Dgraph": "Dgraph",
"Diff: current system vs backup (--- system +++ backup)": "Diff : système actuel vs sauvegarde (--- système +++ sauvegarde)",
"Different host. Backup from:": "Hôte différent. Sauvegarde depuis :",
"Direct Connect file sharing with a web interface": "Partage de fichiers Direct Connect avec une interface web",
"Direct conversion completed for container": "Conversion directe terminée pour le conteneur",
"Directory Exists": "Le répertoire existe",
"Directory Not Empty": "Répertoire non vide",
@@ -3340,6 +3352,7 @@
"Initial Stirling-PDF account": "Compte initial Stirling-PDF",
"Initial Tandoor administrator": "Administrateur Tandoor initial",
"Initial Umami administrator": "Administrateur initial d’Umami",
"Initial Z-Wave JS UI admin password": "Mot de passe administrateur initial Z-Wave JS UI",
"Initial administrator created:": "Administrateur initial créé :",
"Initial administrator user": "Administrateur initial",
"Initializing Borg repository if needed...": "Initialisation du référentiel Borg si nécessaire...",
@@ -3525,6 +3538,7 @@
"Interface MTU": "MTU de l'interface",
"Interface Names (persistent)": "noms d'interface (persistants)",
"Interface Type": "Type d'interface",
"Interface design and prototyping in your browser": "Conception d’interfaces et prototypage dans le navigateur",
"Interface names will return to default systemd behavior.": "Les noms d’interface reviendront au comportement systemd par défaut.",
"Interface type:": "Type d'interface :",
"Interfaces configured": "Interfaces configurées",
@@ -3740,6 +3754,7 @@
"Jupyter Lab (token only)": "Jupyter Lab (jeton seulement)",
"JupyterLab": "JupyterLab",
"JupyterLab access token": "Jeton d’accès JupyterLab",
"KDE's twin-panel file manager in a browser-based desktop.": "le gestionnaire de fichiers à deux panneaux de KDE dans un bureau basé sur un navigateur.",
"KDF:": "KDF :",
"KROMA": "KROMA",
"KVM MSR options added to /etc/modprobe.d/kvm.conf": "Options KVM MSR ajoutées à /etc/modprobe.d/kvm.conf",
@@ -3787,12 +3802,14 @@
"KiCad - A Cross Platform and Open Source Electronics Design Automation Suite.": "KiCad - Une plateforme croisée et une suite d'automatisation de conception électronique ouverte.",
"Kimai has no default account. Enter the container with: pct enter {main_vmid}": "Kimai n’a pas de compte par défaut. Ouvrez un shell dans le conteneur avec : pct enter {main_vmid}",
"Kimai is a professional grade time-tracking application, free and open-source.": "Kimai est une application professionnelle de suivi du temps, libre et open-source.",
"KitchenOwl": "KitchenOwl",
"Kometa is a powerful tool designed to give you complete control over your media libraries. With Kometa, you can take your customization to the next level, with granular control over metadata, collections, overlays, and much more.": "Kometa est un outil puissant conçu pour vous donner un contrôle complet sur vos bibliothèques multimédias. Avec Kometa, vous pouvez porter votre personnalisation au niveau suivant, avec un contrôle granulaire sur les métadonnées, les collections, les superpositions et bien plus encore.",
"Kometa reads its configuration from /config/config.yml and the container only ships /config/config.yml.template. Copy the template to config.yml, fill in the required Plex and TMDb connections, then restart the container.": "Kometa lit sa configuration à partir de /config/config.yml et le conteneur ne livre que /config/config.yml.template. Copiez le modèle pour config.yml, remplissez les connexions required Plex et TMDb, puis redémarrez le conteneur.",
"Komga is a media server for your comics, mangas, BDs, magazines and eBooks.": "Komga est un serveur multimédia pour vos BD, mangas, BD, magazines et eBooks.",
"Kopia Web UI": "Interface web de Kopia",
"Kopia Web UI login": "Connexion à l’interface web de Kopia",
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita est un programme professionnel de peinture libre et GRATUIT. Il est fait par des artistes qui veulent voir des outils d'art abordables pour tout le monde.",
"Krusader Web UI": "interface utilisateur Web Krusader",
"LAN access to the kept containers (stack configuration incomplete):": "Accès au réseau local des conteneurs gardés (configuration incomplète):",
"LAN address applied to the application URLs": "Adresse LAN appliquée aux URL de l'application",
"LLDAP": "LLDAP",
@@ -4020,6 +4037,7 @@
"Manage OCI stack": "Gérer la pile OCI",
"Manage PBS encryption keyfile": "Gérer le fichier de clés de chiffrement PBS",
"Manage Secure Gateway": "Gérer Secure Gateway",
"Manage a Z-Wave network from a web dashboard and WebSocket gateway.": "Gérez un réseau Z-Wave à partir d'un tableau de bord Web et d'une passerelle WebSocket.",
"Manage and inspect VM disk images": "Gérer et inspecter les images de disque de VM",
"Manage custom backup paths": "Gérer les chemins de sauvegarde personnalisés",
"Manage custom paths (add / remove your folders)": "Gérer les chemins personnalisés (ajouter/supprimer vos dossiers)",
@@ -4029,6 +4047,7 @@
"Manage local backup target": "Gérer la cible de sauvegarde locale",
"Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Gérer les registres d’images privés.\nLes informations d'identification enregistrées permettent à ProxMenux d'accéder à vos images privées.",
"Manage registry accounts as root on the Proxmox node.": "Gérez les comptes de registre en tant que root sur le nœud Proxmox.",
"Manage teams of AI agents from a web dashboard.": "Gérez des équipes d’agents IA depuis un tableau de bord web.",
"Managed disks must have backup enabled and a valid size": "Les disques gérés doivent avoir une sauvegarde activée et une taille valide",
"Managed public route include is missing": "Le fichier de configuration des routes publiques gérées est manquant",
"Managed public route installation failed": "Impossible de configurer les routes publiques gérées",
@@ -4134,6 +4153,7 @@
"Monitoring": "Surveillance",
"Monitoring & Analytics": "Surveillance et analyse",
"Most common cause: the archive is corrupted (interrupted write, partial copy, or storage issue).": "Cause la plus courante : l'archive est corrompue (écriture interrompue, copie partielle ou problème de stockage).",
"Motion graphics and compositing in your browser": "Animation graphique et compositing dans le navigateur",
"Mount Added Successfully:": "Montage ajouté avec succès :",
"Mount CIFS share:": "Montez le partage CIFS :",
"Mount Configuration Summary:": "Résumé de la configuration du montage :",
@@ -4434,6 +4454,7 @@
"New Search": "Nouvelle recherche",
"New VM:": "Nouvelle VM :",
"New Virtual Machine": "Nouvelle machine virtuelle",
"New applications since your last visit: {count}": "Nouvelles applications depuis votre dernière visite : {count}",
"New backup job": "Nouveau travail de sauvegarde",
"New backups on this host will be unencrypted until a new keyfile is set up.": "Les nouvelles sauvegardes sur cet hôte ne seront pas chiffrées jusqu'à ce qu'un nouveau fichier de clés soit configuré.",
"New image compatible:": "Nouvelle image compatible & #160;:",
@@ -4896,6 +4917,8 @@
"Open the page of an application in the menu": "Ouvrir la page d'une application dans le menu",
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Ouvrez l'adresse web et créez le premier compte : le daemon s'enregistre tout seul et lance la première analyse.",
"Open the web address and create the password of the akadmin user in the first-run setup.": "ouvrez l'adresse Web et créez le mot de passe de l'utilisateur akadmin lors de la configuration de première exécution.",
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured.": "ouvrez l'adresse Web et suivez l'intégration de KitchenOwl pour créer le premier compte ;aucun compte par défaut n'est configuré.",
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Ouvrez le tableau de bord web et liez votre compte Movistar/O2 avec sa vérification par SMS.",
"Open-source AI-powered coding assistant": "Assistant de codage à source ouverte",
"Open-source UI for building and debugging multi-agent and RAG applications": "UI open-source pour la construction et le débogage d'applications multi-agents et RAG",
"Open-source in-memory data store.": "Magasin de données en mémoire libre.",
@@ -5018,6 +5041,7 @@
"Packages:": "Forfaits :",
"Packaging OVA file...": "Emballage du fichier OVA...",
"Packing installer archive...": "Archive du programme d'installation de l'emballage...",
"Page layout and publishing in your browser": "Mise en page et publication dans le navigateur",
"PairDrop is a sublime alternative to AirDrop that works on all platforms. Send images, documents or text via peer to peer connection to devices in the same local network/Wi-Fi or to paired devices.": "PairDrop est une sublime alternative à AirDrop qui fonctionne sur toutes les plateformes. Envoyez des images, des documents ou du texte via une connexion pair à des appareils du même réseau local/Wi-Fi ou à des appareils appariés.",
"Paperless configuration cancelled": "Configuration sans papier annulée",
"Paperless-ngx WebUI": "Paperless-ngx WebUI",
@@ -5036,6 +5060,7 @@
"Pass /dev/video12 to the LXC": "Passer /dev/video12 au LXC",
"Pass a host device to the LXC": "Passer un appareil hôte au LXC",
"Pass the UPS to the LXC": "Passer l'UPS au LXC",
"Pass through a Z-Wave USB or serial controller": "Passer par un contrôleur USB ou série Z-Wave",
"Passing NVIDIA does not enable acceleration inside the application. The host needs NVIDIA Container Toolkit and a compatible image. Continue?": "Passer NVIDIA n’active pas l’accélération dans l’application. L'hôte a besoin du NVIDIA Container Toolkit et d'une image compatible. Continuer?",
"Passkey-based identity provider for self-hosted apps.": "Fournisseur d’identité utilisant des passkeys pour les applications auto-hébergées.",
"Passphrase used to unlock the imported keyfile (leave blank if the keyfile is unencrypted / kdf=none):": "Phrase secrète utilisée pour déverrouiller le fichier de clés importé (laisser vide si le fichier de clés n'est pas chiffré / kdf=aucun) :",
@@ -5143,6 +5168,8 @@
"Personal finance management application": "Demande de gestion des finances personnelles",
"Personal media server for browsing and playing a local video library, with direct play and optional modules.": "Serveur multimédia personnel pour parcourir et lire une vidéothèque locale, avec lecture directe et modules facultatifs.",
"Photo and video library with optional GPU transcoding and machine learning": "Photothèque et vidéothèque avec transcodage GPU optionnel et apprentissage automatique",
"Photo editing in your browser": "Retouche photo dans le navigateur",
"Photo library and RAW development in your browser": "Photothèque et développement RAW dans le navigateur",
"PhotoPrism": "PhotoPrism",
"Photofield": "Photofield",
"Phpmyadmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB.": "Phpmyadmin est un logiciel libre écrit en PHP, destiné à gérer l'administration de MySQL sur le Web. phpMyAdmin prend en charge une large gamme de operations sur MySQL et MariaDB.",
@@ -5235,6 +5262,7 @@
"Preparing the machine learning container for the new choice...": "Préparation du conteneur d'apprentissage automatique pour le nouveau choix...",
"Preparing the recreation...": "Préparer les loisirs...",
"Preparing the update...": "Préparation de la mise à jour...",
"Presentations and slide decks in your browser": "Présentations et diaporamas dans le navigateur",
"Preserving logs to /var/log.hdd before unmounting...": "Conserver les journaux dans /var/log.hdd avant de démonter...",
"Press 'q' to exit": "Appuyez sur « q » pour quitter",
"Press Ctrl+C to stop the server and return to menu.": "Appuyez sur Ctrl+C pour arrêter le serveur et revenir au menu.",
@@ -5395,6 +5423,7 @@
"Proxmox web interface: Datacenter > Storage > Add > ZFS": "Interface web Proxmox : Datacenter > Stockage > Ajouter > ZFS",
"Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Interface Web Proxmox : Datacenter > Stockage > Ajouter > iSCSI",
"Proxy address to reach the API (optional)": "Adresse proxy pour accéder à l'API (facultatif)",
"Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)": "URL HTTPS publique utilisée pour ouvrir ce portail Authelia (par exemple https://auth.example.com)",
"Public UDP port clients connect to": "Les clients du port UDP public se connectent à",
"Public UDP port peers connect to": "Les pairs du port UDP public se connectent à",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "URL publique de phpMyAdmin quand elle est servie derrière un proxy inversé",
@@ -5455,6 +5484,7 @@
"Re-running pre-check after repairs...": "Nouvelle vérification préalable après réparation...",
"Reachable": "Accessible",
"Read an oci-compose from a file of this host": "Lire un oci-compose à partir d'un fichier de cet hôte",
"Read and edit PDF documents in your browser": "Lire et modifier des documents PDF dans le navigateur",
"Read its Compose file from a file of this host": "Lire son fichier Composer à partir d'un fichier de cet hôte",
"Read manga through a self-hosted server and web UI.": "Lire des mangas via un serveur auto-hébergé et son interface web.",
"Read the link with pct console CTID on the Proxmox host, or from the Console panel of the container in the Proxmox web interface, then open the https://playit.gg/claim/ address it shows in a browser and sign in to playit.gg. Ctrl+a q leaves pct console.": "Lisez le lien avec la console pct CTID sur l'hôte Proxmox, ou depuis le panneau Console du conteneur dans l'interface web Proxmox, puis ouvrez l'adresse https://playit.gg/claim/ qu'elle affiche dans un navigateur et connectez-vous à playit.gg. Ctrl+a q quitte la console pct.",
@@ -5560,6 +5590,7 @@
"Recursive and authoritative DNS server.": "Serveur DNS récursif et faisant autorité.",
"Redmine": "Redmine",
"Refresh APT index and verify repositories:": "Actualisez l'index APT et vérifiez les référentiels :",
"Refresh catalog": "Actualiser le catalogue",
"Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.": "Actualiser les dépôts APT configurés et examiner la mise à niveau des paquets PBS ? Les fichiers des dépôts seront conservés.",
"Refresh the index from the image sources": "Actualiser l'index à partir des sources d'images",
"Refresh token of the connector, from the Twingate admin console": "Jeton d'actualisation du connecteur, depuis la console d'administration Twingate",
@@ -5567,6 +5598,7 @@
"Refresh your browser to see changes (server restart may be required)": "Actualisez votre navigateur pour voir les modifications (un redémarrage du serveur peut être nécessaire)",
"Refreshing apt cache...": "Actualisation du cache apt...",
"Refreshing the NVIDIA runtime...": "Rafraîchir l'exécution NVIDIA...",
"Refreshing the application catalog...": "Mise à jour du catalogue des applications...",
"Refusing an unexpected rootfs path:": "Refuser un chemin inattendu de roofs :",
"Regenerate the catalog templates": "Régénérer les modèles du catalogue",
"Regenerate the template of one application": "Régénérer le modèle d'une application",
@@ -6258,6 +6290,7 @@
"Self-hosted file sync and sharing.": "Service auto-hébergé de synchronisation et de partage de fichiers.",
"Self-hosted file toolkit for images, video, audio, PDFs, and files": "Boîte à outils de fichiers auto-organisé pour les images, vidéo, audio, PDF et fichiers",
"Self-hosted forms and workflows.": "Formulaires et workflows auto-hébergés.",
"Self-hosted grocery list and recipe manager": "Liste d'épicerie et gestionnaire de recettes auto-hébergés",
"Self-hosted household plant-care tracker with reminders, photos, and multiple user accounts.": "Suivi auto-hébergé de l'entretien des plantes à la maison, avec rappels, photos et plusieurs comptes utilisateur.",
"Self-hosted image-hosting service with authenticated uploads, image processing, public links, and local storage.": "Service auto-hébergé d'hébergement d'images avec téléversements authentifiés, traitement des images, liens publics et stockage local.",
"Self-hosted internet archiving solution": "Solution d'archivage internet auto-organisé",
@@ -6452,6 +6485,7 @@
"Simple and easy to use DDNS": "Simple et facile à utiliser DDNS",
"Simple self-hosted file sharing.": "Service simple et auto-hébergé de partage de fichiers.",
"Single GPU Warning": "Avertissement sur un seul GPU",
"Single sign-on and multi-factor authentication": "authentification unique et authentification multifacteur",
"Single target found — selected automatically:": "Cible unique trouvée — sélectionnée automatiquement :",
"Single-node log storage and query UI.": "Stockage de journaux sur un nœud unique avec interface de requête.",
"Single-node observability database for metrics, logs and traces.": "Base de données d’observabilité à nœud unique pour les métriques, les journaux et les traces.",
@@ -6520,7 +6554,9 @@
"Specific subnet (enter manually)": "Sous-réseau spécifique (saisir manuellement)",
"Speedtest Tracker web interface": "Interface web Speedtest Tracker",
"Speedtest-tracker is a self-hosted internet performance tracking application that runs speedtest checks against Ookla's Speedtest service.": "Speedtest-tracker est une application de suivi de performance internet auto-organisé qui effectue des contrôles de test de vitesse contre le service Speedtest d'Ookla.",
"Spoolman web interface": "interface Web Spoolman",
"Spotube is an open source, cross-platform Spotify client compatible across multiple platforms utilizing Spotify's data API and YouTube, Piped.video or JioSaavn as an audio source, eliminating the need for Spotify Premium": "Spotube est un client Spotify ouvert et multiplateforme compatible avec plusieurs plateformes utilisant l'API de données de Spotify et YouTube, Piped. vidéo ou JioSaavn comme source audio, éliminant le besoin de Spotify Premium",
"Spreadsheets in your browser": "Tableur dans le navigateur",
"Sshwifty": "Sshwifty",
"Sshwifty web access (password only)": "Accès web à Sshwifty (mot de passe uniquement)",
"Stable (main branch)": "Stable (branche principale)",
@@ -7416,6 +7452,7 @@
"Then bind-mount to container": "Puis liez le montage au conteneur",
"Then change the VM display to none (vga: none) when the guest is stable.": "Modifiez ensuite l'affichage de la VM sur aucun (vga : aucun) lorsque l'invité est stable.",
"Then change the VM display to none (vga: none) when the system is stable.": "Modifiez ensuite l'affichage de la VM sur aucun (vga : aucun) lorsque le système est stable.",
"Then restart the container so the new model appears in the list.": "Redémarrez ensuite le conteneur pour que le nouveau modèle apparaisse dans la liste.",
"Then run this option again:": "Ensuite, réexécutez cette option :",
"Then update /etc/fstab on the host with the same options.": "Mettez ensuite à jour /etc/fstab sur l'hôte avec les mêmes options.",
"There are extra disks or bind mounts outside the journal; the rootfs is not replaced": "Il y a des disques supplémentaires ou des fixations en dehors du journal; les rootfs ne sont pas remplacés",
@@ -7463,6 +7500,7 @@
"This container does not have apt-get. NFS client installation only supports Debian/Ubuntu containers.": "Ce conteneur n'a pas apt-get. L'installation du client NFS prend uniquement en charge les conteneurs Debian/Ubuntu.",
"This container does not have apt-get. Samba client installation only supports Debian/Ubuntu containers.": "Ce conteneur n'a pas apt-get. L'installation du client Samba prend uniquement en charge les conteneurs Debian/Ubuntu.",
"This container has no GPU configured. Coral TPU works best alongside hardware video decoding (Quick Sync, VA-API, NVENC) for apps like Frigate.": "Ce conteneur n'a aucun GPU configuré. Coral TPU fonctionne mieux avec le décodage vidéo matériel (Quick Sync, VA-API, NVENC) pour des applications comme Frigate.",
"This container is managed by high availability. Remove ct:{vmid} from HA (Datacenter → HA, or ha-manager remove ct:{vmid}), repeat the operation and add it back to HA with the same settings.": "Ce conteneur est géré par la haute disponibilité. Retirez ct:{vmid} de HA (Centre de données → HA, ou ha-manager remove ct:{vmid}), relancez l'opération et rajoutez-le à HA avec les mêmes paramètres.",
"This container is not a member of a multi-container application": "Ce conteneur n'est pas membre d'une application multi-conteneurs",
"This container is not a registered OCI instance.": "Ce conteneur n'est pas une instance OCI enregistrée.",
"This container was restored or came back from another host after its record on this host was written. Open this menu again to recover it; nothing was changed.": "Ce conteneur a été restauré ou est revenu d'un autre hôte après l'écriture de son enregistrement sur cet hôte. Ouvrez à nouveau ce menu pour le récupérer ; rien n'a été changé.",
@@ -7581,6 +7619,7 @@
"Tip: You can install the QEMU Guest Agent inside the VM with:": "Astuce : Vous pouvez installer l'agent invité QEMU dans la VM avec :",
"Tip: zfs set acltype=posixacl xattr=sa <pool>/<dataset> enables full ACL support.": "Astuce : zfs set acltype=posixacl xattr=sa <pool>/<dataset> active la prise en charge complète des ACL.",
"Tmpfs size in MiB for": "Taille Tmpfs en MiB pour",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:": "Pour ajouter un modèle, ouvrez la console du conteneur dans Proxmox et téléchargez-le dans /models, par exemple :",
"To allow LXC write access, change the NFS export on the server to include:": "Pour autoriser l'accès en écriture LXC, modifiez l'exportation NFS sur le serveur pour inclure :",
"To apply it to the current shell now, run:": "Pour l’appliquer maintenant à la session shell actuelle, exécutez :",
"To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.": "Pour attribuer des VF aux VM ou LXC, modifiez la configuration manuellement via l'interface Web Proxmox. La fonction physique restera liée au pilote natif.",
@@ -7620,6 +7659,7 @@
"Total routes": "Total des itinéraires",
"Total size:": "Taille totale :",
"Toxiproxy": "Toxiproxy",
"Track 3D printer filament spools and usage.": "Suivez les bobines de filament d’imprimante 3D et leur utilisation.",
"Track movies, television, anime and games you want to enjoy.": "Suivez les films, séries, animés et jeux vidéo que vous souhaitez découvrir.",
"Track subscriptions and recurring expenses.": "Suivi des abonnements et des dépenses récurrentes.",
"Track your music listening history on your own server.": "Historique d’écoute musicale hébergé sur votre propre serveur.",
@@ -7854,6 +7894,7 @@
"Update the whole stack?": "Mettre à jour toute la pile ?",
"Update, modify or recreate one installed OCI instance": "Mettre à jour, modifier ou recréer une instance OCI installée",
"Updated": "Mis à jour",
"Updated recipes since your last visit: {count}": "Recettes mises à jour depuis votre dernière visite : {count}",
"Updated sharedfiles group to GID: 101000": "Groupe de fichiers partagés mis à jour vers GID : 101000",
"Updated stack checked": "Correction de la pile",
"Updated:": "Mise à jour :",
@@ -8059,6 +8100,7 @@
"Variables": "Variables",
"Variables the installation asks for:": "Variables que l'installation demande:",
"Vaultwarden Web Vault": "Vaultwarden Web Vault",
"Vector illustration in your browser": "Illustration vectorielle dans le navigateur",
"Vector search engine with a built-in dashboard.": "Moteur de recherche vectorielle avec tableau de bord intégré.",
"Verbose pool status": "État du pool détaillé",
"Verification": "Vérification",
@@ -8089,6 +8131,7 @@
"Versions shown belong to maintained NVIDIA branches that list your GPU PCI ID and are new enough to build against the running kernel. DKMS compilation is the final validation. The recommended version keeps the current branch, or uses the NVIDIA Production Branch on a fresh install.": "Les versions affichées appartiennent aux branches NVIDIA maintenues qui répertorient votre ID PCI GPU et sont suffisamment récentes pour être construites sur le noyau en cours d'exécution. La compilation DKMS est la validation finale. La version recommandée conserve la branche actuelle ou utilise la branche de production NVIDIA sur une nouvelle installation.",
"VictoriaLogs": "VictoriaLogs",
"Video acceleration and object detection are independent choices; the installer does not write camera or detector YAML.": "L'accélération vidéo et la détection d'objets sont des choix indépendants; l'installateur n'écrit pas la caméra ou le détecteur YAML.",
"Video editing in your browser": "Montage vidéo dans le navigateur",
"Video transcoding acceleration": "Accélération du transcodage vidéo",
"Video transcoding profile not implemented:": "Profil de transcodage vidéo non implémenté :",
"View CIFS Mounts (pvesm + fstab)": "Afficher les montages CIFS (pvesm + fstab)",
@@ -8198,12 +8241,17 @@
"Web access": "Accès au Web",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Adresse Web du AdGuard Home qui reçoit les paramètres (p. ex. http://192.168.1.3)",
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Adresse Web du principal AdGuard Home, dont les paramètres sont copiés (par exemple http://192.168.1.2)",
"Web dashboard": "Tableau de bord web",
"Web dashboard and WebDAV": "Tableau de bord web et WebDAV",
"Web interface": "interface Web",
"Web interface for Borg Backup repositories and jobs.": "Interface web pour les dépôts et tâches Borg Backup.",
"Web interface for managing 3D printers.": "Interface web de gestion des imprimantes 3D.",
"Web interface to manage devices running Tasmota firmware.": "Interface Web pour gérer les appareils utilisant le firmware Tasmota.",
"Web reverse proxy with an administration interface.": "Proxy inverse web doté d’une interface d’administration.",
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord peut être résumé comme un paquet de durcissements de sécurité et de confidentialité, les fonctionnalités Discord réimplémentations, Electron / Chromium / Discord bugs workarounds, les feuilles de style, les pages internes et la page https://discord.com enveloppée, conçue pour se conformer à ToS autant qu'il est possible (ou cacher les changements qui pourraient la violer des yeux de Discord).",
"WebDAV": "WebDAV",
"WebDAV and dashboard password (leave empty to generate)": "Mot de passe WebDAV et du tableau de bord (vide = généré)",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV est disponible sur le port 8080 du conteneur. Le compte doit être lié avant toute opération sur les fichiers du cloud.",
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus est un accrocheur différentiel multisite xmltv egg. Il recueille les données du guide TV-programme à partir de sites sélectionnés pour vos chaînes préférées.",
"Webservers & Proxies": "Serveurs web et proxys",
"Website": "Site web",
@@ -8261,6 +8309,7 @@
"Without a usable reset path, passthrough reliability is poor and VM": "Sans chemin de réinitialisation utilisable, la fiabilité du relais est médiocre et la VM",
"Wizard cancelled": "Assistant annulé",
"Wolfenstein: Blade of Agony is a story-driven WWII shooter inspired by Wolfenstein and Doom.": "Wolfenstein: Blade of Agony est un jeu de tir inspiré par Wolfenstein et Doom.",
"Word processing in your browser": "Traitement de texte dans le navigateur",
"Workflow automation tool": "Outil d'automatisation du flux de travail",
"Working directory:": "Répertoire de travail :",
"Works with LVM, ZFS, and BTRFS storage types": "Fonctionne avec les types de stockage LVM, ZFS et BTRFS",
@@ -8311,6 +8360,8 @@
"Your machine learning Env work with Jupyter Lab": "Votre machine learning Env travaille avec Jupyter Lab",
"Your next YouTube media manager": "Votre prochain gestionnaire de médias YouTube",
"Your_spotify is a self-hosted application that tracks what you listen and offers you a dashboard to explore statistics about it! It's composed of a web server which polls the Spotify API every now and then and a web application on which you can explore your statistics.": "Your_spotify est une application auto-hôte qui suit ce que vous écoutez et vous offre un tableau de bord pour explorer les statistiques à ce sujet! Il est composé d'un serveur web qui interroge l'API Spotify de temps en temps et d'une application web sur laquelle vous pouvez explorer vos statistiques.",
"Z-Wave JS UI": "Z-Wave JS UI",
"Z-Wave JS UI admin login": "connexion administrateur Z-Wave JS UI",
"ZFS ARC config removed (kernel defaults will apply on reboot)": "Configuration ZFS ARC supprimée (les valeurs par défaut du noyau s'appliqueront au redémarrage)",
"ZFS ARC maximum configured:": "ZFS ARC maximum configuré :",
"ZFS ARC optimization completed": "Optimisation ZFS ARC terminée",
@@ -8424,6 +8475,7 @@
"could not be compiled for kernel": "n'a pas pu être compilé pour le noyau",
"could not validate NVIDIA; exit code": "n'a pas pu valider NVIDIA; code de sortie",
"cpuunits must be between 8 and 10000": "cpuunits doivent être compris entre 8 et 10000",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf": "curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"custom": "personnalisé",
"custom dependency commands are not yet supported": "commandes de dépendance personnalisées ne sont pas encore prises en charge",
"custom path(s) saved.": "chemin(s) personnalisé(s) enregistré(s).",
@@ -8630,6 +8682,7 @@
"kexec-tools is not installed or already removed.": "kexec-tools n'est pas installé ou déjà supprimé.",
"layers": "couches",
"legacy .link file(s) to the ProxMenux-managed format": "les anciens fichiers .link au format géré par ProxMenux",
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.": "llama.cpp affiche dans son interface web tous les modèles GGUF enregistrés dans /models et charge celui que vous choisissez.",
"log2ram completely removed from system": "log2ram complètement supprimé du système",
"main container of the application": "conteneur principal de l'application",
"make cloned mount tree read-only": "rendre l'arborescence de montage clonée en lecture seule",
+53
View File
@@ -184,6 +184,7 @@
"A tunneling daemon by Cloudflare that safely exposes your web servers into the internet.": "Un servizio di tunneling di Cloudflare che espone in modo sicuro i tuoi server web su Internet.",
"A unified email and collaboration server.": "Un server unificato per email e collaborazione.",
"A unified platform for logs, metrics and traces.": "Una piattaforma unificata per log, metriche e tracce.",
"A validating, recursive DNS resolver for your private network.": "un risolutore DNS ricorsivo e di convalida per la tua rete privata.",
"A versatile file conversion tool that supports multiple formats.": "Uno strumento versatile per convertire file in diversi formati.",
"A visual tool for exploring and documenting database schemas.": "Uno strumento visivo per esplorare e documentare gli schemi dei database.",
"A web GUI client of Project V which supports VMess, VLESS, SS, SSR, Trojan, Tuic and Juicity protocols": "Un client web di Project V che supporta i protocolli VMess, VLESS, SS, SSR, Trojan, Tuic e Juicity",
@@ -256,6 +257,7 @@
"Acceleration for llama.cpp": "Accelerazione per llama.cpp",
"Accept routes from other nodes?": "Accettare rotte da altri nodi?",
"Accept this host monitoring profile?": "Accettare questo profilo di monitoraggio host?",
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Accedi al cloud di Movistar e O2 da client WebDAV e strumenti di backup.",
"Access Scope:": "Ambito di accesso:",
"Access bridge": "Bridge di accesso",
"Access bridge for Immich": "Bridge di accesso per Immich",
@@ -410,6 +412,7 @@
"After the reboot, you will only be able to access the Proxmox host via:": "Dopo il riavvio, potrai accedere all'host Proxmox solo tramite:",
"After this LXC → VM switch, reboot the host so the new binding state is applied cleanly.": "Dopo questo passaggio LXC → VM, riavviare l’host in modo che il nuovo stato di associazione venga applicato correttamente.",
"Agentless monitoring and observability platform.": "Piattaforma di monitoraggio e osservabilità senza agent.",
"AirDC++ administrator": "Amministratore AirDC++",
"Airsonic Advanced web interface": "Interfaccia web Airsonic Advanced",
"Airsonic-advanced is a free, web-based media streamer, providing ubiquitious access to your music. Use it to share your music with friends, or to listen to your own music while at work. You can stream to multiple players simultaneously, for instance to one player in your kitchen and another in your living room.": "Airsonic-advanced è un servizio gratuito di streaming multimediale via web che permette di accedere alla propria musica ovunque. Puoi condividerla con gli amici o ascoltarla mentre lavori. Puoi riprodurla contemporaneamente su più dispositivi, per esempio in cucina e in soggiorno.",
"Aliases added to .bashrc": "Alias aggiunti a .bashrc",
@@ -598,11 +601,15 @@
"Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Attenzione: la rimozione del banner di abbonamento potrebbe causare problemi nell'interfaccia web dopo un futuro aggiornamento.",
"Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity è un editor e registratore audio multitraccia facile da usare, sviluppato come software open source da un gruppo di volontari.",
"Audio device directory": "Directory del dispositivo audio",
"Audio recording and mixing in your browser": "Registrazione e missaggio audio nel browser",
"Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf è un server self-hosted per audiolibri e podcast.",
"Audit completed. Press Enter to continue...": "Audit completato. Premi Invio per continuare...",
"Audit socket disabled or not required": "Socket di audit disabilitato o non richiesto",
"Auth key is required.": "È richiesta la chiave di autenticazione.",
"Auth:": "Autenticazione:",
"Authelia Web UI": "interfaccia utente Web Authelia",
"Authelia administrator": "amministratore Authelia",
"Authelia session cookie domain for this portal (for example example.com)": "dominio del cookie di sessione Authelia per questo portale (ad esempio example.com)",
"Authentication": "Autenticazione",
"Authentication & Security": "Autenticazione e sicurezza",
"Authentication Error": "Errore di autenticazione",
@@ -642,6 +649,7 @@
"Available PVE Version": "Versione PVE disponibile",
"Available Shares:": "Condivisioni disponibili:",
"Available action": "Azione disponibile",
"Available applications: {count}": "Applicazioni disponibili: {count}",
"Available archives:": "Archivi disponibili:",
"Available disks detected.": "Rilevati dischi disponibili.",
"Available host backups:": "Backup host disponibili:",
@@ -873,6 +881,7 @@
"Cannot write the image archive to {storage}. Check storage access and mount status.": "Impossibile scrivere l'archivio dell'immagine su {storage}. Controlla l'accesso allo storage e lo stato di montaggio.",
"Capabilities cannot be kept and all dropped at the same time": "Non è possibile conservare alcune capability e rimuoverle tutte contemporaneamente",
"Catalog options": "Opzioni del catalogo",
"Catalog refresh unavailable; using the local catalog.": "Impossibile aggiornare il catalogo; viene usata la copia locale.",
"Category": "Categoria",
"Caution: Maximum mode generates more heat.": "Attenzione: la modalità massima genera più calore.",
"Central server for file and image backups.": "Server centrale per il backup di file e immagini.",
@@ -1159,6 +1168,7 @@
"Compressing": "Compressione",
"Compression": "Compressione",
"Compression Tools": "Strumenti di compressione",
"Computer-aided design and drafting in your browser": "Progettazione CAD e disegno tecnico nel browser",
"Concise output of logical volumes": "Output conciso di volumi logici",
"Concise output of physical volumes": "Output conciso di volumi fisici",
"Concise output of volume groups": "Output conciso dei gruppi di volumi",
@@ -1393,6 +1403,7 @@
"Controller + NVMe": "Controller + NVMe",
"Controller + NVMe assignment will be written now and become active after host reboot.": "L'assegnazione Controller + NVMe verrà scritta ora e diventerà attiva dopo il riavvio dell'host.",
"Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.": "Il passthrough di controller + NVMe richiede il tipo di macchina q35. Assegnazione del controller saltata.",
"Controller path on the Proxmox host; prefer /dev/serial/by-id/...": "percorso del controller sull'host Proxmox;preferisco /dev/serial/by-id/...",
"Controller/NVMe Conflict Policy": "Policy conflitti controller/NVMe",
"Controller/NVMe already present in VM config": "Controller/NVMe già presente nella configurazione VM",
"Controller/NVMe already present in VM config (%s)": "Controller/NVMe già presente nella configurazione della VM (%s)",
@@ -1927,6 +1938,7 @@
"Dgraph": "Dgraph",
"Diff: current system vs backup (--- system +++ backup)": "Differenza: sistema attuale vs backup (--- sistema +++ backup)",
"Different host. Backup from:": "Host diverso. Backup da:",
"Direct Connect file sharing with a web interface": "Condivisione di file Direct Connect con interfaccia web",
"Direct conversion completed for container": "Conversione diretta completata per il container",
"Directory Exists": "Directory esistente",
"Directory Not Empty": "Directory non vuota",
@@ -3340,6 +3352,7 @@
"Initial Stirling-PDF account": "Account iniziale di Stirling-PDF",
"Initial Tandoor administrator": "Amministratore iniziale Tandoor",
"Initial Umami administrator": "Amministratore iniziale di Umami",
"Initial Z-Wave JS UI admin password": "password amministratore iniziale Z-Wave JS UI",
"Initial administrator created:": "Amministratore iniziale creato:",
"Initial administrator user": "Utente amministratore iniziale",
"Initializing Borg repository if needed...": "Inizializzazione del repository Borg, se necessario...",
@@ -3525,6 +3538,7 @@
"Interface MTU": "MTU interfaccia",
"Interface Names (persistent)": "Nomi interfacce (persistenti)",
"Interface Type": "Tipo interfaccia",
"Interface design and prototyping in your browser": "Progettazione di interfacce e prototipi nel browser",
"Interface names will return to default systemd behavior.": "I nomi delle interfacce torneranno al comportamento systemd predefinito.",
"Interface type:": "Tipo interfaccia:",
"Interfaces configured": "Interfacce configurate",
@@ -3740,6 +3754,7 @@
"Jupyter Lab (token only)": "Jupyter Lab (solo token)",
"JupyterLab": "JupyterLab",
"JupyterLab access token": "Token di accesso JupyterLab",
"KDE's twin-panel file manager in a browser-based desktop.": "il file manager a doppio pannello di KDE in un desktop basato su browser.",
"KDF:": "KDF:",
"KROMA": "KROMA",
"KVM MSR options added to /etc/modprobe.d/kvm.conf": "Opzioni KVM MSR aggiunte a /etc/modprobe.d/kvm.conf",
@@ -3787,12 +3802,14 @@
"KiCad - A Cross Platform and Open Source Electronics Design Automation Suite.": "KiCad: una suite multipiattaforma e open source per la progettazione elettronica.",
"Kimai has no default account. Enter the container with: pct enter {main_vmid}": "Kimai non ha un account predefinito. Accedi al container con: pct enter {main_vmid}",
"Kimai is a professional grade time-tracking application, free and open-source.": "Kimai è un'applicazione professionale, gratuita e open source per il monitoraggio del tempo.",
"KitchenOwl": "KitchenOwl",
"Kometa is a powerful tool designed to give you complete control over your media libraries. With Kometa, you can take your customization to the next level, with granular control over metadata, collections, overlays, and much more.": "Kometa è uno strumento che ti offre un controllo completo sulle tue librerie multimediali. Permette di personalizzare nel dettaglio metadati, raccolte, sovrimpressioni e molto altro.",
"Kometa reads its configuration from /config/config.yml and the container only ships /config/config.yml.template. Copy the template to config.yml, fill in the required Plex and TMDb connections, then restart the container.": "Kometa legge la configurazione da /config/config.yml, ma il container include solo /config/config.yml.template. Copia il modello in config.yml, configura le connessioni necessarie a Plex e TMDb, quindi riavvia il container.",
"Komga is a media server for your comics, mangas, BDs, magazines and eBooks.": "Komga è un server multimediale per fumetti, manga, bande dessinée, riviste ed e-book.",
"Kopia Web UI": "Interfaccia web di Kopia",
"Kopia Web UI login": "Accesso all’interfaccia web di Kopia",
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita è un programma professionale, gratuito e open source per dipingere. È creato da artisti che vogliono rendere gli strumenti artistici accessibili a tutti.",
"Krusader Web UI": "interfaccia utente Web Krusader",
"LAN access to the kept containers (stack configuration incomplete):": "Accesso LAN ai container conservati (configurazione stack incompleta):",
"LAN address applied to the application URLs": "Indirizzo LAN applicato agli URL dell'applicazione",
"LLDAP": "LLDAP",
@@ -4020,6 +4037,7 @@
"Manage OCI stack": "Gestisci stack OCI",
"Manage PBS encryption keyfile": "Gestisci il file di chiavi di crittografia PBS",
"Manage Secure Gateway": "Gestisci Secure Gateway",
"Manage a Z-Wave network from a web dashboard and WebSocket gateway.": "gestisci una rete Z-Wave da una dashboard Web e da un gateway WebSocket.",
"Manage and inspect VM disk images": "Gestisci e ispeziona le immagini disco delle VM",
"Manage custom backup paths": "Gestisci percorsi di backup personalizzati",
"Manage custom paths (add / remove your folders)": "Gestisci percorsi personalizzati (aggiungi/rimuovi le tue cartelle)",
@@ -4029,6 +4047,7 @@
"Manage local backup target": "Gestisci la destinazione di backup locale",
"Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Gestisci i registri di immagini private.\nLe credenziali salvate consentono a ProxMenux di accedere alle tue immagini private.",
"Manage registry accounts as root on the Proxmox node.": "Gestisci gli account del registro come root sul nodo Proxmox.",
"Manage teams of AI agents from a web dashboard.": "Gestisci team di agenti IA da una dashboard web.",
"Managed disks must have backup enabled and a valid size": "I dischi gestiti devono avere il backup abilitato e una dimensione valida",
"Managed public route include is missing": "Manca la direttiva di inclusione per le rotte pubbliche gestite",
"Managed public route installation failed": "Impossibile configurare le rotte pubbliche gestite",
@@ -4134,6 +4153,7 @@
"Monitoring": "Monitoraggio",
"Monitoring & Analytics": "Monitoraggio e analisi",
"Most common cause: the archive is corrupted (interrupted write, partial copy, or storage issue).": "Causa più comune: l'archivio è danneggiato (scrittura interrotta, copia parziale o problema di archiviazione).",
"Motion graphics and compositing in your browser": "Grafica animata e compositing nel browser",
"Mount Added Successfully:": "Montaggio aggiunto con successo:",
"Mount CIFS share:": "Monta la condivisione CIFS:",
"Mount Configuration Summary:": "Riepilogo configurazione montaggio:",
@@ -4434,6 +4454,7 @@
"New Search": "Nuova ricerca",
"New VM:": "Nuova VM:",
"New Virtual Machine": "Nuova VM",
"New applications since your last visit: {count}": "Nuove applicazioni dalla tua ultima visita: {count}",
"New backup job": "Nuova attività di backup",
"New backups on this host will be unencrypted until a new keyfile is set up.": "I nuovi backup su questo host non saranno crittografati finché non verrà impostato un nuovo file di chiavi.",
"New image compatible:": "Nuova immagine compatibile:",
@@ -4896,6 +4917,8 @@
"Open the page of an application in the menu": "Apri la pagina di un'applicazione nel menu",
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Apri l'indirizzo web e crea il primo account: il daemon si registra da solo e avvia la prima scansione.",
"Open the web address and create the password of the akadmin user in the first-run setup.": "Apri l'indirizzo web e imposta la password dell'utente akadmin durante la configurazione iniziale.",
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured.": "apri l'indirizzo web e segui l'onboarding di KitchenOwl per creare il primo account;non è configurato alcun account predefinito.",
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Apri la dashboard web e collega il tuo account Movistar/O2 con la verifica tramite SMS.",
"Open-source AI-powered coding assistant": "Assistente open source per la programmazione basato sull'IA",
"Open-source UI for building and debugging multi-agent and RAG applications": "Interfaccia open source per creare ed eseguire il debug di applicazioni multiagente e RAG",
"Open-source in-memory data store.": "Archivio dati in memoria open source.",
@@ -5018,6 +5041,7 @@
"Packages:": "Pacchetti:",
"Packaging OVA file...": "Creazione del file OVA...",
"Packing installer archive...": "Compressione dell'archivio del programma di installazione...",
"Page layout and publishing in your browser": "Impaginazione e pubblicazione nel browser",
"PairDrop is a sublime alternative to AirDrop that works on all platforms. Send images, documents or text via peer to peer connection to devices in the same local network/Wi-Fi or to paired devices.": "PairDrop è un'ottima alternativa ad AirDrop che funziona su tutte le piattaforme. Invia immagini, documenti o testo con una connessione peer-to-peer a dispositivi sulla stessa rete locale/Wi-Fi o a dispositivi associati.",
"Paperless configuration cancelled": "Configurazione di Paperless annullata",
"Paperless-ngx WebUI": "Paperless-ngx WebUI",
@@ -5036,6 +5060,7 @@
"Pass /dev/video12 to the LXC": "Collega /dev/video12 al container LXC",
"Pass a host device to the LXC": "Collega un dispositivo dell’host al container LXC",
"Pass the UPS to the LXC": "Passa l'UPS al container LXC",
"Pass through a Z-Wave USB or serial controller": "passa attraverso un controller USB o seriale Z-Wave",
"Passing NVIDIA does not enable acceleration inside the application. The host needs NVIDIA Container Toolkit and a compatible image. Continue?": "il passaggio di NVIDIA non abilita l'accelerazione all'interno dell'applicazione. L'host necessita di NVIDIA Container Toolkit e di un'immagine compatibile. Continuare?",
"Passkey-based identity provider for self-hosted apps.": "Provider di identità basato su passkey per app self-hosted.",
"Passphrase used to unlock the imported keyfile (leave blank if the keyfile is unencrypted / kdf=none):": "Passphrase per sbloccare il file di chiavi importato (lascia vuoto se non è crittografato / kdf=none):",
@@ -5143,6 +5168,8 @@
"Personal finance management application": "Applicazione per la gestione delle finanze personali",
"Personal media server for browsing and playing a local video library, with direct play and optional modules.": "Server multimediale personale per sfogliare e riprodurre una raccolta video locale, con riproduzione diretta e moduli opzionali.",
"Photo and video library with optional GPU transcoding and machine learning": "Libreria di foto e video con transcodifica GPU e apprendimento automatico opzionali",
"Photo editing in your browser": "Fotoritocco nel browser",
"Photo library and RAW development in your browser": "Libreria fotografica e sviluppo RAW nel browser",
"PhotoPrism": "PhotoPrism",
"Photofield": "Photofield",
"Phpmyadmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB.": "phpMyAdmin è uno strumento software libero scritto in PHP per amministrare MySQL via web. Supporta numerose operazioni su MySQL e MariaDB.",
@@ -5235,6 +5262,7 @@
"Preparing the machine learning container for the new choice...": "Preparazione del container per machine learning con la nuova scelta...",
"Preparing the recreation...": "Preparazione ricreazione...",
"Preparing the update...": "Preparazione dell'aggiornamento...",
"Presentations and slide decks in your browser": "Presentazioni e diapositive nel browser",
"Preserving logs to /var/log.hdd before unmounting...": "Conservazione dei log su /var/log.hdd prima dello smontaggio...",
"Press 'q' to exit": "Premi 'q' per uscire",
"Press Ctrl+C to stop the server and return to menu.": "Premi Ctrl+C per arrestare il server e tornare al menu.",
@@ -5395,6 +5423,7 @@
"Proxmox web interface: Datacenter > Storage > Add > ZFS": "Interfaccia web Proxmox: Datacenter > Storage > Aggiungi > ZFS",
"Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Interfaccia web Proxmox: Datacenter > Storage > Aggiungi > iSCSI",
"Proxy address to reach the API (optional)": "Indirizzo proxy per raggiungere l'API (facoltativo)",
"Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)": "URL HTTPS pubblico utilizzato per aprire questo portale Authelia (ad esempio https://auth.example.com)",
"Public UDP port clients connect to": "Porta UDP pubblica a cui si connettono i client",
"Public UDP port peers connect to": "Porta UDP pubblica a cui si connettono i peer",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "URL pubblico di phpMyAdmin quando viene servito dietro un proxy inverso",
@@ -5455,6 +5484,7 @@
"Re-running pre-check after repairs...": "Nuova esecuzione del controllo preliminare dopo la riparazione...",
"Reachable": "Raggiungibile",
"Read an oci-compose from a file of this host": "Leggi un oci-compose da un file dell’host",
"Read and edit PDF documents in your browser": "Lettura e modifica di documenti PDF nel browser",
"Read its Compose file from a file of this host": "Leggi il file Compose da un file dell’host",
"Read manga through a self-hosted server and web UI.": "Lettura di manga tramite un server self-hosted e un’interfaccia web.",
"Read the link with pct console CTID on the Proxmox host, or from the Console panel of the container in the Proxmox web interface, then open the https://playit.gg/claim/ address it shows in a browser and sign in to playit.gg. Ctrl+a q leaves pct console.": "Leggi il link con pct console CTID sull'host Proxmox oppure nel pannello Console del container nell'interfaccia web Proxmox. Apri nel browser l'indirizzo https://playit.gg/claim/ mostrato e accedi a playit.gg. Ctrl+a q chiude pct console.",
@@ -5560,6 +5590,7 @@
"Recursive and authoritative DNS server.": "Server DNS ricorsivo e autorevole.",
"Redmine": "Redmine",
"Refresh APT index and verify repositories:": "Aggiorna l'indice APT e verifica i repository:",
"Refresh catalog": "Aggiorna catalogo",
"Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.": "Aggiornare gli indici dei repository APT configurati ed esaminare l'aggiornamento dei pacchetti PBS? I file dei repository verranno conservati.",
"Refresh the index from the image sources": "Aggiorna l'indice dalle sorgenti delle immagini",
"Refresh token of the connector, from the Twingate admin console": "Token di refresh del connettore, dalla console di amministrazione Twingate",
@@ -5567,6 +5598,7 @@
"Refresh your browser to see changes (server restart may be required)": "Aggiorna il browser per vedere le modifiche (potrebbe essere necessario il riavvio del server)",
"Refreshing apt cache...": "Aggiornamento cache apt...",
"Refreshing the NVIDIA runtime...": "Aggiornamento del runtime NVIDIA...",
"Refreshing the application catalog...": "Aggiornamento del catalogo delle applicazioni...",
"Refusing an unexpected rootfs path:": "Rifiutato un percorso rootfs inatteso:",
"Regenerate the catalog templates": "Rigenera i modelli del catalogo",
"Regenerate the template of one application": "Rigenera il modello di un'applicazione",
@@ -6258,6 +6290,7 @@
"Self-hosted file sync and sharing.": "Servizio self-hosted per sincronizzare e condividere file.",
"Self-hosted file toolkit for images, video, audio, PDFs, and files": "Set di strumenti self-hosted per immagini, video, audio, PDF e altri file",
"Self-hosted forms and workflows.": "Moduli e flussi di lavoro auto-ospitati.",
"Self-hosted grocery list and recipe manager": "lista della spesa e gestore di ricette self-hosted",
"Self-hosted household plant-care tracker with reminders, photos, and multiple user accounts.": "Strumento per la cura delle piante domestiche da ospitare sul proprio server, con promemoria, foto e più account utente.",
"Self-hosted image-hosting service with authenticated uploads, image processing, public links, and local storage.": "Servizio per ospitare immagini sul proprio server, con caricamenti autenticati, elaborazione delle immagini, link pubblici e archiviazione locale.",
"Self-hosted internet archiving solution": "Soluzione self-hosted per archiviare contenuti Internet",
@@ -6452,6 +6485,7 @@
"Simple and easy to use DDNS": "DDNS semplice e facile da usare",
"Simple self-hosted file sharing.": "Servizio semplice e self-hosted per condividere file.",
"Single GPU Warning": "Avviso GPU singola",
"Single sign-on and multi-factor authentication": "Single Sign-On e autenticazione a più fattori",
"Single target found — selected automatically:": "Unica destinazione trovata - selezionata automaticamente:",
"Single-node log storage and query UI.": "Archiviazione dei log su un singolo nodo e interfaccia di interrogazione.",
"Single-node observability database for metrics, logs and traces.": "Database di osservabilità a nodo singolo per metriche, log e tracce.",
@@ -6520,7 +6554,9 @@
"Specific subnet (enter manually)": "Sottorete specifica (immettere manualmente)",
"Speedtest Tracker web interface": "Interfaccia web Speedtest Tracker",
"Speedtest-tracker is a self-hosted internet performance tracking application that runs speedtest checks against Ookla's Speedtest service.": "Speedtest-tracker è un'applicazione self-hosted per monitorare le prestazioni della connessione Internet eseguendo test tramite il servizio Speedtest di Ookla.",
"Spoolman web interface": "interfaccia web Spoolman",
"Spotube is an open source, cross-platform Spotify client compatible across multiple platforms utilizing Spotify's data API and YouTube, Piped.video or JioSaavn as an audio source, eliminating the need for Spotify Premium": "Spotube è un client Spotify open source e multipiattaforma che usa l'API dati di Spotify e YouTube, Piped.video o JioSaavn come sorgenti audio, eliminando la necessità di Spotify Premium",
"Spreadsheets in your browser": "Fogli di calcolo nel browser",
"Sshwifty": "Sshwifty",
"Sshwifty web access (password only)": "Accesso web a Sshwifty (solo password)",
"Stable (main branch)": "Stabile (ramo main)",
@@ -7417,6 +7453,7 @@
"Then bind-mount to container": "Quindi eseguire un bind mount nel container",
"Then change the VM display to none (vga: none) when the guest is stable.": "Quindi impostare il display VM su none (vga: none) quando il guest è stabile.",
"Then change the VM display to none (vga: none) when the system is stable.": "Quindi impostare il display VM su none (vga: none) quando il sistema è stabile.",
"Then restart the container so the new model appears in the list.": "Poi riavvia il container perché il nuovo modello compaia nell'elenco.",
"Then run this option again:": "Quindi eseguire di nuovo questa opzione:",
"Then update /etc/fstab on the host with the same options.": "Quindi aggiornare /etc/fstab sull’host con le stesse opzioni.",
"There are extra disks or bind mounts outside the journal; the rootfs is not replaced": "Ci sono dischi aggiuntivi o bind mount non registrati nel journal; la rootfs non viene sostituita",
@@ -7464,6 +7501,7 @@
"This container does not have apt-get. NFS client installation only supports Debian/Ubuntu containers.": "Questo container non ha apt-get. L'installazione del client NFS supporta solo i container Debian/Ubuntu.",
"This container does not have apt-get. Samba client installation only supports Debian/Ubuntu containers.": "Questo container non ha apt-get. L'installazione del client Samba supporta solo i container Debian/Ubuntu.",
"This container has no GPU configured. Coral TPU works best alongside hardware video decoding (Quick Sync, VA-API, NVENC) for apps like Frigate.": "Questo container non ha una GPU configurata. Coral TPU funziona meglio insieme alla decodifica video hardware (Quick Sync, VA-API, NVENC) per app come Frigate.",
"This container is managed by high availability. Remove ct:{vmid} from HA (Datacenter → HA, or ha-manager remove ct:{vmid}), repeat the operation and add it back to HA with the same settings.": "Questo container è gestito dall'alta disponibilità. Rimuovi ct:{vmid} da HA (Datacenter → HA, oppure ha-manager remove ct:{vmid}), ripeti l'operazione e aggiungilo di nuovo a HA con le stesse impostazioni.",
"This container is not a member of a multi-container application": "Questo container non fa parte di un’applicazione con più container",
"This container is not a registered OCI instance.": "Questo container non è un’istanza OCI registrata.",
"This container was restored or came back from another host after its record on this host was written. Open this menu again to recover it; nothing was changed.": "Questo contenitore è stato ripristinato o è tornato da un altro host dopo la scrittura del suo record su questo host. Apri nuovamente questo menu per recuperarlo; non è stato modificato nulla.",
@@ -7582,6 +7620,7 @@
"Tip: You can install the QEMU Guest Agent inside the VM with:": "Suggerimento: è possibile installare QEMU Guest Agent nella VM con:",
"Tip: zfs set acltype=posixacl xattr=sa <pool>/<dataset> enables full ACL support.": "Suggerimento: zfs set acltype=posixacl xattr=sa <pool>/<dataset> abilita il supporto ACL completo.",
"Tmpfs size in MiB for": "Dimensione tmpfs in MiB per",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:": "Per aggiungere un modello, apri la console del container in Proxmox e scaricalo in /models, ad esempio:",
"To allow LXC write access, change the NFS export on the server to include:": "Per consentire l'accesso in scrittura LXC, modificare l'esportazione NFS sul server per includere:",
"To apply it to the current shell now, run:": "Per applicarlo ora alla shell corrente, eseguire:",
"To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.": "Per assegnare VF a VM o LXC, modificare manualmente la configurazione tramite l'interfaccia web Proxmox. La funzione fisica resterà associata al driver nativo.",
@@ -7621,6 +7660,7 @@
"Total routes": "Rotte totali",
"Total size:": "Dimensione totale:",
"Toxiproxy": "Toxiproxy",
"Track 3D printer filament spools and usage.": "monitora le bobine e l'utilizzo dei filamenti della stampante 3D.",
"Track movies, television, anime and games you want to enjoy.": "Tieni traccia di film, serie TV, anime e videogiochi che vuoi guardare o provare.",
"Track subscriptions and recurring expenses.": "Tieni traccia degli abbonamenti e delle spese ricorrenti.",
"Track your music listening history on your own server.": "Tieni traccia della cronologia di ascolto musicale sul tuo server.",
@@ -7855,6 +7895,7 @@
"Update the whole stack?": "Aggiornare l’intero stack?",
"Update, modify or recreate one installed OCI instance": "Aggiorna, modifica o ricrea un'istanza OCI installata",
"Updated": "Aggiornato",
"Updated recipes since your last visit: {count}": "Ricette aggiornate dalla tua ultima visita: {count}",
"Updated sharedfiles group to GID: 101000": "Gruppo sharedfiles aggiornato a GID: 101000",
"Updated stack checked": "Stack aggiornato verificato",
"Updated:": "Aggiornato:",
@@ -8060,6 +8101,7 @@
"Variables": "Variabili",
"Variables the installation asks for:": "Variabili richieste durante l’installazione:",
"Vaultwarden Web Vault": "Vaultwarden Web Vault",
"Vector illustration in your browser": "Illustrazione vettoriale nel browser",
"Vector search engine with a built-in dashboard.": "Motore di ricerca vettoriale con dashboard integrata.",
"Verbose pool status": "Stato pool dettagliato",
"Verification": "Verifica",
@@ -8090,6 +8132,7 @@
"Versions shown belong to maintained NVIDIA branches that list your GPU PCI ID and are new enough to build against the running kernel. DKMS compilation is the final validation. The recommended version keeps the current branch, or uses the NVIDIA Production Branch on a fresh install.": "Le versioni mostrate appartengono a rami NVIDIA mantenuti che elencano l’ID PCI della tua GPU e sono abbastanza recenti da poter essere compilate per il kernel in esecuzione. La compilazione DKMS costituisce la verifica finale. La versione consigliata mantiene il ramo corrente oppure, per una nuova installazione, utilizza NVIDIA Production Branch.",
"VictoriaLogs": "VictoriaLogs",
"Video acceleration and object detection are independent choices; the installer does not write camera or detector YAML.": "L'accelerazione video e il rilevamento degli oggetti sono scelte indipendenti; l'installer non scrive la configurazione YAML delle telecamere o dei rilevatori.",
"Video editing in your browser": "Montaggio video nel browser",
"Video transcoding acceleration": "Accelerazione transcodifica video",
"Video transcoding profile not implemented:": "Profilo transcodifica video non implementato:",
"View CIFS Mounts (pvesm + fstab)": "Visualizza montaggi CIFS (pvesm + fstab)",
@@ -8199,12 +8242,17 @@
"Web access": "Accesso web",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Indirizzo web dell'istanza AdGuard Home che riceve le impostazioni (ad es. http://192.168.1.3)",
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Indirizzo web dell'istanza AdGuard Home principale, da cui vengono copiate le impostazioni (ad es. http://192.168.1.2)",
"Web dashboard": "Dashboard web",
"Web dashboard and WebDAV": "Dashboard web e WebDAV",
"Web interface": "Interfaccia web",
"Web interface for Borg Backup repositories and jobs.": "Interfaccia web per repository e job di Borg Backup.",
"Web interface for managing 3D printers.": "Interfaccia web per gestire stampanti 3D.",
"Web interface to manage devices running Tasmota firmware.": "Interfaccia web per gestire dispositivi con firmware Tasmota.",
"Web reverse proxy with an administration interface.": "Proxy inverso web con interfaccia di amministrazione.",
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord comprende miglioramenti alla sicurezza e alla privacy, reimplementazioni di funzioni di Discord, soluzioni alternative ai bug di Electron, Chromium e Discord, fogli di stile, pagine interne e la pagina https://discord.com incapsulata. È progettato per rispettare i termini di servizio per quanto possibile (o nascondere a Discord le modifiche che potrebbero violarli).",
"WebDAV": "WebDAV",
"WebDAV and dashboard password (leave empty to generate)": "Password di WebDAV e della dashboard (campo vuoto = generata)",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV è disponibile sulla porta 8080 del container. Prima di operare sui file del cloud bisogna collegare l'account.",
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus acquisisce dati EPG XMLTV incrementalmente da più siti. Raccoglie le guide TV dai siti selezionati per i canali preferiti.",
"Webservers & Proxies": "Server web e proxy",
"Website": "Sito web",
@@ -8262,6 +8310,7 @@
"Without a usable reset path, passthrough reliability is poor and VM": "Senza un metodo di reset utilizzabile, l'affidabilità del passthrough è scarsa e per le VM",
"Wizard cancelled": "Procedura guidata annullata",
"Wolfenstein: Blade of Agony is a story-driven WWII shooter inspired by Wolfenstein and Doom.": "Wolfenstein: Blade of Agony è uno sparatutto ambientato nella seconda guerra mondiale e incentrato sulla storia, ispirato a Wolfenstein e Doom.",
"Word processing in your browser": "Elaborazione di testi nel browser",
"Workflow automation tool": "Strumento automazione flussi di lavoro",
"Working directory:": "Directory di lavoro:",
"Works with LVM, ZFS, and BTRFS storage types": "Funziona con storage LVM, ZFS e BTRFS",
@@ -8312,6 +8361,8 @@
"Your machine learning Env work with Jupyter Lab": "Ambiente machine learning con Jupyter Lab",
"Your next YouTube media manager": "Il tuo prossimo gestore di video YouTube",
"Your_spotify is a self-hosted application that tracks what you listen and offers you a dashboard to explore statistics about it! It's composed of a web server which polls the Spotify API every now and then and a web application on which you can explore your statistics.": "Your_spotify è un’applicazione self-hosted che traccia gli ascolti e offre una dashboard per consultarne le statistiche. Comprende un server web che interroga periodicamente l’API Spotify e un’applicazione web per esplorare le statistiche.",
"Z-Wave JS UI": "Z-Wave JS UI",
"Z-Wave JS UI admin login": "accesso amministratore Z-Wave JS UI",
"ZFS ARC config removed (kernel defaults will apply on reboot)": "Configurazione ZFS ARC rimossa (valori predefiniti del kernel applicati al riavvio)",
"ZFS ARC maximum configured:": "Limite massimo ZFS ARC configurato:",
"ZFS ARC optimization completed": "Ottimizzazione ZFS ARC completata",
@@ -8425,6 +8476,7 @@
"could not be compiled for kernel": "non è stato possibile compilarlo per il kernel",
"could not validate NVIDIA; exit code": "impossibile convalidare NVIDIA; codice di uscita",
"cpuunits must be between 8 and 10000": "cpuunits deve essere compreso tra 8 e 10000",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf": "curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"custom": "personalizzato",
"custom dependency commands are not yet supported": "i comandi di dipendenza personalizzati non sono ancora supportati",
"custom path(s) saved.": "percorsi personalizzati salvati.",
@@ -8631,6 +8683,7 @@
"kexec-tools is not installed or already removed.": "kexec-tools non è installato o è già stato rimosso.",
"layers": "layer",
"legacy .link file(s) to the ProxMenux-managed format": "file .link legacy nel formato gestito da ProxMenux",
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.": "llama.cpp mostra nella sua interfaccia web tutti i modelli GGUF salvati in /models e carica quello scelto.",
"log2ram completely removed from system": "log2ram completamente rimosso dal sistema",
"main container of the application": "container principale dell'applicazione",
"make cloned mount tree read-only": "impostazione in sola lettura dell'albero di mount clonato",
+53
View File
@@ -184,6 +184,7 @@
"A tunneling daemon by Cloudflare that safely exposes your web servers into the internet.": "Um daemon de túneis pela Cloudflare que expõe com segurança seus servidores web na internet.",
"A unified email and collaboration server.": "Um servidor unificado de e-mail e colaboração.",
"A unified platform for logs, metrics and traces.": "Uma plataforma unificada para logs, métricas e traces.",
"A validating, recursive DNS resolver for your private network.": "um resolvedor DNS recursivo e validador para sua rede privada.",
"A versatile file conversion tool that supports multiple formats.": "Uma ferramenta versátil de conversão de arquivos que suporta vários formatos.",
"A visual tool for exploring and documenting database schemas.": "Uma ferramenta visual para explorar e documentar esquemas de bases de dados.",
"A web GUI client of Project V which supports VMess, VLESS, SS, SSR, Trojan, Tuic and Juicity protocols": "Um cliente web GUI do Projeto V que suporta protocolos VMess, VLESS, SS, SS, SSR, Trojan, Tuic e Juicity",
@@ -256,6 +257,7 @@
"Acceleration for llama.cpp": "Aceleração para llama.cpp",
"Accept routes from other nodes?": "Aceita rotas de outros nós?",
"Accept this host monitoring profile?": "Aceita este perfil de monitorização da máquina?",
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Acesse a nuvem da Movistar e da O2 a partir de clientes WebDAV e ferramentas de backup.",
"Access Scope:": "Escopo de acesso:",
"Access bridge": "Ponte de acesso",
"Access bridge for Immich": "Ponte de acesso para Immich",
@@ -410,6 +412,7 @@
"After the reboot, you will only be able to access the Proxmox host via:": "Após a reinicialização, você só poderá acessar o host Proxmox via:",
"After this LXC → VM switch, reboot the host so the new binding state is applied cleanly.": "Após esta opção LXC → VM, reinicialize o host para que o novo estado de ligação seja aplicado de forma limpa.",
"Agentless monitoring and observability platform.": "Plataforma de monitoramento e observabilidade sem agentes.",
"AirDC++ administrator": "Administrador do AirDC++",
"Airsonic Advanced web interface": "Interface Web Airsonic Advanced",
"Airsonic-advanced is a free, web-based media streamer, providing ubiquitious access to your music. Use it to share your music with friends, or to listen to your own music while at work. You can stream to multiple players simultaneously, for instance to one player in your kitchen and another in your living room.": "Airsonic-avanced é uma transmissão de mídia gratuita, baseada na web, proporcionando ubiquitious acesso à sua música. Use-o para compartilhar sua música com amigos, ou para ouvir sua própria música durante o trabalho. Você pode transmitir para vários jogadores simultaneamente, por exemplo para um jogador na sua cozinha e outro na sua sala de estar.",
"Aliases added to .bashrc": "Aliases adicionados a .bashrc",
@@ -598,11 +601,15 @@
"Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Atenção: A remoção do banner de assinatura pode causar problemas na interface web após uma atualização futura.",
"Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity é um editor e gravador de áudio de várias faixas fácil de usar. Desenvolvido por um grupo de voluntários como código aberto.",
"Audio device directory": "Directório do dispositivo de áudio",
"Audio recording and mixing in your browser": "Gravação e mixagem de áudio no navegador",
"Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf é um servidor de áudio e podcast self-hosted.",
"Audit completed. Press Enter to continue...": "Auditoria concluída. Pressione Enter para continuar...",
"Audit socket disabled or not required": "soquete de auditoria desabilitado ou não necessário",
"Auth key is required.": "A chave de autenticação é obrigatória.",
"Auth:": "Autenticação:",
"Authelia Web UI": "UI da Web Authelia",
"Authelia administrator": "administrador Authelia",
"Authelia session cookie domain for this portal (for example example.com)": "domínio de cookie de sessão Authelia para este portal (por exemplo example.com)",
"Authentication": "Autenticação",
"Authentication & Security": "Autenticação e segurança",
"Authentication Error": "Erro de autenticação",
@@ -642,6 +649,7 @@
"Available PVE Version": "Versão PVE disponível",
"Available Shares:": "Ações disponíveis:",
"Available action": "Ação disponível",
"Available applications: {count}": "Aplicações disponíveis: {count}",
"Available archives:": "Arquivos disponíveis:",
"Available disks detected.": "Discos disponíveis detectados.",
"Available host backups:": "Backups de host disponíveis:",
@@ -873,6 +881,7 @@
"Cannot write the image archive to {storage}. Check storage access and mount status.": "Não é possível gravar o arquivo de imagem em {storage}. Verifique o acesso ao armazenamento e o status de montagem.",
"Capabilities cannot be kept and all dropped at the same time": "Capacidades não podem ser mantidas e todas retiradas ao mesmo tempo",
"Catalog options": "Opções do catálogo",
"Catalog refresh unavailable; using the local catalog.": "Não foi possível atualizar o catálogo; está a ser usada a cópia local.",
"Category": "Categoria",
"Caution: Maximum mode generates more heat.": "Cuidado: O modo máximo gera mais calor.",
"Central server for file and image backups.": "Servidor central para backups de arquivos e imagens.",
@@ -1159,6 +1168,7 @@
"Compressing": "Comprimindo",
"Compression": "Compressão",
"Compression Tools": "Ferramentas de compressão",
"Computer-aided design and drafting in your browser": "Projeto CAD e desenho técnico no navegador",
"Concise output of logical volumes": "Saída concisa de volumes lógicos",
"Concise output of physical volumes": "Saída concisa de volumes físicos",
"Concise output of volume groups": "Saída concisa de grupos de volumes",
@@ -1393,6 +1403,7 @@
"Controller + NVMe": "Controlador + NVMe",
"Controller + NVMe assignment will be written now and become active after host reboot.": "A atribuição de controlador + NVMe será gravada agora e se tornará ativa após a reinicialização do host.",
"Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.": "A passagem Controlador + NVMe requer tipo de máquina q35. Ignorando atribuição do controlador.",
"Controller path on the Proxmox host; prefer /dev/serial/by-id/...": "caminho do controlador no host Proxmox;prefira /dev/serial/by-id/...",
"Controller/NVMe Conflict Policy": "Política de Conflito Controlador/NVMe",
"Controller/NVMe already present in VM config": "Controlador/NVMe já presente na configuração da VM",
"Controller/NVMe already present in VM config (%s)": "Controlador/NVMe já presente na configuração da VM (%s)",
@@ -1927,6 +1938,7 @@
"Dgraph": "Dgraph",
"Diff: current system vs backup (--- system +++ backup)": "Diferença: sistema atual vs backup (--- backup do sistema +++)",
"Different host. Backup from:": "Anfitrião diferente. Backup de:",
"Direct Connect file sharing with a web interface": "Partilha de ficheiros Direct Connect com interface web",
"Direct conversion completed for container": "Conversão direta concluída para contêiner",
"Directory Exists": "O diretório existe",
"Directory Not Empty": "Diretório não vazio",
@@ -3340,6 +3352,7 @@
"Initial Stirling-PDF account": "Conta inicial do Stirling-PDF",
"Initial Tandoor administrator": "Administrador inicial Tandoor",
"Initial Umami administrator": "Administrador inicial do Umami",
"Initial Z-Wave JS UI admin password": "Senha de administrador inicial do Z-Wave JS UI",
"Initial administrator created:": "Administrador inicial criado:",
"Initial administrator user": "Utilizador de administrador inicial",
"Initializing Borg repository if needed...": "Inicializando o repositório Borg, se necessário...",
@@ -3525,6 +3538,7 @@
"Interface MTU": "Interface MTU",
"Interface Names (persistent)": "Nomes de Interface (persistente)",
"Interface Type": "Tipo de interface",
"Interface design and prototyping in your browser": "Design de interfaces e protótipos no navegador",
"Interface names will return to default systemd behavior.": "Os nomes das interfaces retornarão ao comportamento padrão do systemd.",
"Interface type:": "Tipo de interface:",
"Interfaces configured": "Interfaces configuradas",
@@ -3740,6 +3754,7 @@
"Jupyter Lab (token only)": "Laboratório Jupyter (apenas por token)",
"JupyterLab": "JupyterLab",
"JupyterLab access token": "Token de acesso do JupyterLab",
"KDE's twin-panel file manager in a browser-based desktop.": "Gerenciador de arquivos de painel duplo do KDE em uma área de trabalho baseada em navegador.",
"KDF:": "KDF:",
"KROMA": "KROMA",
"KVM MSR options added to /etc/modprobe.d/kvm.conf": "Opções KVM MSR adicionadas a /etc/modprobe.d/kvm.conf",
@@ -3787,12 +3802,14 @@
"KiCad - A Cross Platform and Open Source Electronics Design Automation Suite.": "KiCad - Uma plataforma cruzada e Open Source Electronics Design Automation Suite.",
"Kimai has no default account. Enter the container with: pct enter {main_vmid}": "O Kimai não tem uma conta predefinida. Aceda ao contentor com: pct enter {main_vmid}",
"Kimai is a professional grade time-tracking application, free and open-source.": "Kimai é um aplicativo de rastreamento de tempo profissional, gratuito e de código aberto.",
"KitchenOwl": "KitchenOwl",
"Kometa is a powerful tool designed to give you complete control over your media libraries. With Kometa, you can take your customization to the next level, with granular control over metadata, collections, overlays, and much more.": "Kometa é uma ferramenta poderosa projetada para lhe dar controle completo sobre suas bibliotecas de mídia. Com o Kometa, você pode levar sua personalização para o próximo nível, com controle granular sobre metadados, coleções, sobreposições e muito mais.",
"Kometa reads its configuration from /config/config.yml and the container only ships /config/config.yml.template. Copy the template to config.yml, fill in the required Plex and TMDb connections, then restart the container.": "Kometa lê a sua configuração a partir de /config/config.yml e o recipiente apenas navios /config/config.yml.template. Copie o modelo para config.yml, preencha o requi vermelho Plex e conexões TMDb, em seguida, reinicie o recipiente.",
"Komga is a media server for your comics, mangas, BDs, magazines and eBooks.": "Komga é um servidor de mídia para seus quadrinhos, mangás, BDs, revistas e eBooks.",
"Kopia Web UI": "Interface web do Kopia",
"Kopia Web UI login": "Acesso à interface web do Kopia",
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita é um programa de pintura livre e livre profissional. É feito por artistas que querem ver ferramentas de arte acessíveis para todos.",
"Krusader Web UI": "UI da Web Krusader",
"LAN access to the kept containers (stack configuration incomplete):": "Acesso LAN aos recipientes mantidos (configuração incompleta):",
"LAN address applied to the application URLs": "Endereço LAN aplicado aos URLs da aplicação",
"LLDAP": "LLDAP",
@@ -4020,6 +4037,7 @@
"Manage OCI stack": "Gerenciar a pilha OCI",
"Manage PBS encryption keyfile": "Gerenciar arquivo de chave de criptografia PBS",
"Manage Secure Gateway": "Gerenciar Secure Gateway",
"Manage a Z-Wave network from a web dashboard and WebSocket gateway.": "gerencie uma rede Z-Wave a partir de um painel da web e gateway WebSocket.",
"Manage and inspect VM disk images": "Gerenciar e inspecionar imagens de disco de VM",
"Manage custom backup paths": "Gerencie caminhos de backup personalizados",
"Manage custom paths (add / remove your folders)": "Gerencie caminhos personalizados (adicione/remova suas pastas)",
@@ -4029,6 +4047,7 @@
"Manage local backup target": "Gerenciar destino de backup local",
"Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Gerencie registros de imagens privadas.\nAs credenciais salvas permitem que ProxMenux acesse suas imagens privadas.",
"Manage registry accounts as root on the Proxmox node.": "Gerencie contas de registro como root no nó Proxmox.",
"Manage teams of AI agents from a web dashboard.": "Gerencie equipes de agentes de IA a partir de um painel web.",
"Managed disks must have backup enabled and a valid size": "Os discos gerenciados devem ter backup ativado e um tamanho válido",
"Managed public route include is missing": "Falta o ficheiro de configuração das rotas públicas geridas",
"Managed public route installation failed": "Não foi possível configurar as rotas públicas geridas",
@@ -4134,6 +4153,7 @@
"Monitoring": "Monitoramento",
"Monitoring & Analytics": "Monitorização e análise",
"Most common cause: the archive is corrupted (interrupted write, partial copy, or storage issue).": "Causa mais comum: o arquivo está corrompido (gravação interrompida, cópia parcial ou problema de armazenamento).",
"Motion graphics and compositing in your browser": "Animação gráfica e composição no navegador",
"Mount Added Successfully:": "Montagem adicionada com sucesso:",
"Mount CIFS share:": "Monte o compartilhamento CIFS:",
"Mount Configuration Summary:": "Resumo da configuração de montagem:",
@@ -4434,6 +4454,7 @@
"New Search": "Nova pesquisa",
"New VM:": "Nova VM:",
"New Virtual Machine": "Nova máquina virtual",
"New applications since your last visit: {count}": "Novas aplicações desde a sua última visita: {count}",
"New backup job": "Nova tarefa de backup",
"New backups on this host will be unencrypted until a new keyfile is set up.": "Novos backups neste host serão descriptografados até que um novo arquivo-chave seja configurado.",
"New image compatible:": "Nova imagem compatível:",
@@ -4896,6 +4917,8 @@
"Open the page of an application in the menu": "Abrir a página de uma aplicação no menu",
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Abra o endereço web e crie a primeira conta: o daemon regista-se sozinho e inicia a primeira análise.",
"Open the web address and create the password of the akadmin user in the first-run setup.": "Abra o endereço da web e crie a senha do usuário akadmin na configuração inicial.",
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured.": "Abra o endereço web e siga o onboarding do KitchenOwl para criar a primeira conta;nenhuma conta padrão está configurada.",
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Abra o painel web e vincule sua conta Movistar/O2 com a verificação por SMS.",
"Open-source AI-powered coding assistant": "Assistente de codificação com código aberto",
"Open-source UI for building and debugging multi-agent and RAG applications": "UI de código aberto para a construção e depuração de aplicações multi-agente e RAG",
"Open-source in-memory data store.": "Armazenamento de dados em memória de código aberto.",
@@ -5018,6 +5041,7 @@
"Packages:": "Pacotes:",
"Packaging OVA file...": "Empacotando arquivo OVA...",
"Packing installer archive...": "Empacotando o arquivo do instalador...",
"Page layout and publishing in your browser": "Diagramação e publicação no navegador",
"PairDrop is a sublime alternative to AirDrop that works on all platforms. Send images, documents or text via peer to peer connection to devices in the same local network/Wi-Fi or to paired devices.": "PairDrop é uma alternativa sublime para AirDrop que funciona em todas as plataformas. Envie imagens, documentos ou texto via peer para conexão por pares a dispositivos na mesma rede local/Wi-Fi ou para dispositivos pareados.",
"Paperless configuration cancelled": "Configuração sem papel cancelada",
"Paperless-ngx WebUI": "Paperless-ngx WebUI",
@@ -5036,6 +5060,7 @@
"Pass /dev/video12 to the LXC": "Passe /dev/video12 para o LXC",
"Pass a host device to the LXC": "Passe um dispositivo da máquina para o LXC",
"Pass the UPS to the LXC": "Passe o UPS para o LXC",
"Pass through a Z-Wave USB or serial controller": "passe por um controlador serial ou USB Z-Wave",
"Passing NVIDIA does not enable acceleration inside the application. The host needs NVIDIA Container Toolkit and a compatible image. Continue?": "Passar NVIDIA não habilita a aceleração dentro do aplicativo. O host precisa do NVIDIA Container Toolkit e de uma imagem compatível. Continuar?",
"Passkey-based identity provider for self-hosted apps.": "Fornecedor de identidade baseado em passkeys para aplicações autoalojadas.",
"Passphrase used to unlock the imported keyfile (leave blank if the keyfile is unencrypted / kdf=none):": "Senha usada para desbloquear o arquivo-chave importado (deixe em branco se o arquivo-chave não estiver criptografado / kdf=none):",
@@ -5143,6 +5168,8 @@
"Personal finance management application": "Aplicação de gestão de finanças pessoais",
"Personal media server for browsing and playing a local video library, with direct play and optional modules.": "Servidor multimídia pessoal para navegar e reproduzir uma biblioteca local de vídeos, com reprodução direta e módulos opcionais.",
"Photo and video library with optional GPU transcoding and machine learning": "Biblioteca de fotos e vídeos com transcodificação GPU opcional e aprendizado de máquina",
"Photo editing in your browser": "Edição de fotos no navegador",
"Photo library and RAW development in your browser": "Biblioteca de fotos e revelação RAW no navegador",
"PhotoPrism": "PhotoPrism",
"Photofield": "Photofield",
"Phpmyadmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB.": "Phpmyadmin é uma ferramenta de software livre escrita em PHP, destinada a lidar com a administração do MySQL através da Web. phpMyAdmin suporta uma ampla gama de operations no MySQL e MariaDB.",
@@ -5235,6 +5262,7 @@
"Preparing the machine learning container for the new choice...": "Preparando o contêiner de aprendizado de máquina para a nova escolha...",
"Preparing the recreation...": "Preparando a recreação...",
"Preparing the update...": "Preparando a atualização...",
"Presentations and slide decks in your browser": "Apresentações e slides no navegador",
"Preserving logs to /var/log.hdd before unmounting...": "Preservando logs em /var/log.hdd antes de desmontar...",
"Press 'q' to exit": "Pressione 'q' para sair",
"Press Ctrl+C to stop the server and return to menu.": "Pressione Ctrl+C para parar o servidor e retornar ao menu.",
@@ -5395,6 +5423,7 @@
"Proxmox web interface: Datacenter > Storage > Add > ZFS": "Interface web Proxmox: Datacenter > Armazenamento > Adicionar > ZFS",
"Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Interface web Proxmox: Datacenter > Armazenamento > Adicionar > iSCSI",
"Proxy address to reach the API (optional)": "Endereço proxy para acessar a API (opcional)",
"Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)": "URL HTTPS público usado para abrir este portal Authelia (por exemplo https://auth.example.com)",
"Public UDP port clients connect to": "Clientes públicos de porta UDP se conectam",
"Public UDP port peers connect to": "Os pares públicos de portas UDP se conectam",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "URL público do phpMyAdmin quando é servido por trás de um proxy reverso",
@@ -5455,6 +5484,7 @@
"Re-running pre-check after repairs...": "Executando novamente a pré-verificação após os reparos...",
"Reachable": "Acessível",
"Read an oci-compose from a file of this host": "Leia um oci-compose de um arquivo deste host",
"Read and edit PDF documents in your browser": "Leitura e edição de documentos PDF no navegador",
"Read its Compose file from a file of this host": "Leia seu arquivo Compor de um arquivo desta máquina",
"Read manga through a self-hosted server and web UI.": "Leia mangás em um servidor self-hosted com interface web.",
"Read the link with pct console CTID on the Proxmox host, or from the Console panel of the container in the Proxmox web interface, then open the https://playit.gg/claim/ address it shows in a browser and sign in to playit.gg. Ctrl+a q leaves pct console.": "Leia o link com o PCT console CTID no host Proxmox, ou a partir do painel Console do recipiente na interface web Proxmox, em seguida, abra o https://playit.gg/claim/ endereço que ele mostra em um navegador e entre para playit.gg. Ctrl+a q deixa o console pct.",
@@ -5560,6 +5590,7 @@
"Recursive and authoritative DNS server.": "Servidor DNS recursivo e autoritativo.",
"Redmine": "Redmine",
"Refresh APT index and verify repositories:": "Atualize o índice APT e verifique os repositórios:",
"Refresh catalog": "Atualizar catálogo",
"Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.": "Atualizar os índices dos repositórios APT configurados e rever a atualização de pacotes PBS? Os ficheiros dos repositórios serão preservados.",
"Refresh the index from the image sources": "Atualizar o índice a partir das origens de imagens",
"Refresh token of the connector, from the Twingate admin console": "Token de atualização do conector, no console administrativo Twingate",
@@ -5567,6 +5598,7 @@
"Refresh your browser to see changes (server restart may be required)": "Atualize seu navegador para ver as alterações (pode ser necessário reiniciar o servidor)",
"Refreshing apt cache...": "Atualizando o cache do apt...",
"Refreshing the NVIDIA runtime...": "Atualizando o tempo de execução NVIDIA...",
"Refreshing the application catalog...": "A atualizar o catálogo de aplicações...",
"Refusing an unexpected rootfs path:": "Recusando um caminho inesperado do rootfs:",
"Regenerate the catalog templates": "Regenerar os modelos do catálogo",
"Regenerate the template of one application": "Regenerar o modelo de uma aplicação",
@@ -6258,6 +6290,7 @@
"Self-hosted file sync and sharing.": "Sincronização e compartilhamento de arquivos self-hosted.",
"Self-hosted file toolkit for images, video, audio, PDFs, and files": "Kit de ferramentas de arquivo auto hospedado para imagens, vídeo, áudio, PDFs e arquivos",
"Self-hosted forms and workflows.": "Formulários e fluxos de trabalho autoalojados.",
"Self-hosted grocery list and recipe manager": "lista de compras auto-hospedada e gerenciador de receitas",
"Self-hosted household plant-care tracker with reminders, photos, and multiple user accounts.": "Gerenciador auto-hospedado de cuidados com plantas domésticas, com lembretes, fotos e várias contas de usuário.",
"Self-hosted image-hosting service with authenticated uploads, image processing, public links, and local storage.": "Serviço auto-hospedado de hospedagem de imagens, com uploads autenticados, processamento de imagens, links públicos e armazenamento local.",
"Self-hosted internet archiving solution": "Solução de arquivamento de internet self-hosted",
@@ -6452,6 +6485,7 @@
"Simple and easy to use DDNS": "Simples e fácil de usar DDNS",
"Simple self-hosted file sharing.": "Serviço simples e autoalojado para partilha de ficheiros.",
"Single GPU Warning": "Aviso de GPU única",
"Single sign-on and multi-factor authentication": "login único e autenticação multifator",
"Single target found — selected automatically:": "Único alvo encontrado — selecionado automaticamente:",
"Single-node log storage and query UI.": "Armazenamento de logs para um único nó com interface de consulta.",
"Single-node observability database for metrics, logs and traces.": "Banco de dados de observabilidade de nó único para métricas, logs e traces.",
@@ -6520,7 +6554,9 @@
"Specific subnet (enter manually)": "Sub-rede específica (inserir manualmente)",
"Speedtest Tracker web interface": "Interface Web Speedtest Tracker",
"Speedtest-tracker is a self-hosted internet performance tracking application that runs speedtest checks against Ookla's Speedtest service.": "Speedtest-tracker é um aplicativo de rastreamento de desempenho da internet que executa verificações de velocidade contra o serviço Speedtest da Ookla.",
"Spoolman web interface": "interface web Spoolman",
"Spotube is an open source, cross-platform Spotify client compatible across multiple platforms utilizing Spotify's data API and YouTube, Piped.video or JioSaavn as an audio source, eliminating the need for Spotify Premium": "Spotube é um cliente Spotify de código aberto, multi-plataforma compatível em várias plataformas utilizando a API de dados do Spotify e YouTube, Piped. vídeo ou JioSaavn como uma fonte de áudio, eliminando a necessidade de Spotify Premium",
"Spreadsheets in your browser": "Planilhas no navegador",
"Sshwifty": "Sshwifty",
"Sshwifty web access (password only)": "Acesso web ao Sshwifty (somente com senha)",
"Stable (main branch)": "Estável (ramo principal)",
@@ -7417,6 +7453,7 @@
"Then bind-mount to container": "Em seguida, ligue a montagem ao contêiner",
"Then change the VM display to none (vga: none) when the guest is stable.": "Em seguida, altere a exibição da VM para nenhum (vga: nenhum) quando o convidado estiver estável.",
"Then change the VM display to none (vga: none) when the system is stable.": "Em seguida, altere a exibição da VM para nenhum (vga: nenhum) quando o sistema estiver estável.",
"Then restart the container so the new model appears in the list.": "Depois reinicie o contêiner para que o novo modelo apareça na lista.",
"Then run this option again:": "Em seguida, execute esta opção novamente:",
"Then update /etc/fstab on the host with the same options.": "Em seguida, atualize /etc/fstab no host com as mesmas opções.",
"There are extra disks or bind mounts outside the journal; the rootfs is not replaced": "Existem discos extras ou montagens de ligação fora do diário; o rootfs não é substituído",
@@ -7464,6 +7501,7 @@
"This container does not have apt-get. NFS client installation only supports Debian/Ubuntu containers.": "Este contêiner não possui o apt-get. A instalação do cliente NFS suporta apenas contêineres Debian/Ubuntu.",
"This container does not have apt-get. Samba client installation only supports Debian/Ubuntu containers.": "Este contêiner não possui o apt-get. A instalação do cliente Samba suporta apenas contêineres Debian/Ubuntu.",
"This container has no GPU configured. Coral TPU works best alongside hardware video decoding (Quick Sync, VA-API, NVENC) for apps like Frigate.": "Este contêiner não tem GPU configurada. Coral TPU funciona melhor com decodificação de vídeo de hardware (Quick Sync, VA-API, NVENC) para aplicativos como Frigate.",
"This container is managed by high availability. Remove ct:{vmid} from HA (Datacenter → HA, or ha-manager remove ct:{vmid}), repeat the operation and add it back to HA with the same settings.": "Este contentor é gerido pela alta disponibilidade. Remova ct:{vmid} da HA (Datacenter → HA, ou ha-manager remove ct:{vmid}), repita a operação e volte a adicioná-lo à HA com as mesmas definições.",
"This container is not a member of a multi-container application": "Este contêiner não é membro de um aplicativo de vários contêineres",
"This container is not a registered OCI instance.": "Este contêiner não é uma instância OCI registrada.",
"This container was restored or came back from another host after its record on this host was written. Open this menu again to recover it; nothing was changed.": "Este contêiner foi restaurado ou voltou de outro host depois que seu registro neste host foi gravado. Abra este menu novamente para recuperá-lo; nada foi alterado.",
@@ -7582,6 +7620,7 @@
"Tip: You can install the QEMU Guest Agent inside the VM with:": "Dica: você pode instalar o agente convidado QEMU dentro da VM com:",
"Tip: zfs set acltype=posixacl xattr=sa <pool>/<dataset> enables full ACL support.": "Dica: zfs set acltype=posixacl xattr=sa <pool>/<dataset> permite suporte completo a ACL.",
"Tmpfs size in MiB for": "Tamanho do Tmpfs em MiB para",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:": "Para adicionar um modelo, abra o console do contêiner no Proxmox e baixe-o em /models, por exemplo:",
"To allow LXC write access, change the NFS export on the server to include:": "Para permitir o acesso de gravação LXC, altere a exportação NFS no servidor para incluir:",
"To apply it to the current shell now, run:": "Para aplicá-lo agora à sessão shell atual, execute:",
"To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.": "Para atribuir VFs a VMs ou LXCs, edite a configuração manualmente por meio da interface web do Proxmox. A Função Física permanecerá vinculada ao driver nativo.",
@@ -7621,6 +7660,7 @@
"Total routes": "Rotas totais",
"Total size:": "Tamanho total:",
"Toxiproxy": "Toxiproxy",
"Track 3D printer filament spools and usage.": "rastreie os carretéis e o uso do filamento da impressora 3D.",
"Track movies, television, anime and games you want to enjoy.": "Acompanhe os filmes, séries, anime e videojogos que quer ver ou jogar.",
"Track subscriptions and recurring expenses.": "Acompanhe subscrições e despesas recorrentes.",
"Track your music listening history on your own server.": "Acompanhe seu histórico de músicas ouvidas no seu próprio servidor.",
@@ -7855,6 +7895,7 @@
"Update the whole stack?": "Atualizar toda a pilha?",
"Update, modify or recreate one installed OCI instance": "Atualizar, modificar ou recriar uma instância OCI instalada",
"Updated": "Atualizado",
"Updated recipes since your last visit: {count}": "Receitas atualizadas desde a sua última visita: {count}",
"Updated sharedfiles group to GID: 101000": "Grupo de arquivos compartilhados atualizado para GID: 101000",
"Updated stack checked": "Stack atualizado verificado",
"Updated:": "Actualizado:",
@@ -8060,6 +8101,7 @@
"Variables": "Variáveis",
"Variables the installation asks for:": "Variáveis que a instalação solicita:",
"Vaultwarden Web Vault": "Vaultwarden Web Vault",
"Vector illustration in your browser": "Ilustração vetorial no navegador",
"Vector search engine with a built-in dashboard.": "Mecanismo de busca vetorial com painel integrado.",
"Verbose pool status": "Status detalhado do pool",
"Verification": "Verificação",
@@ -8090,6 +8132,7 @@
"Versions shown belong to maintained NVIDIA branches that list your GPU PCI ID and are new enough to build against the running kernel. DKMS compilation is the final validation. The recommended version keeps the current branch, or uses the NVIDIA Production Branch on a fresh install.": "As versões mostradas pertencem a ramificações NVIDIA mantidas que listam seu ID PCI da GPU e são novas o suficiente para serem construídas no kernel em execução. A compilação DKMS é a validação final. A versão recomendada mantém a ramificação atual ou usa a ramificação de produção NVIDIA em uma nova instalação.",
"VictoriaLogs": "VictoriaLogs",
"Video acceleration and object detection are independent choices; the installer does not write camera or detector YAML.": "Aceleração de vídeo e detecção de objetos são escolhas independentes; o instalador não grava câmera ou detector YAML.",
"Video editing in your browser": "Edição de vídeo no navegador",
"Video transcoding acceleration": "Aceleração da transcodificação de vídeo",
"Video transcoding profile not implemented:": "Perfil de transcodificação de vídeo não implementado:",
"View CIFS Mounts (pvesm + fstab)": "Ver montagens CIFS (pvesm + fstab)",
@@ -8199,12 +8242,17 @@
"Web access": "Acesso à Internet",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Endereço Web do AdGuard Home que recebe as definições (por exemplo, http://192.168.1.3)",
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Endereço Web do AdGuard Home principal, cujas configurações são copiadas (por exemplo, http://192.168.1.2)",
"Web dashboard": "Painel web",
"Web dashboard and WebDAV": "Painel web e WebDAV",
"Web interface": "Interface da Web",
"Web interface for Borg Backup repositories and jobs.": "Interface web para gerenciar repositórios e tarefas do Borg Backup.",
"Web interface for managing 3D printers.": "Interface web para gerenciar impressoras 3D.",
"Web interface to manage devices running Tasmota firmware.": "Interface Web para gerenciar dispositivos rodando firmware Tasmota.",
"Web reverse proxy with an administration interface.": "Proxy reverso web com interface de administração.",
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord pode ser resumido como um pacote de endurecimentos de segurança e privacidade, recursos de discórdia reimplementações, Electron / Chromium / Erros de discórdia workarounds, stylesheets, páginas internas e página envolto https://discord.com, projetado para se conformar com ToS tanto quanto possível (ou ocultar as alterações que podem violá-lo dos olhos da Discord).",
"WebDAV": "WebDAV",
"WebDAV and dashboard password (leave empty to generate)": "Senha do WebDAV e do painel (vazio = gerada)",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "O WebDAV está disponível na porta 8080 do contêiner. É preciso vincular a conta antes de operar com os arquivos da nuvem.",
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus é um multi-site incremental xmltv epg grabber. Ele coleta dados de guias de tv-programa de sites selecionados para seus canais favoritos.",
"Webservers & Proxies": "Servidores web e proxies",
"Website": "Site",
@@ -8262,6 +8310,7 @@
"Without a usable reset path, passthrough reliability is poor and VM": "Sem um caminho de redefinição utilizável, a confiabilidade da passagem é baixa e a VM",
"Wizard cancelled": "Assistente cancelado",
"Wolfenstein: Blade of Agony is a story-driven WWII shooter inspired by Wolfenstein and Doom.": "Wolfenstein: Blade of Agony é um atirador inspirado em Wolfenstein e Doom.",
"Word processing in your browser": "Processamento de texto no navegador",
"Workflow automation tool": "Ferramenta de automação de fluxo de trabalho",
"Working directory:": "Diretório de trabalho:",
"Works with LVM, ZFS, and BTRFS storage types": "Funciona com tipos de armazenamento LVM, ZFS e BTRFS",
@@ -8312,6 +8361,8 @@
"Your machine learning Env work with Jupyter Lab": "O seu Env de aprendizagem de máquina trabalha com o Jupyter Lab",
"Your next YouTube media manager": "Seu próximo gerenciador de mídia do YouTube",
"Your_spotify is a self-hosted application that tracks what you listen and offers you a dashboard to explore statistics about it! It's composed of a web server which polls the Spotify API every now and then and a web application on which you can explore your statistics.": "Your_spotify é uma aplicação auto-anfitriã que rastreia o que você ouve e oferece um painel para explorar estatísticas sobre isso! É composto por um servidor web que pesquisa a API do Spotify de vez em quando e uma aplicação web na qual você pode explorar suas estatísticas.",
"Z-Wave JS UI": "Z-Wave JS UI",
"Z-Wave JS UI admin login": "login de administrador Z-Wave JS UI",
"ZFS ARC config removed (kernel defaults will apply on reboot)": "Configuração do ZFS ARC removida (os padrões do kernel serão aplicados na reinicialização)",
"ZFS ARC maximum configured:": "máximo do ZFS ARC configurado:",
"ZFS ARC optimization completed": "Otimização ZFS ARC concluída",
@@ -8425,6 +8476,7 @@
"could not be compiled for kernel": "não foi possível compilar para o kernel",
"could not validate NVIDIA; exit code": "não foi possível validar o NVIDIA; código de saída",
"cpuunits must be between 8 and 10000": "cpuunidades devem estar entre 8 e 10000",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf": "curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"custom": "personalizado",
"custom dependency commands are not yet supported": "comandos de dependência personalizados ainda não são suportados",
"custom path(s) saved.": "caminhos personalizados salvos.",
@@ -8631,6 +8683,7 @@
"kexec-tools is not installed or already removed.": "kexec-tools não está instalado ou já foi removido.",
"layers": "camadas",
"legacy .link file(s) to the ProxMenux-managed format": "arquivo(s) .link herdado(s) para o formato gerenciado pelo ProxMenux",
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.": "O llama.cpp mostra na sua interface web todos os modelos GGUF salvos em /models e carrega o que você escolher.",
"log2ram completely removed from system": "log2ram completamente removido do sistema",
"main container of the application": "contentor principal da aplicação",
"make cloned mount tree read-only": "tornar só de leitura a árvore de montagem clonada",
+53
View File
@@ -184,6 +184,7 @@
"A tunneling daemon by Cloudflare that safely exposes your web servers into the internet.": "Tunelový démon Cloudflare, ktorý bezpečne vystavuje vaše webové servery na internet.",
"A unified email and collaboration server.": "Jednotný server na e-mail a spoluprácu.",
"A unified platform for logs, metrics and traces.": "Jednotná platforma pre logy, metriky a trasovanie.",
"A validating, recursive DNS resolver for your private network.": "Validujúci rekurzívny DNS resolver pre vašu súkromnú sieť.",
"A versatile file conversion tool that supports multiple formats.": "Univerzálny nástroj na konverziu súborov, ktorý podporuje viacero formátov.",
"A visual tool for exploring and documenting database schemas.": "Vizuálny nástroj na skúmanie a dokumentovanie schém databáz.",
"A web GUI client of Project V which supports VMess, VLESS, SS, SSR, Trojan, Tuic and Juicity protocols": "Webový GUI klient projektu V, ktorý podporuje protokoly VMess, VLESS, SS, SSR, Trojan, Tuic a Juicity",
@@ -256,6 +257,7 @@
"Acceleration for llama.cpp": "Zrýchlenie pre llama.cpp",
"Accept routes from other nodes?": "Prijímať trasy z iných uzlov?",
"Accept this host monitoring profile?": "Prijať tento profil monitorovania hostiteľa?",
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Prístup ku cloudu Movistar a O2 z klientov WebDAV a nástrojov na zálohovanie.",
"Access Scope:": "Rozsah prístupu:",
"Access bridge": "Sieťový most (bridge)",
"Access bridge for Immich": "Sieťový most (bridge) pre Immich",
@@ -410,6 +412,7 @@
"After the reboot, you will only be able to access the Proxmox host via:": "Po reštarte sa k Proxmox hostovi dostanete iba cez:",
"After this LXC → VM switch, reboot the host so the new binding state is applied cleanly.": "Po tomto prepnutí LXC → VM reštartujte host, aby sa nové naviazanie použilo čisto.",
"Agentless monitoring and observability platform.": "Platforma na monitorovanie a observabilitu bez klientskych agentov.",
"AirDC++ administrator": "Správca AirDC++",
"Airsonic Advanced web interface": "Webové rozhranie Airsonic Advanced",
"Airsonic-advanced is a free, web-based media streamer, providing ubiquitious access to your music. Use it to share your music with friends, or to listen to your own music while at work. You can stream to multiple players simultaneously, for instance to one player in your kitchen and another in your living room.": "Airsonic-advanced je bezplatný webový server na streamovanie hudby. Umožňuje zdieľať hudbu s priateľmi alebo počúvať vlastnú zbierku aj v práci. Podporuje súčasné prehrávanie na viacerých zariadeniach, napríklad v kuchyni a obývačke.",
"Aliases added to .bashrc": "Aliasy boli pridané do .bashrc",
@@ -598,11 +601,15 @@
"Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Upozornenie: odstránenie hlásenia o predplatnom môže po budúcej aktualizácii spôsobiť problém vo webovom rozhraní.",
"Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity je jednoduchý viacstopový zvukový editor a rekordér, ktorý dobrovoľníci vyvíjajú ako softvér s otvoreným zdrojovým kódom.",
"Audio device directory": "Adresár zvukových zariadení",
"Audio recording and mixing in your browser": "Nahrávanie a mixovanie zvuku v prehliadači",
"Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf je server na audioknihy a podcasty, ktorý prevádzkujete sami.",
"Audit completed. Press Enter to continue...": "Audit dokončený. Pokračujte stlačením Enter...",
"Audit socket disabled or not required": "Zásuvka auditu je zakázaná alebo sa nevyžaduje",
"Auth key is required.": "Auth key je povinný.",
"Auth:": "Prihlásenie:",
"Authelia Web UI": "Webové rozhranie Authelia",
"Authelia administrator": "Správca Authelia",
"Authelia session cookie domain for this portal (for example example.com)": "Doména súboru cookie relácie Authelia pre tento portál (napríklad example.com)",
"Authentication": "Prihlásenie",
"Authentication & Security": "Overovanie a zabezpečenie",
"Authentication Error": "Chyba prihlásenia",
@@ -642,6 +649,7 @@
"Available PVE Version": "Dostupná verzia PVE",
"Available Shares:": "Dostupné zdieľania:",
"Available action": "Dostupná akcia",
"Available applications: {count}": "Dostupné aplikácie: {count}",
"Available archives:": "Dostupné archívy:",
"Available disks detected.": "Dostupné disky boli nájdené.",
"Available host backups:": "Dostupné zálohy hosta:",
@@ -873,6 +881,7 @@
"Cannot write the image archive to {storage}. Check storage access and mount status.": "Archív obrazu sa nedá zapísať do úložiska {storage}. Skontrolujte prístup k úložisku a stav jeho pripojenia.",
"Capabilities cannot be kept and all dropped at the same time": "Oprávnenia capabilities nemožno súčasne ponechať aj všetky odobrať",
"Catalog options": "Možnosti katalógu",
"Catalog refresh unavailable; using the local catalog.": "Katalóg sa nepodarilo aktualizovať; používa sa miestna kópia.",
"Category": "Kategória",
"Caution: Maximum mode generates more heat.": "Pozor: maximálny režim vytvára viac tepla.",
"Central server for file and image backups.": "Centrálny server na zálohovanie súborov a obrazov.",
@@ -1159,6 +1168,7 @@
"Compressing": "Komprimujem",
"Compression": "Kompresia",
"Compression Tools": "Kompresné nástroje",
"Computer-aided design and drafting in your browser": "Počítačom podporované navrhovanie a technické kreslenie v prehliadači",
"Concise output of logical volumes": "Stručný výpis logických zväzkov",
"Concise output of physical volumes": "Stručný výpis fyzických zväzkov",
"Concise output of volume groups": "Stručný výpis skupín zväzkov",
@@ -1393,6 +1403,7 @@
"Controller + NVMe": "Controller + NVMe",
"Controller + NVMe assignment will be written now and become active after host reboot.": "Priradenie Controller + NVMe sa teraz zapíše a aktivuje sa po reštarte servera.",
"Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.": "Priame priradenie Controller + NVMe vyžaduje typ stroja q35. Priradenie controllera sa preskočí.",
"Controller path on the Proxmox host; prefer /dev/serial/by-id/...": "Cesta ku kontroléru na hostiteľovi Proxmox; uprednostnite /dev/serial/by-id/...",
"Controller/NVMe Conflict Policy": "Riešenie konfliktu Controller/NVMe",
"Controller/NVMe already present in VM config": "Controller/NVMe už je v nastavení VM",
"Controller/NVMe already present in VM config (%s)": "Radič/NVMe už je v nastaveniach VM (%s)",
@@ -1927,6 +1938,7 @@
"Dgraph": "Dgraph",
"Diff: current system vs backup (--- system +++ backup)": "Rozdiel: aktuálny systém vs záloha (--- systém +++ záloha)",
"Different host. Backup from:": "Iný host. Záloha z:",
"Direct Connect file sharing with a web interface": "Zdieľanie súborov cez Direct Connect s webovým rozhraním",
"Direct conversion completed for container": "Priama konverzia bola dokončená pre kontajner",
"Directory Exists": "Priečinok už existuje",
"Directory Not Empty": "Priečinok nie je prázdny",
@@ -3339,6 +3351,7 @@
"Initial Stirling-PDF account": "Počiatočný účet Stirling-PDF",
"Initial Tandoor administrator": "Počiatočný správca Tandoor",
"Initial Umami administrator": "Počiatočný správca Umami",
"Initial Z-Wave JS UI admin password": "Počiatočné heslo správcu Z-Wave JS UI",
"Initial administrator account": "Úvodný účet správcu",
"Initial administrator created:": "Pôvodný správca vytvorený:",
"Initial administrator user": "Počiatočné používateľské meno správcu",
@@ -3525,6 +3538,7 @@
"Interface MTU": "MTU rozhrania",
"Interface Names (persistent)": "Trvalé názvy rozhraní",
"Interface Type": "Typ rozhrania",
"Interface design and prototyping in your browser": "Návrh rozhraní a prototypov v prehliadači",
"Interface names will return to default systemd behavior.": "Názvy rozhraní sa vrátia k predvolenému správaniu systemd.",
"Interface type:": "Typ rozhrania:",
"Interfaces configured": "Nastavené rozhrania",
@@ -3740,6 +3754,7 @@
"Jupyter Lab (token only)": "Jupyter Lab (iba token)",
"JupyterLab": "JupyterLab",
"JupyterLab access token": "Prístupový token JupyterLab",
"KDE's twin-panel file manager in a browser-based desktop.": "Dvojpanelový správca súborov KDE v pracovnej ploche dostupnej cez webový prehliadač.",
"KDF:": "KDF:",
"KROMA": "KROMA",
"KVM MSR options added to /etc/modprobe.d/kvm.conf": "Možnosti KVM MSR boli pridané do /etc/modprobe.d/kvm.conf",
@@ -3787,12 +3802,14 @@
"KiCad - A Cross Platform and Open Source Electronics Design Automation Suite.": "KiCad – multiplatformový balík s otvoreným zdrojovým kódom na návrh elektroniky.",
"Kimai has no default account. Enter the container with: pct enter {main_vmid}": "Kimai nemá predvolený účet. Do kontajnera vstúpite príkazom: pct enter {main_vmid}",
"Kimai is a professional grade time-tracking application, free and open-source.": "Kimai je profesionálna bezplatná aplikácia na sledovanie pracovného času s otvoreným zdrojovým kódom.",
"KitchenOwl": "KitchenOwl",
"Kometa is a powerful tool designed to give you complete control over your media libraries. With Kometa, you can take your customization to the next level, with granular control over metadata, collections, overlays, and much more.": "Kometa poskytuje podrobnú kontrolu nad mediálnymi knižnicami. Umožňuje prispôsobiť metadáta, kolekcie, grafické prekrytia a ďalšie prvky.",
"Kometa reads its configuration from /config/config.yml and the container only ships /config/config.yml.template. Copy the template to config.yml, fill in the required Plex and TMDb connections, then restart the container.": "Kometa číta nastavenia z /config/config.yml, kontajner však obsahuje iba /config/config.yml.template. Skopírujte šablónu do config.yml, vyplňte požadované pripojenia Plex a TMDb a kontajner reštartujte.",
"Komga is a media server for your comics, mangas, BDs, magazines and eBooks.": "Komga je mediálny server na komiksy, mangu, grafické romány, časopisy a elektronické knihy.",
"Kopia Web UI": "Webové rozhranie Kopia",
"Kopia Web UI login": "Prihlásenie do webového rozhrania Kopia",
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita je profesionálny bezplatný maliarsky program s otvoreným zdrojovým kódom. Vytvárajú ho umelci, ktorí chcú sprístupniť umelecké nástroje každému.",
"Krusader Web UI": "Webové rozhranie Krusaderu",
"LAN access to the kept containers (stack configuration incomplete):": "Prístup z LAN k ponechaným kontajnerom (nastavenie zostavy nie je dokončené):",
"LAN address applied to the application URLs": "LAN adresa použitá na URL aplikácie",
"LLDAP": "LLDAP",
@@ -4020,6 +4037,7 @@
"Manage OCI stack": "Spravovať aplikáciu s viacerými kontajnermi",
"Manage PBS encryption keyfile": "Spravovať šifrovací keyfile pre PBS",
"Manage Secure Gateway": "Spravovať Secure Gateway",
"Manage a Z-Wave network from a web dashboard and WebSocket gateway.": "Spravujte sieť Z-Wave cez webový panel a bránu WebSocket.",
"Manage and inspect VM disk images": "Spravovať a kontrolovať diskové obrazy VM",
"Manage custom backup paths": "Spravovať vlastné cesty zálohy",
"Manage custom paths (add / remove your folders)": "Spravovať vlastné cesty (pridať / odstrániť priečinky)",
@@ -4029,6 +4047,7 @@
"Manage local backup target": "Spravovať lokálny cieľ záloh",
"Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Správa súkromných registrov obrazov.\nUložené prihlasovacie údaje umožňujú ProxMenuxu pristupovať k vašim súkromným obrazom.",
"Manage registry accounts as root on the Proxmox node.": "Spravujte účty registra ako root na uzle Proxmox.",
"Manage teams of AI agents from a web dashboard.": "Spravujte tímy AI agentov z webového panela.",
"Managed disks must have backup enabled and a valid size": "Spravované disky musia mať zapnuté zálohovanie a platnú veľkosť",
"Managed public route include is missing": "Chýba konfiguračný súbor spravovaných verejných trás",
"Managed public route installation failed": "Nepodarilo sa nastaviť spravované verejné trasy",
@@ -4134,6 +4153,7 @@
"Monitoring": "Monitorovanie",
"Monitoring & Analytics": "Monitorovanie a analýza",
"Most common cause: the archive is corrupted (interrupted write, partial copy, or storage issue).": "Najčastejšia príčina: archív je poškodený (prerušený zápis, neúplná kópia alebo problém s úložiskom).",
"Motion graphics and compositing in your browser": "Animovaná grafika a kompoziting v prehliadači",
"Mount Added Successfully:": "Mount bol úspešne pridaný:",
"Mount CIFS share:": "Pripojiť CIFS zdieľanie:",
"Mount Configuration Summary:": "Zhrnutie nastavenia mountu:",
@@ -4434,6 +4454,7 @@
"New Search": "Nové hľadanie",
"New VM:": "Nová VM:",
"New Virtual Machine": "Nová virtuálna mašina",
"New applications since your last visit: {count}": "Nové aplikácie od vašej poslednej návštevy: {count}",
"New backup job": "Nová úloha zálohy",
"New backups on this host will be unencrypted until a new keyfile is set up.": "Nové zálohy na tomto hostovi budú nešifrované, kým nenastavíte nový keyfile.",
"New image compatible:": "Nový obraz je kompatibilný:",
@@ -4898,6 +4919,8 @@
"Open the page of an application in the menu": "Otvoriť stránku aplikácie v ponuke",
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Otvorte webovú adresu a vytvorte prvé konto: daemon sa zaregistruje sám a spustí prvé skenovanie.",
"Open the web address and create the password of the akadmin user in the first-run setup.": "Otvorte webovú adresu a v prvotnom nastavení vytvorte heslo používateľa akadmin.",
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured.": "Otvorte webovú adresu a podľa pokynov KitchenOwl vytvorte prvý účet; predvolený účet nie je nastavený.",
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Otvorte webový panel a prepojte svoj účet Movistar/O2 pomocou overenia cez SMS.",
"Open-source AI-powered coding assistant": "Programátorský asistent využívajúci AI s otvoreným zdrojovým kódom",
"Open-source UI for building and debugging multi-agent and RAG applications": "Rozhranie s otvoreným zdrojovým kódom na tvorbu a ladenie aplikácií s viacerými agentmi a RAG",
"Open-source in-memory data store.": "Úložisko údajov v pamäti s otvoreným zdrojovým kódom.",
@@ -5020,6 +5043,7 @@
"Packages:": "Balíky:",
"Packaging OVA file...": "Balím OVA súbor...",
"Packing installer archive...": "Balím archív inštalátora...",
"Page layout and publishing in your browser": "Zalomenie strán a publikovanie v prehliadači",
"PairDrop is a sublime alternative to AirDrop that works on all platforms. Send images, documents or text via peer to peer connection to devices in the same local network/Wi-Fi or to paired devices.": "PairDrop je skvelá alternatíva k AirDrop, ktorá pracuje na všetkých platformách. Poslať obrázky, dokumenty alebo text prostredníctvom peer-to-peer pripojenie k zariadeniam v rovnakej miestnej sieti/Wi-Fi alebo spárované zariadenia.",
"Paperless configuration cancelled": "Nastavenie Paperless bolo zrušené",
"Paperless-ngx WebUI": "Paperless-ngx WebUI",
@@ -5038,6 +5062,7 @@
"Pass /dev/video12 to the LXC": "Sprístupniť /dev/video12 kontajneru LXC",
"Pass a host device to the LXC": "Sprístupniť zariadenie hostiteľa kontajneru LXC",
"Pass the UPS to the LXC": "Sprístupniť UPS kontajneru LXC",
"Pass through a Z-Wave USB or serial controller": "Pripojiť USB alebo sériový radič Z-Wave",
"Passing NVIDIA does not enable acceleration inside the application. The host needs NVIDIA Container Toolkit and a compatible image. Continue?": "Prejdenie NVIDIA neumožní zrýchlenie v aplikácii. Hostiteľ potrebuje NVIDIA Container Toolkit a kompatibilný obrázok. Pokračovať?",
"Passkey-based identity provider for self-hosted apps.": "Poskytovateľ identity založený na passkeys pre samohostované aplikácie.",
"Passphrase used to unlock the imported keyfile (leave blank if the keyfile is unencrypted / kdf=none):": "Fráza na odomknutie importovaného keyfile (nechajte prázdne, ak keyfile nie je šifrovaný / kdf=none):",
@@ -5145,6 +5170,8 @@
"Personal finance management application": "Aplikácia na správu osobných financií",
"Personal media server for browsing and playing a local video library, with direct play and optional modules.": "Osobný mediálny server na prehliadanie a prehrávanie miestnej videoknižnice s priamym prehrávaním a voliteľnými modulmi.",
"Photo and video library with optional GPU transcoding and machine learning": "Knižnica fotografií a videí s voliteľným prevodom videa pomocou GPU a strojovým učením",
"Photo editing in your browser": "Úprava fotografií v prehliadači",
"Photo library and RAW development in your browser": "Fotoknižnica a vyvolávanie RAW v prehliadači",
"PhotoPrism": "PhotoPrism",
"Photofield": "Photofield",
"Phpmyadmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB.": "phpMyAdmin je bezplatný nástroj napísaný v PHP na správu MySQL cez web. Podporuje širokú škálu operácií nad MySQL a MariaDB.",
@@ -5237,6 +5264,7 @@
"Preparing the machine learning container for the new choice...": "Príprava kontajnera strojového učenia pre novú voľbu...",
"Preparing the recreation...": "Príprava rekreácie...",
"Preparing the update...": "Príprava aktualizácie...",
"Presentations and slide decks in your browser": "Prezentácie a snímky v prehliadači",
"Preserving logs to /var/log.hdd before unmounting...": "Pred odpojením zachovávam logy do /var/log.hdd...",
"Press 'q' to exit": "Stlačte 'q' na ukončenie",
"Press Ctrl+C to stop the server and return to menu.": "Server zastavíte stlačením Ctrl+C a vrátite sa do menu.",
@@ -5397,6 +5425,7 @@
"Proxmox web interface: Datacenter > Storage > Add > ZFS": "Webové rozhranie Proxmoxu: Datacenter > Storage > Add > ZFS",
"Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Webové rozhranie Proxmoxu: Datacenter > Storage > Add > iSCSI",
"Proxy address to reach the API (optional)": "Adresa proxy na prístup k API (voliteľné)",
"Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)": "Verejná adresa HTTPS na otvorenie tohto portálu Authelia (napríklad https://auth.example.com)",
"Public UDP port clients connect to": "Verejný port UDP na pripojenie klientov",
"Public UDP port peers connect to": "Verejný port UDP na pripojenie účastníkov",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "Verejné URL phpMyAdmin, keď sa podáva za reverzným proxy",
@@ -5457,6 +5486,7 @@
"Re-running pre-check after repairs...": "Spúšťam predbežnú kontrolu znova po opravách...",
"Reachable": "Dostupné",
"Read an oci-compose from a file of this host": "Načítať oci-compose zo súboru tohto hostiteľa",
"Read and edit PDF documents in your browser": "Čítanie a úprava dokumentov PDF v prehliadači",
"Read its Compose file from a file of this host": "Načítať súbor Compose z tohto hostiteľa",
"Read manga through a self-hosted server and web UI.": "Čítajte mangu cez vlastný server a webové rozhranie.",
"Read the link with pct console CTID on the Proxmox host, or from the Console panel of the container in the Proxmox web interface, then open the https://playit.gg/claim/ address it shows in a browser and sign in to playit.gg. Ctrl+a q leaves pct console.": "Odkaz zobrazíte na hostiteľovi Proxmox príkazom pct console CTID alebo v paneli Console kontajnera vo webovom rozhraní Proxmox. Zobrazenú adresu https://playit.gg/claim/ otvorte v prehliadači a prihláste sa do playit.gg. Konzolu pct console ukončíte pomocou Ctrl+a q.",
@@ -5562,6 +5592,7 @@
"Recursive and authoritative DNS server.": "Rekurzívny a autoritatívny DNS server.",
"Redmine": "Redmine",
"Refresh APT index and verify repositories:": "Obnovte APT index a overte repozitáre:",
"Refresh catalog": "Aktualizovať katalóg",
"Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.": "Obnoviť indexy nakonfigurovaných repozitárov APT a skontrolovať aktualizáciu balíkov PBS? Súbory repozitárov sa zachovajú.",
"Refresh the index from the image sources": "Obnoviť index zo zdrojov obrazov",
"Refresh token of the connector, from the Twingate admin console": "Obnovovací token konektora z administrátorskej konzoly Twingate",
@@ -5569,6 +5600,7 @@
"Refresh your browser to see changes (server restart may be required)": "Obnovte stránku v prehliadači, aby ste videli zmeny (môže byť potrebný reštart servera)",
"Refreshing apt cache...": "Obnovujem apt cache...",
"Refreshing the NVIDIA runtime...": "Obnovenie prevádzky NVIDIA...",
"Refreshing the application catalog...": "Aktualizuje sa katalóg aplikácií...",
"Refusing an unexpected rootfs path:": "Odmietnutá neočakávaná cesta koreňového súborového systému:",
"Regenerate the catalog templates": "Znova vygenerovať šablóny katalógu",
"Regenerate the template of one application": "Znova vygenerovať šablónu jednej aplikácie",
@@ -6260,6 +6292,7 @@
"Self-hosted file sync and sharing.": "Vlastná služba na synchronizáciu a zdieľanie súborov.",
"Self-hosted file toolkit for images, video, audio, PDFs, and files": "Súprava nástrojov na vlastnom serveri na prácu s obrázkami, videom, zvukom, PDF a ďalšími súbormi",
"Self-hosted forms and workflows.": "Formuláre a pracovné postupy prevádzkované na vlastnom serveri.",
"Self-hosted grocery list and recipe manager": "Správca nákupných zoznamov a receptov, ktorý si môžete prevádzkovať sami.",
"Self-hosted household plant-care tracker with reminders, photos, and multiple user accounts.": "Prehľad starostlivosti o izbové rastliny prevádzkovaný na vlastnom serveri s pripomienkami, fotografiami a viacerými používateľskými účtami.",
"Self-hosted image-hosting service with authenticated uploads, image processing, public links, and local storage.": "Služba na ukladanie a zdieľanie obrázkov na vlastnom serveri s nahrávaním pre overených používateľov, spracovaním obrázkov, verejnými odkazmi a lokálnym úložiskom.",
"Self-hosted internet archiving solution": "Riešenie na archiváciu internetového obsahu na vlastnom serveri",
@@ -6454,6 +6487,7 @@
"Simple and easy to use DDNS": "Jednoducho použiteľné dynamické DNS (DDNS)",
"Simple self-hosted file sharing.": "Jednoduchá samohostovaná služba na zdieľanie súborov.",
"Single GPU Warning": "Upozornenie na jednu GPU",
"Single sign-on and multi-factor authentication": "Jednotné prihlásenie a viacfaktorové overovanie",
"Single target found — selected automatically:": "Našiel sa jeden target - vybraný automaticky:",
"Single-node log storage and query UI.": "Úložisko logov a vyhľadávacie rozhranie pre jeden uzol.",
"Single-node observability database for metrics, logs and traces.": "Databáza na jednom uzle na ukladanie metrík, logov a záznamov o priebehu požiadaviek.",
@@ -6522,7 +6556,9 @@
"Specific subnet (enter manually)": "Konkrétna podsieť (zadať ručne)",
"Speedtest Tracker web interface": "Webové rozhranie Speedtest Tracker",
"Speedtest-tracker is a self-hosted internet performance tracking application that runs speedtest checks against Ookla's Speedtest service.": "Speedtest Tracker je aplikácia na vlastnom serveri na sledovanie výkonu internetového pripojenia pomocou meraní služby Ookla Speedtest.",
"Spoolman web interface": "Webové rozhranie Spoolmanu",
"Spotube is an open source, cross-platform Spotify client compatible across multiple platforms utilizing Spotify's data API and YouTube, Piped.video or JioSaavn as an audio source, eliminating the need for Spotify Premium": "Spotube je multiplatformový klient Spotify s otvoreným zdrojovým kódom. Využíva dátové API Spotify a zvuk získava z YouTube, Piped.video alebo JioSaavn, takže nevyžaduje Spotify Premium.",
"Spreadsheets in your browser": "Tabuľkový procesor v prehliadači",
"Sshwifty": "Sshwifty",
"Sshwifty web access (password only)": "Webový prístup do Sshwifty (iba heslom)",
"Stable (main branch)": "Stabilná verzia (vetva main)",
@@ -7418,6 +7454,7 @@
"Then bind-mount to container": "Potom pripojiť do kontajnera cez bind mount",
"Then change the VM display to none (vga: none) when the guest is stable.": "Keď bude VM stabilná, zmeňte jej display na none (vga: none).",
"Then change the VM display to none (vga: none) when the system is stable.": "Keď bude systém stabilný, zmeňte display VM na none (vga: none).",
"Then restart the container so the new model appears in the list.": "Potom kontajner reštartujte, aby sa nový model zobrazil v zozname.",
"Then run this option again:": "Potom túto možnosť spustite znova:",
"Then update /etc/fstab on the host with the same options.": "Potom aktualizujte /etc/fstab na hoste s rovnakými možnosťami.",
"There are extra disks or bind mounts outside the journal; the rootfs is not replaced": "Ďalšie disky alebo pripojené adresáre nie sú uvedené v zázname operácie; rootfs sa nenahradí",
@@ -7465,6 +7502,7 @@
"This container does not have apt-get. NFS client installation only supports Debian/Ubuntu containers.": "Tento kontajner nemá apt-get. Inštalácia NFS klienta je podporovaná iba v Debian/Ubuntu kontajneroch.",
"This container does not have apt-get. Samba client installation only supports Debian/Ubuntu containers.": "Tento kontajner nemá apt-get. Inštalácia Samba klienta je podporovaná iba v Debian/Ubuntu kontajneroch.",
"This container has no GPU configured. Coral TPU works best alongside hardware video decoding (Quick Sync, VA-API, NVENC) for apps like Frigate.": "Tento kontajner nemá nastavenú GPU. Coral TPU funguje najlepšie spolu s hardvérovým dekódovaním videa (Quick Sync, VA-API, NVENC) v aplikáciách ako Frigate.",
"This container is managed by high availability. Remove ct:{vmid} from HA (Datacenter → HA, or ha-manager remove ct:{vmid}), repeat the operation and add it back to HA with the same settings.": "Tento kontajner spravuje vysoká dostupnosť. Odstráňte ct:{vmid} z HA (Dátové centrum → HA alebo ha-manager remove ct:{vmid}), zopakujte operáciu a potom ho znova pridajte do HA s rovnakými nastaveniami.",
"This container is not a member of a multi-container application": "Tento kontajner nie je členom aplikácie s viacerými kontajnermi",
"This container is not a registered OCI instance.": "Tento kontajner nie je registrovanou inštanciou OCI.",
"This container was restored or came back from another host after its record on this host was written. Open this menu again to recover it; nothing was changed.": "Tento kontajner bol obnovený alebo sa vrátil z iného hostiteľa po napísaní jeho záznamu na tomto hostiteľovi. Znova otvorte túto ponuku a obnovte ju; nič sa nezmenilo.",
@@ -7582,6 +7620,7 @@
"Tip: You can install the QEMU Guest Agent inside the VM with:": "Tip: QEMU Guest Agent môžete vo VM nainštalovať pomocou:",
"Tip: zfs set acltype=posixacl xattr=sa <pool>/<dataset> enables full ACL support.": "Tip: zfs set acltype=posixacl xattr=sa <pool>/<dataset> zapne plnú podporu ACL.",
"Tmpfs size in MiB for": "Veľkosť Tmpfs v MiB pre",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:": "Ak chcete pridať model, otvorte konzolu kontajnera v Proxmoxe a stiahnite ho do /models, napríklad:",
"To allow LXC write access, change the NFS export on the server to include:": "Aby LXC mohol zapisovať, upravte NFS export na serveri tak, aby obsahoval:",
"To apply it to the current shell now, run:": "Ak ho chcete použiť v aktuálnej relácii shellu, spustite:",
"To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.": "Ak chcete priradiť VF do VM alebo LXC, upravte nastavenie ručne cez webové rozhranie Proxmoxu. Physical Function zostane naviazaná na natívny ovládač.",
@@ -7621,6 +7660,7 @@
"Total routes": "Počet trás",
"Total size:": "Celková veľkosť:",
"Toxiproxy": "Toxiproxy",
"Track 3D printer filament spools and usage.": "Sledujte cievky filamentu pre 3D tlačiareň a ich spotrebu.",
"Track movies, television, anime and games you want to enjoy.": "Sledujte filmy, seriály, anime a hry, ktoré si chcete pozrieť alebo zahrať.",
"Track subscriptions and recurring expenses.": "Sledovanie predplatných a opakovaných výdavkov.",
"Track your music listening history on your own server.": "Sledujte históriu počúvania hudby na vlastnom serveri.",
@@ -7855,6 +7895,7 @@
"Update the whole stack?": "Aktualizovať celú aplikáciu?",
"Update, modify or recreate one installed OCI instance": "Aktualizovať, upraviť alebo znova vytvoriť jednu nainštalovanú inštanciu OCI",
"Updated": "Aktualizované",
"Updated recipes since your last visit: {count}": "Aktualizované recepty od vašej poslednej návštevy: {count}",
"Updated sharedfiles group to GID: 101000": "Skupina sharedfiles bola aktualizovaná na GID: 101000",
"Updated stack checked": "Aktualizovaná aplikácia je skontrolovaná",
"Updated:": "Aktualizované:",
@@ -8060,6 +8101,7 @@
"Variables": "Premenné",
"Variables the installation asks for:": "Premenné, ktoré požaduje inštalácia:",
"Vaultwarden Web Vault": "Vaultwarden Web Vault",
"Vector illustration in your browser": "Vektorová ilustrácia v prehliadači",
"Vector search engine with a built-in dashboard.": "Vektorový vyhľadávač so vstavaným panelom.",
"Verbose pool status": "Podrobný stav poolu",
"Verification": "Overenie",
@@ -8090,6 +8132,7 @@
"Versions shown belong to maintained NVIDIA branches that list your GPU PCI ID and are new enough to build against the running kernel. DKMS compilation is the final validation. The recommended version keeps the current branch, or uses the NVIDIA Production Branch on a fresh install.": "Zobrazené verzie patria do udržiavaných pobočiek NVIDIA, ktoré uvádzajú vaše ID PCI GPU a sú dostatočne nové na to, aby sa dali postaviť proti bežiacemu jadru. Kompilácia DKMS je konečným overením. Odporúčaná verzia ponecháva aktuálnu vetvu alebo používa NVIDIA Production Branch pri novej inštalácii.",
"VictoriaLogs": "VictoriaLogs",
"Video acceleration and object detection are independent choices; the installer does not write camera or detector YAML.": "Zrýchlenie videa a detekcia objektov sú nezávislé voľby. Inštalačný sprievodca nezapisuje nastavenia kamier ani detektorov do YAML.",
"Video editing in your browser": "Strih videa v prehliadači",
"Video transcoding acceleration": "Zrýchlenie priepustnosti videa",
"Video transcoding profile not implemented:": "Profil transkódovania videa nie je implementovaný:",
"View CIFS Mounts (pvesm + fstab)": "Zobraziť CIFS mounty (pvesm + fstab)",
@@ -8199,12 +8242,17 @@
"Web access": "Adresa webového rozhrania",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Webová adresa AdGuard Home, ktorá prijíma nastavenia (napr. http://192.168.1.3)",
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Webová adresa hlavného AdGuard Home, ktorého nastavenia sú kopírované (napr. http://192.168.1.2)",
"Web dashboard": "Webový panel",
"Web dashboard and WebDAV": "Webový panel a WebDAV",
"Web interface": "Webové rozhranie",
"Web interface for Borg Backup repositories and jobs.": "Webové rozhranie na správu úložísk a úloh Borg Backup.",
"Web interface for managing 3D printers.": "Webové rozhranie na správu 3D tlačiarní.",
"Web interface to manage devices running Tasmota firmware.": "Webové rozhranie pre správu zariadení bežiacich na Tasmota firmware.",
"Web reverse proxy with an administration interface.": "Webový reverzný proxy server s administračným rozhraním.",
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord je klient obklopujúci stránku https://discord.com, ktorý zlepšuje bezpečnosť a súkromie, upravuje funkcie Discordu, obchádza chyby Electronu, Chromia a Discordu a pridáva štýly aj interné stránky. Snaží sa čo najviac dodržiavať podmienky používania alebo skryť pred Discordom úpravy, ktoré by ich mohli porušovať.",
"WebDAV": "WebDAV",
"WebDAV and dashboard password (leave empty to generate)": "Heslo pre WebDAV a panel (prázdne = generované)",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV je dostupný na porte 8080 kontajnera. Pred prácou so súbormi v cloude je potrebné prepojiť účet.",
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "WebGrab+Plus priebežne získava elektronický programový sprievodca (EPG) vo formáte XMLTV z viacerých webov. Zhromažďuje televízny program vybraných staníc z podporovaných stránok.",
"Webservers & Proxies": "Webové servery a proxy",
"Website": "Webová stránka",
@@ -8262,6 +8310,7 @@
"Without a usable reset path, passthrough reliability is poor and VM": "Bez použiteľnej reset cesty je spoľahlivosť passthrough nízka a VM",
"Wizard cancelled": "Sprievodca zrušený",
"Wolfenstein: Blade of Agony is a story-driven WWII shooter inspired by Wolfenstein and Doom.": "Wolfenstein: Blade of Agony je príbehová strieľačka z druhej svetovej vojny inšpirovaná hrami Wolfenstein a Doom.",
"Word processing in your browser": "Spracovanie textu v prehliadači",
"Workflow automation tool": "Nástroj na automatizáciu pracovného toku",
"Working directory:": "Pracovný priečinok:",
"Works with LVM, ZFS, and BTRFS storage types": "Funguje s typmi úložísk LVM, ZFS a BTRFS",
@@ -8312,6 +8361,8 @@
"Your machine learning Env work with Jupyter Lab": "Prostredie strojového učenia s JupyterLab",
"Your next YouTube media manager": "Váš ďalší manažér médií YouTube",
"Your_spotify is a self-hosted application that tracks what you listen and offers you a dashboard to explore statistics about it! It's composed of a web server which polls the Spotify API every now and then and a web application on which you can explore your statistics.": "Your_spotify je aplikácia na vlastnom serveri, ktorá sleduje počúvanie hudby a zobrazuje štatistiky. Tvorí ju server pravidelne zisťujúci údaje cez Spotify API a webové rozhranie na ich prezeranie.",
"Z-Wave JS UI": "Z-Wave JS UI",
"Z-Wave JS UI admin login": "Prihlásenie správcu Z-Wave JS UI",
"ZFS ARC config removed (kernel defaults will apply on reboot)": "Nastavenie ZFS ARC bolo odstránené (predvolené hodnoty kernelu sa použijú po reštarte)",
"ZFS ARC maximum configured:": "Maximálna veľkosť ZFS ARC je nastavená na:",
"ZFS ARC optimization completed": "Optimalizácia ZFS ARC je dokončená",
@@ -8425,6 +8476,7 @@
"could not be compiled for kernel": "nepodarilo sa skompilovať pre jadro",
"could not validate NVIDIA; exit code": "nemohol potvrdiť NVIDIA; kód výstupu",
"cpuunits must be between 8 and 10000": "Hodnota cpuunits musí byť od 8 do 10000",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf": "curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"custom": "vlastné",
"custom dependency commands are not yet supported": "Vlastné príkazy závislosti ešte nie sú podporované",
"custom path(s) saved.": "uložených vlastných ciest.",
@@ -8631,6 +8683,7 @@
"kexec-tools is not installed or already removed.": "kexec-tools nie je nainštalovaný alebo už bol odstránený.",
"layers": "vrstvy",
"legacy .link file(s) to the ProxMenux-managed format": "staršie .link súbory do formátu spravovaného ProxMenuxom",
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.": "llama.cpp zobrazuje vo svojom webovom rozhraní všetky modely GGUF uložené v /models a načíta ten, ktorý si vyberiete.",
"log2ram completely removed from system": "log2ram bol úplne odstránený zo systému",
"main container of the application": "hlavný kontajner aplikácie",
"make cloned mount tree read-only": "nastavenie klonovaného stromu pripojenia iba na čítanie",
+53
View File
@@ -184,6 +184,7 @@
"A tunneling daemon by Cloudflare that safely exposes your web servers into the internet.": "En tunneldemon av Cloudflare som säkert avslöjar dina webbservrar på internet.",
"A unified email and collaboration server.": "En enhetlig server för e-post och samarbete.",
"A unified platform for logs, metrics and traces.": "En enhetlig plattform för loggar, mätvärden och spårningar.",
"A validating, recursive DNS resolver for your private network.": "En validerande, rekursiv DNS-resolver för ditt privata nätverk.",
"A versatile file conversion tool that supports multiple formats.": "Ett mångsidigt filkonverteringsverktyg som stöder flera format.",
"A visual tool for exploring and documenting database schemas.": "Ett visuellt verktyg för att utforska och dokumentera databasscheman.",
"A web GUI client of Project V which supports VMess, VLESS, SS, SSR, Trojan, Tuic and Juicity protocols": "En webb GUI klient av Project V som stöder VMess, VLESS, SS, SSR, Trojan, Tuic och Juicity protokoll",
@@ -256,6 +257,7 @@
"Acceleration for llama.cpp": "Acceleration för llama.cpp",
"Accept routes from other nodes?": "Acceptera rutter från andra noder?",
"Accept this host monitoring profile?": "Acceptera denna värdövervakningsprofil?",
"Access Movistar and O2 Cloud from WebDAV clients and backup tools.": "Kom åt Movistar- och O2-molnet från WebDAV-klienter och säkerhetskopieringsverktyg.",
"Access Scope:": "Åtkomstomfång:",
"Access bridge": "Tillgång bridge",
"Access bridge for Immich": "Tillgångsbro för Immich",
@@ -410,6 +412,7 @@
"After the reboot, you will only be able to access the Proxmox host via:": "Efter omstarten kommer du bara att kunna komma åt Proxmox-värden via:",
"After this LXC → VM switch, reboot the host so the new binding state is applied cleanly.": "Efter denna LXC → VM-switch, starta om värden så att det nya bindningsläget tillämpas korrekt.",
"Agentless monitoring and observability platform.": "Agentlös plattform för övervakning och observerbarhet.",
"AirDC++ administrator": "AirDC++-administratör",
"Airsonic Advanced web interface": "Airsonic Advanced webbgränssnitt",
"Airsonic-advanced is a free, web-based media streamer, providing ubiquitious access to your music. Use it to share your music with friends, or to listen to your own music while at work. You can stream to multiple players simultaneously, for instance to one player in your kitchen and another in your living room.": "Airsonic-advanced är en gratis, webbaserad media streamer, som ger ubiquitious tillgång till din musik. Använd den för att dela din musik med vänner, eller för att lyssna på din egen musik på jobbet. Du kan strömma till flera spelare samtidigt, till exempel till en spelare i ditt kök och en annan i ditt vardagsrum.",
"Aliases added to .bashrc": "Alias har lagts till i .bashrc",
@@ -598,11 +601,15 @@
"Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Observera: Att ta bort prenumerationsbannern kan orsaka problem i webbgränssnittet efter en framtida uppdatering.",
"Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity är en lättanvänd, multi-track ljudredigerare och inspelare. Utvecklad av en grupp frivilliga som öppen källkod.",
"Audio device directory": "Ljudenhetskatalog",
"Audio recording and mixing in your browser": "Ljudinspelning och mixning i webbläsaren",
"Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf är en själv värd ljudbok och podcast server.",
"Audit completed. Press Enter to continue...": "Revision avslutad. Tryck på Enter för att fortsätta...",
"Audit socket disabled or not required": "Granskningsuttaget inaktiverat eller inte nödvändigt",
"Auth key is required.": "Auth-nyckel krävs.",
"Auth:": "Auth:",
"Authelia Web UI": "Authelias webbgränssnitt",
"Authelia administrator": "Authelia administratör",
"Authelia session cookie domain for this portal (for example example.com)": "Authelia sessionscookiedomän för denna portal (till exempel example.com)",
"Authentication": "Autentisering",
"Authentication & Security": "Autentisering och säkerhet",
"Authentication Error": "Autentiseringsfel",
@@ -642,6 +649,7 @@
"Available PVE Version": "Tillgänglig PVE-version",
"Available Shares:": "Tillgängliga andelar:",
"Available action": "Tillgänglig åtgärd",
"Available applications: {count}": "Tillgängliga appar: {count}",
"Available archives:": "Tillgängliga arkiv:",
"Available disks detected.": "Tillgängliga diskar har upptäckts.",
"Available host backups:": "Tillgängliga värdsäkerhetskopior:",
@@ -873,6 +881,7 @@
"Cannot write the image archive to {storage}. Check storage access and mount status.": "Kan inte skriva bildarkivet till {storage}. Kontrollera lagringsåtkomst och monteringsstatus.",
"Capabilities cannot be kept and all dropped at the same time": "Förmågor kan inte hållas och alla tappas samtidigt",
"Catalog options": "Katalogalternativ",
"Catalog refresh unavailable; using the local catalog.": "Katalogen kunde inte uppdateras; den lokala katalogen används.",
"Category": "Kategori",
"Caution: Maximum mode generates more heat.": "Varning: Maximalt läge genererar mer värme.",
"Central server for file and image backups.": "Central server för säkerhetskopiering av filer och bilder.",
@@ -1159,6 +1168,7 @@
"Compressing": "Komprimerar",
"Compression": "Kompression",
"Compression Tools": "Kompressionsverktyg",
"Computer-aided design and drafting in your browser": "CAD och teknisk ritning i webbläsaren",
"Concise output of logical volumes": "Kortfattad utdata av logiska volymer",
"Concise output of physical volumes": "Kortfattad utdata av fysiska volymer",
"Concise output of volume groups": "Kortfattad utdata av volymgrupper",
@@ -1393,6 +1403,7 @@
"Controller + NVMe": "Styrenhet + NVMe",
"Controller + NVMe assignment will be written now and become active after host reboot.": "Tilldelningen av styrenhet + NVMe skrivs nu och aktiveras efter omstart av värden.",
"Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.": "Styrenhets-/NVMe-passthrough kräver maskintypen q35. Hoppar över tilldelning av styrenheten.",
"Controller path on the Proxmox host; prefer /dev/serial/by-id/...": "Styrsökväg på Proxmox-värden;föredrar /dev/serial/by-id/...",
"Controller/NVMe Conflict Policy": "Konfliktpolicy för styrenhet/NVMe",
"Controller/NVMe already present in VM config": "Styrenhet/NVMe finns redan i VM-konfigurationen",
"Controller/NVMe already present in VM config (%s)": "Styrenhet/NVMe finns redan i VM-konfigurationen (%s)",
@@ -1927,6 +1938,7 @@
"Dgraph": "Dgraph",
"Diff: current system vs backup (--- system +++ backup)": "Diff: nuvarande system vs säkerhetskopia (--- system +++ säkerhetskopia)",
"Different host. Backup from:": "Annorlunda värd. Säkerhetskopiering från:",
"Direct Connect file sharing with a web interface": "Fildelning via Direct Connect med webbgränssnitt",
"Direct conversion completed for container": "Direkt konvertering slutförd för container",
"Directory Exists": "Katalog finns",
"Directory Not Empty": "Katalog inte tom",
@@ -3340,6 +3352,7 @@
"Initial Stirling-PDF account": "Första Stirling-PDF-kontot",
"Initial Tandoor administrator": "Initial Tandoor administratör",
"Initial Umami administrator": "Umamis första administratör",
"Initial Z-Wave JS UI admin password": "Initialt Z-Wave JS UI administratörslösenord",
"Initial administrator created:": "Initial administratör skapad:",
"Initial administrator user": "Initial administratör användare",
"Initializing Borg repository if needed...": "Initierar Borg-arkivet om det behövs...",
@@ -3525,6 +3538,7 @@
"Interface MTU": "Gränssnitt MTU",
"Interface Names (persistent)": "Gränssnittsnamn (beständig)",
"Interface Type": "Gränssnittstyp",
"Interface design and prototyping in your browser": "Gränssnittsdesign och prototyper i webbläsaren",
"Interface names will return to default systemd behavior.": "Gränssnittsnamn kommer att återgå till standardsystembeteende.",
"Interface type:": "Gränssnittstyp:",
"Interfaces configured": "Gränssnitt konfigurerade",
@@ -3740,6 +3754,7 @@
"Jupyter Lab (token only)": "Jupyter Lab (endast token)",
"JupyterLab": "JupyterLab",
"JupyterLab access token": "Åtkomsttoken för JupyterLab",
"KDE's twin-panel file manager in a browser-based desktop.": "KDE:s filhanterare med två paneler i ett webbläsarbaserat skrivbord.",
"KDF:": "KDF:",
"KROMA": "KROMA",
"KVM MSR options added to /etc/modprobe.d/kvm.conf": "KVM MSR-alternativ har lagts till i /etc/modprobe.d/kvm.conf",
@@ -3787,12 +3802,14 @@
"KiCad - A Cross Platform and Open Source Electronics Design Automation Suite.": "KiCad - En Cross Platform och Open Source Electronics Design Automation Suite.",
"Kimai has no default account. Enter the container with: pct enter {main_vmid}": "Kimai har inget standardkonto. Öppna ett skal i containern med: pct enter {main_vmid}",
"Kimai is a professional grade time-tracking application, free and open-source.": "Kimai är en professionell tidsspårningsapplikation, fri och öppen källkod.",
"KitchenOwl": "KitchenOwl",
"Kometa is a powerful tool designed to give you complete control over your media libraries. With Kometa, you can take your customization to the next level, with granular control over metadata, collections, overlays, and much more.": "Kometa är ett kraftfullt verktyg för att ge dig fullständig kontroll över dina mediebibliotek. Med Kometa kan du ta din anpassning till nästa nivå, med granulär kontroll över metadata, samlingar, överlagringar och mycket mer.",
"Kometa reads its configuration from /config/config.yml and the container only ships /config/config.yml.template. Copy the template to config.yml, fill in the required Plex and TMDb connections, then restart the container.": "Kometa läser sin konfiguration från /config/config.yml och behållaren endast fartyg /config/config.yml.template. Kopiera mallen till config.yml, fyll i required Plex och TMDb-anslutningar och starta sedan om behållaren.",
"Komga is a media server for your comics, mangas, BDs, magazines and eBooks.": "Komga är en mediaserver för dina serier, mangas, BD, tidskrifter och e-böcker.",
"Kopia Web UI": "Kopia-webbgränssnitt",
"Kopia Web UI login": "Inloggning till Kopias webbgränssnitt",
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita är ett professionellt gratis och öppen källkod målning program. Den är gjord av konstnärer som vill se prisvärda konstverktyg för alla.",
"Krusader Web UI": "Krusaders webbgränssnitt",
"LAN access to the kept containers (stack configuration incomplete):": "LAN tillgång till de bevarade behållarna (stack konfiguration ofullständig):",
"LAN address applied to the application URLs": "LAN-adress tillämpad på ansökningsadresserna",
"LLDAP": "LLDAP",
@@ -4020,6 +4037,7 @@
"Manage OCI stack": "Hantera OCI stack",
"Manage PBS encryption keyfile": "Hantera PBS-krypteringsnyckelfil",
"Manage Secure Gateway": "Hantera Secure Gateway",
"Manage a Z-Wave network from a web dashboard and WebSocket gateway.": "Hantera ett Z-Wave-nätverk från en webbinstrumentpanel och WebSocket-gateway.",
"Manage and inspect VM disk images": "Hantera och inspektera VM-diskavbildningar",
"Manage custom backup paths": "Hantera anpassade säkerhetskopieringsvägar",
"Manage custom paths (add / remove your folders)": "Hantera anpassade sökvägar (lägg till / ta bort dina mappar)",
@@ -4029,6 +4047,7 @@
"Manage local backup target": "Hantera lokalt mål för säkerhetskopiering",
"Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Hantera privata bildregister.\nSparade referenser låter ProxMenux komma åt dina privata bilder.",
"Manage registry accounts as root on the Proxmox node.": "Hantera registerkonton som root på Proxmox-noden.",
"Manage teams of AI agents from a web dashboard.": "Hantera team av AI-agenter från en webbpanel.",
"Managed disks must have backup enabled and a valid size": "Hanterade diskar måste ha backup aktiverad och en giltig storlek",
"Managed public route include is missing": "Konfigurationsfilen för de hanterade publika rutterna saknas",
"Managed public route installation failed": "Det gick inte att konfigurera de hanterade publika rutterna",
@@ -4134,6 +4153,7 @@
"Monitoring": "Övervakning",
"Monitoring & Analytics": "Övervakning och analys",
"Most common cause: the archive is corrupted (interrupted write, partial copy, or storage issue).": "Vanligaste orsaken: arkivet är skadat (avbruten skrivning, delvis kopiering eller lagringsproblem).",
"Motion graphics and compositing in your browser": "Rörlig grafik och komposition i webbläsaren",
"Mount Added Successfully:": "Montering har lagts till:",
"Mount CIFS share:": "Montera CIFS-andel:",
"Mount Configuration Summary:": "Sammanfattning av monteringskonfiguration:",
@@ -4434,6 +4454,7 @@
"New Search": "Ny sökning",
"New VM:": "Ny VM:",
"New Virtual Machine": "Ny virtuell maskin",
"New applications since your last visit: {count}": "Nya appar sedan ditt senaste besök: {count}",
"New backup job": "Nytt säkerhetskopia jobb",
"New backups on this host will be unencrypted until a new keyfile is set up.": "Nya säkerhetskopior på denna värd kommer att vara okrypterade tills en ny nyckelfil ställs in.",
"New image compatible:": "Ny bildkompatibel:",
@@ -4896,6 +4917,8 @@
"Open the page of an application in the menu": "Öppna en applikations sida i menyn",
"Open the web address and create the first account: the daemon registers by itself and starts the first scan.": "Öppna webbadressen och skapa det första kontot: daemonen registrerar sig själv och startar den första skanningen.",
"Open the web address and create the password of the akadmin user in the first-run setup.": "Öppna webbadressen och skapa lösenordet för akadmin-användaren i den första körningen.",
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured.": "Öppna webbadressen och följ KitchenOwls introduktion för att skapa det första kontot;inget standardkonto är konfigurerat.",
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.": "Öppna webbpanelen och koppla ditt Movistar/O2-konto med SMS-verifieringen.",
"Open-source AI-powered coding assistant": "Open-source AI-driven kodningsassistent",
"Open-source UI for building and debugging multi-agent and RAG applications": "Open-source UI för att bygga och debugga multi-agent- och RAG-applikationer",
"Open-source in-memory data store.": "Öppen datalagring i minnet.",
@@ -5018,6 +5041,7 @@
"Packages:": "Paket:",
"Packaging OVA file...": "Förpackning av OVA-fil...",
"Packing installer archive...": "Packar installationsarkiv...",
"Page layout and publishing in your browser": "Sidlayout och publicering i webbläsaren",
"PairDrop is a sublime alternative to AirDrop that works on all platforms. Send images, documents or text via peer to peer connection to devices in the same local network/Wi-Fi or to paired devices.": "PairDrop är ett sublimt alternativ till AirDrop som fungerar på alla plattformar. Skicka bilder, dokument eller text via peer till peer-anslutning till enheter i samma lokala nätverk / Wi-Fi eller till parade enheter.",
"Paperless configuration cancelled": "Papperslös konfiguration inställd",
"Paperless-ngx WebUI": "Paperless-ngx WebUI",
@@ -5036,6 +5060,7 @@
"Pass /dev/video12 to the LXC": "Pass /dev/video12 till LXC",
"Pass a host device to the LXC": "Passera en värdenhet till LXC",
"Pass the UPS to the LXC": "Skicka UPS:en till LXC",
"Pass through a Z-Wave USB or serial controller": "Passera genom en Z-Wave USB eller seriell styrenhet",
"Passing NVIDIA does not enable acceleration inside the application. The host needs NVIDIA Container Toolkit and a compatible image. Continue?": "Att passera NVIDIA möjliggör inte acceleration inuti applikationen. Värden behöver NVIDIA Container Toolkit och en kompatibel bild. Fortsätta?",
"Passkey-based identity provider for self-hosted apps.": "Identitetsleverantör med passkeys för självhostade appar.",
"Passphrase used to unlock the imported keyfile (leave blank if the keyfile is unencrypted / kdf=none):": "Lösenfras som används för att låsa upp den importerade nyckelfilen (lämna tomt om nyckelfilen är okrypterad / kdf=ingen):",
@@ -5143,6 +5168,8 @@
"Personal finance management application": "Personlig ekonomi management ansökan",
"Personal media server for browsing and playing a local video library, with direct play and optional modules.": "Personlig medieserver för att bläddra bland och spela upp ett lokalt videobibliotek, med direktuppspelning och valfria moduler.",
"Photo and video library with optional GPU transcoding and machine learning": "Foto- och videobibliotek med valfri GPU-överkodning och maskininlärning",
"Photo editing in your browser": "Fotoredigering i webbläsaren",
"Photo library and RAW development in your browser": "Fotobibliotek och RAW-framkallning i webbläsaren",
"PhotoPrism": "PhotoPrism",
"Photofield": "Photofield",
"Phpmyadmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB.": "Phpmyadmin är ett gratis mjukvaruverktyg skrivet i PHP, avsedd att hantera administrationen av MySQL över webben. phpMyAdmin stöder ett brett utbud av operations på MySQL och MariaDB.",
@@ -5235,6 +5262,7 @@
"Preparing the machine learning container for the new choice...": "Förbereder maskininlärningsbehållaren för det nya valet...",
"Preparing the recreation...": "Förbereda rekreationen...",
"Preparing the update...": "Förbereda uppdateringen...",
"Presentations and slide decks in your browser": "Presentationer och bildspel i webbläsaren",
"Preserving logs to /var/log.hdd before unmounting...": "Sparar loggar till /var/log.hdd innan avmontering...",
"Press 'q' to exit": "Tryck på 'q' för att avsluta",
"Press Ctrl+C to stop the server and return to menu.": "Tryck på Ctrl+C för att stoppa servern och återgå till menyn.",
@@ -5395,6 +5423,7 @@
"Proxmox web interface: Datacenter > Storage > Add > ZFS": "Proxmox webbgränssnitt: Datacenter > Lagring > Lägg till > ZFS",
"Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Proxmox webbgränssnitt: Datacenter > Lagring > Lägg till > iSCSI",
"Proxy address to reach the API (optional)": "Proxyadress för att nå API:t (valfritt)",
"Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)": "Offentlig HTTPS-URL som används för att öppna denna Authelia-portal (till exempel https://auth.example.com)",
"Public UDP port clients connect to": "Offentliga UDP-portklienter ansluter till",
"Public UDP port peers connect to": "Offentliga UDP-portpeers ansluter till",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "Public URL av phpMyAdmin när den serveras bakom en omvänd proxy",
@@ -5455,6 +5484,7 @@
"Re-running pre-check after repairs...": "Kör förkontroll igen efter reparationer...",
"Reachable": "Kan nåbar",
"Read an oci-compose from a file of this host": "Läs en oci-compose från en fil på denna värd",
"Read and edit PDF documents in your browser": "Läs och redigera PDF-dokument i webbläsaren",
"Read its Compose file from a file of this host": "Läs dess Compose-fil från en fil av denna värd",
"Read manga through a self-hosted server and web UI.": "Läs manga via en självhostad server och ett webbgränssnitt.",
"Read the link with pct console CTID on the Proxmox host, or from the Console panel of the container in the Proxmox web interface, then open the https://playit.gg/claim/ address it shows in a browser and sign in to playit.gg. Ctrl+a q leaves pct console.": "Läs länken med pct console CTID på Proxmox-värden, eller från Console-panelen i behållaren i Proxmox-webbgränssnittet, öppna sedan https://playit.gg/claim/adressen visas i en webbläsare och logga in för att spelait.gg. Ctrl+a q lämnar pct konsol.",
@@ -5560,6 +5590,7 @@
"Recursive and authoritative DNS server.": "Rekursiv och auktoritativ DNS-server.",
"Redmine": "Redmine",
"Refresh APT index and verify repositories:": "Uppdatera APT-index och verifiera förråd:",
"Refresh catalog": "Uppdatera katalogen",
"Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.": "Uppdatera de konfigurerade APT-paketförråden och granska PBS-paketuppgraderingen? Paketförrådens filer bevaras.",
"Refresh the index from the image sources": "Uppdatera indexet från avbildskällorna",
"Refresh token of the connector, from the Twingate admin console": "Uppdateringstoken för kontakten, från Twingate-administratörskonsolen",
@@ -5567,6 +5598,7 @@
"Refresh your browser to see changes (server restart may be required)": "Uppdatera din webbläsare för att se ändringar (serverns omstart kan krävas)",
"Refreshing apt cache...": "Uppdaterar apt cache...",
"Refreshing the NVIDIA runtime...": "Uppfriskande NVIDIA runtime...",
"Refreshing the application catalog...": "Uppdaterar appkatalogen...",
"Refusing an unexpected rootfs path:": "Vägrar en oväntad rootfs väg:",
"Regenerate the catalog templates": "Generera om katalogmallarna",
"Regenerate the template of one application": "Generera om mallen för en applikation",
@@ -6258,6 +6290,7 @@
"Self-hosted file sync and sharing.": "Självhostad filsynkronisering och delning.",
"Self-hosted file toolkit for images, video, audio, PDFs, and files": "Självvärd filverktyg för bilder, video, ljud, PDF-filer och filer",
"Self-hosted forms and workflows.": "Självhostade formulär och arbetsflöden.",
"Self-hosted grocery list and recipe manager": "Self-hosted inköpslista och recept manager",
"Self-hosted household plant-care tracker with reminders, photos, and multiple user accounts.": "Självhostad skötselapp för krukväxter med påminnelser, foton och flera användarkonton.",
"Self-hosted image-hosting service with authenticated uploads, image processing, public links, and local storage.": "Självhostad bildtjänst med autentiserade uppladdningar, bildbehandling, offentliga länkar och lokal lagring.",
"Self-hosted internet archiving solution": "Självhäftad internetarkiveringslösning",
@@ -6452,6 +6485,7 @@
"Simple and easy to use DDNS": "Enkelt och enkelt att använda DDNS",
"Simple self-hosted file sharing.": "Enkel självhostad fildelning.",
"Single GPU Warning": "Varning för enkel GPU",
"Single sign-on and multi-factor authentication": "Enkel inloggning och multifaktorautentisering",
"Single target found — selected automatically:": "Enstaka mål hittades — väljs automatiskt:",
"Single-node log storage and query UI.": "Gränssnitt för logglagring och loggsökning på en enda nod.",
"Single-node observability database for metrics, logs and traces.": "Observabilitetsdatabas med en nod för mätvärden, loggar och spår.",
@@ -6520,7 +6554,9 @@
"Specific subnet (enter manually)": "Specifikt subnät (skriv in manuellt)",
"Speedtest Tracker web interface": "Speedtest Tracker webbgränssnitt",
"Speedtest-tracker is a self-hosted internet performance tracking application that runs speedtest checks against Ookla's Speedtest service.": "Speedtest-tracker är en självhäftad internetprestationsspårningsapplikation som kör snabbaste kontroller mot Ooklas Speedtest-tjänst.",
"Spoolman web interface": "Spoolman webbgränssnitt",
"Spotube is an open source, cross-platform Spotify client compatible across multiple platforms utilizing Spotify's data API and YouTube, Piped.video or JioSaavn as an audio source, eliminating the need for Spotify Premium": "Spotube är en öppen källkod, plattform Spotify klient kompatibel över flera plattformar som använder Spotifys data API och YouTube, Piped. video eller JioSaavn som ljudkälla, vilket eliminerar behovet av Spotify Premium",
"Spreadsheets in your browser": "Kalkylblad i webbläsaren",
"Sshwifty": "Sshwifty",
"Sshwifty web access (password only)": "Sshwifty-webbåtkomst (endast lösenord)",
"Stable (main branch)": "Stabil (huvudgren)",
@@ -7417,6 +7453,7 @@
"Then bind-mount to container": "Bind-montera sedan till behållaren",
"Then change the VM display to none (vga: none) when the guest is stable.": "Ändra sedan VM-skärmen till ingen (vga: ingen) när gästen är stabil.",
"Then change the VM display to none (vga: none) when the system is stable.": "Ändra sedan VM-skärmen till ingen (vga: ingen) när systemet är stabilt.",
"Then restart the container so the new model appears in the list.": "Starta sedan om containern så att den nya modellen visas i listan.",
"Then run this option again:": "Kör sedan det här alternativet igen:",
"Then update /etc/fstab on the host with the same options.": "Then update /etc/fstab on the host with the same options.",
"There are extra disks or bind mounts outside the journal; the rootfs is not replaced": "Det finns extra diskar eller binda fästen utanför tidskriften; rootfs ersätts inte",
@@ -7464,6 +7501,7 @@
"This container does not have apt-get. NFS client installation only supports Debian/Ubuntu containers.": "Den här behållaren har inte apt-get. NFS-klientinstallation stöder endast Debian/Ubuntu-behållare.",
"This container does not have apt-get. Samba client installation only supports Debian/Ubuntu containers.": "Den här behållaren har inte apt-get. Samba-klientinstallationen stöder endast Debian/Ubuntu-behållare.",
"This container has no GPU configured. Coral TPU works best alongside hardware video decoding (Quick Sync, VA-API, NVENC) for apps like Frigate.": "Den här behållaren har ingen GPU konfigurerad. Coral TPU fungerar bäst tillsammans med hårdvaruvideoavkodning (Quick Sync, VA-API, NVENC) för appar som Frigate.",
"This container is managed by high availability. Remove ct:{vmid} from HA (Datacenter → HA, or ha-manager remove ct:{vmid}), repeat the operation and add it back to HA with the same settings.": "Den här containern hanteras av hög tillgänglighet. Ta bort ct:{vmid} från HA (Datacenter → HA, eller ha-manager remove ct:{vmid}), upprepa åtgärden och lägg sedan tillbaka den i HA med samma inställningar.",
"This container is not a member of a multi-container application": "Den här behållaren är inte medlem i ett program för flera behållare",
"This container is not a registered OCI instance.": "Denna behållare är inte en registrerad OCI-instans.",
"This container was restored or came back from another host after its record on this host was written. Open this menu again to recover it; nothing was changed.": "Den här behållaren återställdes eller kom tillbaka från en annan värd efter att dess post på denna värd skrevs. Öppna den här menyn igen för att återställa den; ingenting ändrades.",
@@ -7582,6 +7620,7 @@
"Tip: You can install the QEMU Guest Agent inside the VM with:": "Tips: Du kan installera QEMU Guest Agent inuti den virtuella datorn med:",
"Tip: zfs set acltype=posixacl xattr=sa <pool>/<dataset> enables full ACL support.": "Tips: zfs set acltype=posixacl xattr=sa <pool>/<dataset> möjliggör fullt ACL-stöd.",
"Tmpfs size in MiB for": "Tmpfs storlek i MiB för",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:": "Om du vill lägga till en modell öppnar du containerns konsol i Proxmox och laddar ned den till /models, till exempel:",
"To allow LXC write access, change the NFS export on the server to include:": "För att tillåta LXC-skrivåtkomst, ändra NFS-exporten på servern så att den inkluderar:",
"To apply it to the current shell now, run:": "För att använda den i den aktuella shellsessionen nu, kör:",
"To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.": "För att tilldela VF:er till virtuella datorer eller LXC:er, redigera konfigurationen manuellt via Proxmox webbgränssnitt. Den fysiska funktionen förblir bunden till den ursprungliga drivrutinen.",
@@ -7621,6 +7660,7 @@
"Total routes": "Totalt antal rutter",
"Total size:": "Total storlek:",
"Toxiproxy": "Toxiproxy",
"Track 3D printer filament spools and usage.": "Spåra 3D-skrivarens filamentspolar och användning.",
"Track movies, television, anime and games you want to enjoy.": "Håll koll på filmer, tv-serier, anime och spel som du vill se eller spela.",
"Track subscriptions and recurring expenses.": "Håll koll på prenumerationer och återkommande utgifter.",
"Track your music listening history on your own server.": "Följ din musikhistorik på din egen server.",
@@ -7855,6 +7895,7 @@
"Update the whole stack?": "Uppdatera hela stacken?",
"Update, modify or recreate one installed OCI instance": "Uppdatera, ändra eller återskapa en installerad OCI-instans",
"Updated": "Uppdaterad",
"Updated recipes since your last visit: {count}": "Uppdaterade recept sedan ditt senaste besök: {count}",
"Updated sharedfiles group to GID: 101000": "Uppdaterad sharedfiles-grupp till GID: 101000",
"Updated stack checked": "Uppdaterad stack kontrollerad",
"Updated:": "Uppdaterad:",
@@ -8060,6 +8101,7 @@
"Variables": "Variables",
"Variables the installation asks for:": "Variabler som installationen begär:",
"Vaultwarden Web Vault": "Vaultwarden Web Vault",
"Vector illustration in your browser": "Vektorillustration i webbläsaren",
"Vector search engine with a built-in dashboard.": "Vektorsökmotor med inbyggd kontrollpanel.",
"Verbose pool status": "Utförlig poolstatus",
"Verification": "Kontroll",
@@ -8090,6 +8132,7 @@
"Versions shown belong to maintained NVIDIA branches that list your GPU PCI ID and are new enough to build against the running kernel. DKMS compilation is the final validation. The recommended version keeps the current branch, or uses the NVIDIA Production Branch on a fresh install.": "Versioner som visas tillhör underhållna NVIDIA-grenar som listar ditt GPU PCI-ID och är tillräckligt nya för att bygga mot den körande kärnan. DKMS kompilering är den slutliga valideringen. Den rekommenderade versionen behåller den aktuella grenen eller använder NVIDIA Production Branch på en nyinstallation.",
"VictoriaLogs": "VictoriaLogs",
"Video acceleration and object detection are independent choices; the installer does not write camera or detector YAML.": "Videoacceleration och objektdetektering är oberoende val; installatören skriver inte kamera eller detektor YAML.",
"Video editing in your browser": "Videoredigering i webbläsaren",
"Video transcoding acceleration": "Videoöverskridande acceleration",
"Video transcoding profile not implemented:": "Videokodningsprofilen har inte implementerats:",
"View CIFS Mounts (pvesm + fstab)": "Visa CIFS-fästen (pvesm + fstab)",
@@ -8199,12 +8242,17 @@
"Web access": "Web access",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Webbadress för AdGuard Home som tar emot inställningarna (t.ex. http://192.168.1.3)",
"Web address of the main AdGuard Home, whose settings are copied (e.g. http://192.168.1.2)": "Webbadressen för AdGuard Home, vars inställningar kopieras (t.ex. http://192.168.1.2)",
"Web dashboard": "Webbpanel",
"Web dashboard and WebDAV": "Webbpanel och WebDAV",
"Web interface": "Webbgränssnitt",
"Web interface for Borg Backup repositories and jobs.": "Webbgränssnitt för Borg Backup-arkiv och jobb.",
"Web interface for managing 3D printers.": "Webbgränssnitt för hantering av 3D-skrivare.",
"Web interface to manage devices running Tasmota firmware.": "Webbgränssnitt för att hantera enheter som kör Tasmota firmware.",
"Web reverse proxy with an administration interface.": "Omvänd proxy för webben med administrationsgränssnitt.",
"WebCord can be summarized as a pack of security and privacy hardenings, Discord features reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, internal pages and wrapped https://discord.com page, designed to conform with ToS as much as it is possible (or hide the changes that might violate it from Discord's eyes).": "WebCord kan sammanfattas som ett paket av säkerhets- och sekretesshärdningar, Discord-funktioner reimplementations, Electron / Chromium / Discord bugs workarounds, stylesheets, interna sidor och wrapped https://discord.com sida, utformad för att överensstämma med ToS så mycket som möjligt (eller dölja de förändringar som kan bryta mot det från Discords ögon).",
"WebDAV": "WebDAV",
"WebDAV and dashboard password (leave empty to generate)": "Lösenord för WebDAV och panelen (tom = genererat)",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations.": "WebDAV är tillgängligt på containerns port 8080. Kontot måste kopplas innan du arbetar med filerna i molnet.",
"Webgrabplus is a multi-site incremental xmltv epg grabber. It collects tv-program guide data from selected tvguide sites for your favourite channels.": "Webgrabplus är en multi-site inkrementell xmltv epg grabber. Det samlar in tv-programguide data från utvalda tvguide webbplatser för dina favoritkanaler.",
"Webservers & Proxies": "Webbservrar och proxyservrar",
"Website": "Webbplats",
@@ -8262,6 +8310,7 @@
"Without a usable reset path, passthrough reliability is poor and VM": "Utan en användbar återställningsväg är tillförlitligheten för genomkoppling dålig och VM",
"Wizard cancelled": "Wizard avbruten",
"Wolfenstein: Blade of Agony is a story-driven WWII shooter inspired by Wolfenstein and Doom.": "Wolfenstein: Blade of Agony är en story-driven WWII skytt inspirerad av Wolfenstein och Doom.",
"Word processing in your browser": "Ordbehandling i webbläsaren",
"Workflow automation tool": "Workflow automation verktyg",
"Working directory:": "Arbetskatalog:",
"Works with LVM, ZFS, and BTRFS storage types": "Fungerar med LVM, ZFS och BTRFS lagringstyper",
@@ -8312,6 +8361,8 @@
"Your machine learning Env work with Jupyter Lab": "Din maskininlärning Env arbetar med Jupyter Lab",
"Your next YouTube media manager": "Din nästa YouTube Media Manager",
"Your_spotify is a self-hosted application that tracks what you listen and offers you a dashboard to explore statistics about it! It's composed of a web server which polls the Spotify API every now and then and a web application on which you can explore your statistics.": "Your_spotify är en egen värd program som spårar vad du lyssnar och erbjuder dig en instrumentpanel för att utforska statistik om det! Den består av en webbserver som undersöker Spotify API då och då och en webbapplikation där du kan utforska din statistik.",
"Z-Wave JS UI": "Z-Wave JS UI",
"Z-Wave JS UI admin login": "Administratörsinloggning för Z-Wave JS UI",
"ZFS ARC config removed (kernel defaults will apply on reboot)": "ZFS ARC-konfigurationen togs bort (kärnans standardinställningar gäller vid omstart)",
"ZFS ARC maximum configured:": "ZFS ARC maximalt konfigurerat:",
"ZFS ARC optimization completed": "ZFS ARC-optimering slutförd",
@@ -8425,6 +8476,7 @@
"could not be compiled for kernel": "kunde inte kompileras för kärnan",
"could not validate NVIDIA; exit code": "kan inte validera NVIDIA; exitkod",
"cpuunits must be between 8 and 10000": "cpuunits måste vara mellan 8 och 10000",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf": "curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"custom": "anpassade",
"custom dependency commands are not yet supported": "Anpassade beroendekommandon stöds ännu inte",
"custom path(s) saved.": "anpassade sökvägar har sparats.",
@@ -8631,6 +8683,7 @@
"kexec-tools is not installed or already removed.": "kexec-tools är inte installerat eller redan borttaget.",
"layers": "Lager",
"legacy .link file(s) to the ProxMenux-managed format": "äldre .link-fil(er) till det ProxMenux-hanterade formatet",
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.": "llama.cpp visar alla GGUF-modeller som sparats i /models i sitt webbgränssnitt och läser in den du väljer.",
"log2ram completely removed from system": "log2ram helt borttagen från systemet",
"main container of the application": "applikationens huvudbehållare",
"make cloned mount tree read-only": "gör det klonade monteringsträdet skrivskyddat",
+69
View File
@@ -0,0 +1,69 @@
# Automatic catalog refresh
Opening OCI Manager displays its local catalog immediately and starts a separate
worker. The menu shows the available total, additions since the last displayed
catalog, and changed recipes. Returning from a search or installation does not
start another download. A running wizard keeps the catalog it started with.
The menu also offers **Refresh catalog** to check again manually or retry after
a connection failure. Selecting it during a refresh does not start a second worker.
Manual refresh bypasses the conditional check and verifies the complete manifest,
allowing it to repair damaged cached files even when the upstream revision has not
changed. A repaired snapshot gets a separate immutable directory so existing
readers retain their original snapshot until they return to the menu. Each
Catalog reader holds an OS file-lock lease. Every worker run, including unchanged
checks and failed downloads, prunes snapshots that are neither a channel's active
snapshot nor leased by an open reader. Reader exit or a crash releases its lease
automatically. Snapshot selection, publication and pruning share a short local
lock; opening a menu never waits for the worker's network lock.
The worker checks the latest commit affecting `oci/catalog` in the official
MacRimi/ProxMenux repository. GitHub's ETag avoids repeated transfers. When the
revision changes, its immutable Git tree supplies the file manifest. Only changed
JSON files are downloaded from that commit; Git blob hashes and sizes are checked.
The complete snapshot, including overlays, categories, volume policy and
verification records, is validated before publishing its pointer atomically.
Runtime Python or shell files are never downloaded by catalog refresh.
State and snapshots live in `/usr/local/share/proxmenux/oci/catalog-cache`, outside
the engine replaced by the normal ProxMenux updater. The bundled catalog remains
the fallback. A network failure, incomplete manifest, invalid recipe, different
template schema or unsupported catalog engine API leaves the previous catalog
active. The private `CHANNEL-result.json` records the diagnostic.
The revision, snapshot and ETag are committed together in one atomic pointer;
failure to publish it cannot acknowledge an update that was not applied.
The channel follows `install_branch`, an active beta program or `beta_version.txt`;
otherwise it is `main`. A host can explicitly select `main` or `develop` with
`/usr/local/share/proxmenux/oci/catalog-source.json`:
```json
{"channel": "develop", "local_apps": ["my-local-preview"]}
```
`local_apps` optionally keeps explicitly named bundled preview recipes available
when they are absent upstream. These are local overrides, not automatic retention
of withdrawn upstream applications. An upstream recipe with the same ID wins.
The first visit uses the bundled/current catalog as its baseline. Additions are
compared by application ID, not net growth, and only visible installable entries
are counted, using the same rule as the existing menu. A downloaded catalog is
acknowledged only after the menu displays it. Exiting during a download therefore
preserves its news for the next visit. The new-app count remains visible throughout
the current visit and becomes zero on the next visit after acknowledgement.
Downloaded recipes are also checked against the top-level `installer_profile`
keys used by the engine's bundled apps, curated recipes and overlays. A new app
using an unknown key is silently excluded; an existing app retains its previous
compatible, fully composed recipe and its matching settings. Hidden entries do
not contribute to the available/new counters, and retaining an old recipe does
not count it as an update. When a ProxMenux update adds support for that key, the
next background check re-evaluates the catalog even at the same remote revision.
This is a conservative key-presence gate, not validation of new values or nested
options of an already known key. Changes in meaning still require `engine_api`.
Catalog maintainers must increase `catalog/compatibility.json`'s `engine_api` when
recipes require incompatible runtime capabilities. The consumer currently
supports API 1. Changes to the template schema also require a ProxMenux engine
update. Catalog delivery alone neither changes installed CTs nor applies a new
recipe to an existing deployment; the established management actions remain in
charge of those changes.
+6
View File
@@ -1117,3 +1117,9 @@ have not been tested. No custom supervisor or image entrypoint is introduced.
DeepSeek OCR remains deferred at the user's request: registry inspection on
2026-09-14 found only `v2.2.0` for both IceWhaleTech images and no `latest` tag.
No fixed-version exception or deployment has been introduced.
## Automatic catalog refresh
OCI Manager opens with its local catalog and checks for new applications and recipes
in the background. **Refresh catalog** repeats the check manually. See
[Automatic catalog refresh](CATALOG-REFRESH.md) for caching, channels and compatibility.
+9 -1
View File
@@ -2,7 +2,7 @@
<!-- Generated from oci/catalog/verification.json by .github/scripts/oci_validation.py. Do not edit by hand. -->
44 of 532 applications in the OCI catalog have been tested for real: 41 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
52 of 554 applications in the OCI catalog have been tested for real: 49 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
Each test describes the scenario that was run and names the image it ran on. It does not cover every possible configuration of the application, and a newer image has not been tested until someone reports it.
@@ -38,6 +38,7 @@ Questions and ideas about OCI testing go in [discussion #440](https://github.com
| Alby Hub ✨ | Finance & Budgeting |
| Alist | Files & Sharing |
| aMule | Files & Downloads |
| Authentik | Authentication & Security |
| Chromium | Browsers & Web Desktops |
| CodeProject.AI Server | AI |
| CopyParty | Files & Sharing |
@@ -50,26 +51,33 @@ Questions and ideas about OCI testing go in [discussion #440](https://github.com
| Flexget | *Arr Suite |
| Frigate | NVR & Cameras |
| Grafana | Monitoring & Analytics |
| HAOS One | IoT & Smart Home |
| Immich | Media |
| JDownloader | Files & Downloads |
| Jenkins CI/CD | AI / Coding & Dev-Tools |
| Linkwarden | Documents & Notes |
| Mariadb | Databases |
| Memos | Documents & Notes |
| MineOS | Gaming & Leisure |
| Motioneye | NVR & Cameras |
| Navidrome | Media & Streaming |
| Nextcloud | Productivity & Workflows |
| Nextcloud Stack | Productivity & Workflows |
| OpenList | Files & Sharing |
| Openssh Server | Remote Access & VPN |
| Paperless-ngx | Productivity & Workflows |
| Phpmyadmin | Databases |
| Prowlarr | *Arr Suite |
| Qbittorrent | Files & Downloads |
| Rclone WebUI | Backup & Recovery |
| Real-Debrid Torrent Client | Files & Downloads |
| Scanopy | Network & Firewall |
| ShareCoveX | Files & Sharing |
| SnapOtter | Media & Streaming |
| Sonarr | *Arr Suite |
| Tandoor Recipes | Productivity & Workflows |
| Thelounge | Communication & Community |
| Trilium | Documents & Notes |
| Vaultwarden | Authentication & Security |
| Wireguard | Remote Access & VPN |
| WireGuard Easy | Remote Access & VPN |
@@ -323,6 +323,9 @@
"AceStream HTTP Proxy has no web interface: a media player opens its streams.",
"HLS stream: port 6878, path /ace/manifest.m3u8?id= followed by the channel ID.",
"MPEG-TS stream: port 6878, path /ace/getstream?id= followed by the channel ID."
],
"non_persistent_image_volumes": [
"/home/appuser/.ACEStream"
]
}
},
+585
View File
@@ -0,0 +1,585 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-airdcpp-webclient",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "AirDC++ Web Client",
"es_ES": "AirDC++ Web Client"
},
"tagline": {
"en_US": "Direct Connect file sharing with a web interface",
"es_ES": "Intercambio de archivos Direct Connect con interfaz web"
},
"description": {
"en_US": "AirDC++ Web Client using the community-maintained gangefors image. Configuration, downloads and shared content use separate persistent paths.",
"es_ES": "AirDC++ Web Client con la imagen comunitaria de gangefors. La configuración, las descargas y los archivos compartidos usan rutas persistentes separadas."
},
"category": "downloads",
"category_label": "Files & Downloads",
"author": "gangefors",
"developer": "AirDC++",
"icon": "https://raw.githubusercontent.com/airdcpp-web/airdcpp-webui/eeeea5025a5e720f38dac53ced8e002940f00a74/resources/images/logo.svg",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64"
],
"launch": {
"scheme": "http",
"port": 5600,
"path": "/"
},
"website": "https://airdcpp-web.github.io/",
"documentation": "https://github.com/gangefors/docker-airdcpp-webclient",
"repository": "https://github.com/gangefors/docker-airdcpp-webclient",
"tips": [
"The upstream initial login is admin / password. Change it in Settings > System > Users before allowing access beyond a trusted LAN.",
"Configuration uses /.airdcpp on a managed Proxmox volume included in backups. /Downloads and /Share can use managed volumes or explicitly selected host directories.",
"Files under /Share are shared by AirDC++. Select the contents deliberately; router forwarding and hub configuration are separate administrator actions.",
"PUID and PGID default to 1000 and must be at least 101. The original entrypoint creates the application account; volume ownership follows these values.",
"Open HTTP port 5600 on the dedicated LXC address. HTTPS port 5601 uses the upstream self-signed certificate; use a trusted reverse proxy certificate for remote web access.",
"Incoming Direct Connect traffic uses TCP and UDP 21248 and TLS TCP 21249. ProxMenux keeps those native ports and does not configure your router."
],
"mini_changelog": [],
"display_version": null,
"updated_at": "2026-10-25"
},
"source": {
"provider": "gangefors",
"repository": "https://github.com/gangefors/docker-airdcpp-webclient",
"revision": "37f2e939c152fb2c0158bc83bc76cc972aed965e",
"image_repository_url": "https://hub.docker.com/r/gangefors/airdcpp-webclient",
"readme_pushed_at": "2026-10-25T11:51:53Z",
"compose_sha256": "4ce8aec542cfc3e7f5ca142e309a41f04aca444bd1724ca1741c96acb5c3d5bf",
"generated_at": "2026-11-03T11:47:04+00:00",
"default_branch": "master",
"readme_raw_url": "https://raw.githubusercontent.com/gangefors/docker-airdcpp-webclient/37f2e939c152fb2c0158bc83bc76cc972aed965e/docker-compose.yml"
},
"container_contract": {
"service_name": "airdcpp",
"container_name": "airdcpp",
"image": {
"reference": "docker.io/gangefors/airdcpp-webclient:latest",
"registry": "docker.io",
"repository": "docker.io/gangefors/airdcpp-webclient",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "0022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
}
],
"volumes": [
{
"id": "config",
"container_path": "/.airdcpp",
"compose_source_example": "./config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
},
{
"id": "downloads",
"container_path": "/Downloads",
"compose_source_example": "./downloads",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 32
}
},
{
"id": "share",
"container_path": "/Share",
"compose_source_example": "./share",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 32
}
}
],
"ports": [
{
"container_port": 5600,
"published_example": 5600,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 5601,
"published_example": 5601,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 21248,
"published_example": 21248,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 21248,
"published_example": 21248,
"protocol": "udp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 21249,
"published_example": 21249,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "name: airdcpp-webclient\nservices:\n airdcpp:\n image: docker.io/gangefors/airdcpp-webclient:latest\n restart: unless-stopped\n environment:\n PUID: '1000'\n PGID: '1000'\n UMASK: '0022'\n ports:\n - 5600:5600\n - 5601:5601\n - 21248:21248/tcp\n - 21248:21248/udp\n - 21249:21249/tcp\n volumes:\n - ./config:/.airdcpp\n - ./downloads:/Downloads\n - ./share:/Share\n"
},
"compose_stack": {
"project_name": "airdcpp-webclient",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "airdcpp",
"service_count": 1,
"services": [
{
"name": "airdcpp",
"image": "docker.io/gangefors/airdcpp-webclient:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "docker.io/gangefors/airdcpp-webclient:latest",
"restart": "unless-stopped",
"environment": {
"PUID": "1000",
"PGID": "1000",
"UMASK": "0022"
},
"ports": [
"5600:5600",
"5601:5601",
"21248:21248/tcp",
"21248:21248/udp",
"21249:21249/tcp"
],
"volumes": [
"./config:/.airdcpp",
"./downloads:/Downloads",
"./share:/Share"
]
}
}
],
"top_level": {
"name": "airdcpp-webclient"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "airdcpp-volume-0",
"service": "airdcpp",
"container_path": "/.airdcpp",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "airdcpp-volume-1",
"service": "airdcpp",
"container_path": "/Downloads",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "airdcpp-volume-2",
"service": "airdcpp",
"container_path": "/Share",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"airdcpp"
],
"stop_order": [
"airdcpp"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "http",
"port": 5600,
"path": "/",
"source": "https://github.com/gangefors/docker-airdcpp-webclient"
}
],
"credentials": [
{
"label": "AirDC++ administrator",
"type": "static-default",
"username": "admin",
"password": "password",
"change_required": true,
"source": "https://github.com/gangefors/docker-airdcpp-webclient#run-the-application"
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/.airdcpp",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/Downloads",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/Share",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 5600,
"path": "/index.html",
"timeout_seconds": 180,
"request_timeout_seconds": 5,
"stability_seconds": 4,
"verify_tls": true
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community image and single-LXC contract reviewed against the publisher Compose and entrypoint; Linux amd64 confirmed in the registry manifest. Runtime lifecycle checks remain pending."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending",
"authenticated_login": "pending",
"advanced_install": "pending",
"host_bind_storage": "pending",
"managed_storage": "pending",
"removal": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+453
View File
@@ -0,0 +1,453 @@
{
"schema_version": "0.4.0",
"kind": "proxmenux.oci-template",
"id": "image-authelia",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Authelia",
"es_ES": "Authelia"
},
"tagline": {
"en_US": "Single sign-on and multi-factor authentication",
"es_ES": "Inicio de sesión único y autenticación multifactor"
},
"description": {
"en_US": "An open-source authentication and authorization server for protecting web applications. This single-image profile provides a local SQLite database and file notifications; configure your domain, reverse proxy and access rules before protecting other services.",
"es_ES": "Servidor de autenticación y autorización de código abierto para proteger aplicaciones web. Este perfil de una sola imagen incluye una base de datos SQLite local y notificaciones en archivo; configura el dominio, el proxy inverso y las reglas de acceso antes de proteger otros servicios."
},
"category": "security",
"category_label": "Authentication & Security",
"author": "Authelia",
"developer": "Authelia",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/authelia.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 9091,
"path": "/"
},
"website": "https://www.authelia.com/",
"documentation": "https://www.authelia.com/integration/deployment/docker/",
"repository": "https://github.com/authelia/authelia",
"tips": [
"The installer creates a unique admin password and stores only its Argon2id hash in /config/users_database.yml. The password is shown in the installation result.",
"Authelia requires an HTTPS portal URL and a cookie domain matching that hostname. If you use Nginx Proxy Manager, follow the official integration guide and configure trusted proxies and forward-auth separately.",
"The default notifier writes messages to /config/notification.txt. Configure SMTP in /config/configuration.yml if you want email delivery.",
"The initial access-control policy is one_factor. Add explicit access-control rules before attaching Authelia to protected proxy hosts."
],
"mini_changelog": [],
"display_version": "4.39.28",
"updated_at": "2026-09-17"
},
"source": {
"provider": "authelia",
"repository": "https://github.com/authelia/authelia",
"default_branch": "master",
"revision": "8da42b2348b0351c6284a2940a9c5eec3d4cd3fd",
"readme_raw_url": "https://raw.githubusercontent.com/authelia/authelia/v4.39.28/examples/compose/lite/compose.yml",
"readme_pushed_at": "2026-09-17T12:13:30Z",
"compose_sha256": "848ce0f70e502981a050ac200d9d1882978a6c3b0f9f0dfcc6d52ce66ca37fb5",
"generated_at": "2026-11-03T09:10:57+00:00",
"image_repository_url": "https://hub.docker.com/r/authelia/authelia"
},
"container_contract": {
"service_name": "authelia",
"container_name": "authelia",
"image": {
"reference": "docker.io/authelia/authelia:4.39.28",
"registry": "docker.io",
"repository": "docker.io/authelia/authelia",
"tag": "4.39.28",
"digest": null,
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
},
"environment": [
{
"name": "PROXMENUX_ADMIN_PASSWORD",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-first-start"
},
{
"name": "AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "AUTHELIA_SESSION_SECRET",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "AUTHELIA_STORAGE_ENCRYPTION_KEY",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "X_AUTHELIA_CONFIG_FILTERS",
"example": "template",
"required": true,
"sensitive": false,
"source": "authelia-container"
},
{
"name": "PROXMENUX_AUTHELIA_COOKIE_DOMAIN",
"example": "",
"prompt": "Authelia session cookie domain for this portal (for example example.com)",
"required": true,
"sensitive": false,
"source": "administrator"
},
{
"name": "PROXMENUX_AUTHELIA_URL",
"example": "",
"prompt": "Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)",
"required": true,
"sensitive": false,
"source": "administrator"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./authelia",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
}
],
"ports": [
{
"container_port": 9091,
"published_example": 9091,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n authelia:\n entrypoint:\n - /bin/sh\n - /usr/local/bin/proxmenux-authelia-bootstrap\n environment:\n AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET: ${GENERATED_RESET_PASSWORD_JWT_SECRET}\n AUTHELIA_SESSION_SECRET: ${GENERATED_SESSION_SECRET}\n AUTHELIA_STORAGE_ENCRYPTION_KEY: ${GENERATED_STORAGE_ENCRYPTION_KEY}\n PROXMENUX_ADMIN_PASSWORD: ${GENERATED_ADMIN_PASSWORD}\n PROXMENUX_AUTHELIA_COOKIE_DOMAIN: ${AUTHELIA_COOKIE_DOMAIN}\n PROXMENUX_AUTHELIA_URL: ${AUTHELIA_URL}\n X_AUTHELIA_CONFIG_FILTERS: template\n image: docker.io/authelia/authelia:4.39.28\n ports:\n - 9091:9091\n restart: unless-stopped\n volumes:\n - ./authelia:/config\n"
},
"first_run": {
"endpoints": [
{
"label": "Authelia Web UI",
"scheme": "http",
"port": 9091,
"path": "/",
"source": "official-image"
}
],
"credentials": [
{
"label": "Authelia administrator",
"type": "configured-or-installer-generated",
"username": "admin",
"password": null,
"password_environment": "PROXMENUX_ADMIN_PASSWORD",
"change_required": false,
"source": "Generated on first start and stored as an Argon2id hash in the persistent users file."
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 512,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 60
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"runtime": {
"compose_entrypoint": [
"/bin/sh",
"/usr/local/bin/proxmenux-authelia-bootstrap"
]
},
"generated_sensitive_environment": {
"PROXMENUX_ADMIN_PASSWORD": {
"strategy": "token-hex",
"bytes": 24,
"prompt": false
},
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"AUTHELIA_SESSION_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"AUTHELIA_STORAGE_ENCRYPTION_KEY": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
}
},
"minimum_secret_length": {
"PROXMENUX_ADMIN_PASSWORD": 24,
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET": 32,
"AUTHELIA_SESSION_SECRET": 32,
"AUTHELIA_STORAGE_ENCRYPTION_KEY": 32
},
"generated_files": [
{
"container_path": "/config/configuration.yml",
"mode": "0600",
"owner": "mapped-root",
"only_if_missing": true,
"content": "---\nserver:\n address: 'tcp://:9091'\n\nlog:\n level: 'info'\n\ntotp:\n issuer: 'Authelia'\n\nidentity_validation:\n reset_password:\n jwt_secret: 'configured-by-environment'\n\nauthentication_backend:\n file:\n path: '/config/users_database.yml'\n watch: true\n\naccess_control:\n default_policy: 'one_factor'\n\nsession:\n secret: 'configured-by-environment'\n cookies:\n - name: 'authelia_session'\n domain: '{{ env \"PROXMENUX_AUTHELIA_COOKIE_DOMAIN\" }}'\n authelia_url: '{{ env \"PROXMENUX_AUTHELIA_URL\" }}'\n expiration: '1 hour'\n inactivity: '5 minutes'\n\nstorage:\n encryption_key: 'configured-by-environment'\n local:\n path: '/config/db.sqlite3'\n\nnotifier:\n filesystem:\n filename: '/config/notification.txt'\n"
},
{
"container_path": "/usr/local/bin/proxmenux-authelia-bootstrap",
"mode": "0700",
"owner": "mapped-root",
"only_if_missing": false,
"content": "#!/bin/sh\nset -eu\numask 077\n\nusers_file=/config/users_database.yml\nif [ ! -s \"$users_file\" ]; then\n : \"${PROXMENUX_ADMIN_PASSWORD:?ProxMenux did not provide an initial administrator password}\"\n mkdir -p /config\n hash_output=$(authelia crypto hash generate argon2 --password \"$PROXMENUX_ADMIN_PASSWORD\" --no-confirm)\n password_hash=$(printf '%s\\n' \"$hash_output\" | sed -n 's/^Digest: //p')\n case \"$password_hash\" in\n '$argon2id$'*) ;;\n *) printf '%s\\n' 'Authelia did not return an Argon2id password hash' >&2; exit 1 ;;\n esac\n temporary_file=\"${users_file}.tmp.$$\"\n cat >\"$temporary_file\" <<EOF\nusers:\n admin:\n disabled: false\n displayname: 'Authelia Administrator'\n password: \"$password_hash\"\n groups:\n - 'admins'\nEOF\n chmod 0600 \"$temporary_file\"\n mv -f \"$temporary_file\" \"$users_file\"\nfi\nunset PROXMENUX_ADMIN_PASSWORD\nexec /app/entrypoint.sh \"$@\"\n"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 9091,
"path": "/api/health",
"timeout_seconds": 240,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"adaptations": [
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "The application listens on the same container ports at its dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Users open the LXC address instead of the Proxmox host address.",
"validation": "pending-per-application"
},
{
"id": "compose-environment-overlay",
"upstream_behavior": "Compose environment values override OCI image environment values.",
"native_lxc_behavior": "ProxMenux merges the same values into lxc.environment.runtime while the CT is stopped.",
"reason": "PVE imports image Env automatically; Compose values still need to override it.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "stop-grace-period",
"upstream_behavior": "Docker waits for Compose stop_grace_period before forcing termination.",
"native_lxc_behavior": "ProxMenux records the same timeout for its pct shutdown lifecycle operations.",
"reason": "Proxmox has no equivalent per-CT persistent restart-policy field; startup.down is not a shutdown timeout.",
"behavioral_impact": "Normal Proxmox node shutdown remains governed by the node-wide shutdown policy.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "pending-per-application"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "A single-image profile for the Authelia authentication portal. ProxMenux creates a unique initial administrator account; the local notifier and SQLite storage are kept in /config. Reverse-proxy trust and explicit access-control rules remain administrator settings."
},
"validation": {
"schema": "pending-local-validation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "replace-rootfs-from-new-oci-image-preserve-managed-volumes",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+62 -2
View File
@@ -76,6 +76,38 @@
"backup": true,
"default_size_gb": 2
}
},
{
"id": "volume-1",
"container_path": "/etc/bind",
"compose_source_example": "./config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
},
{
"id": "volume-2",
"container_path": "/var/lib/bind",
"compose_source_example": "./lib",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
@@ -123,7 +155,9 @@
"53:53/tcp"
],
"volumes": [
"./bind:/var/cache/bind"
"./bind:/var/cache/bind",
"./config:/etc/bind",
"./lib:/var/lib/bind"
]
}
}
@@ -151,6 +185,28 @@
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "bind9-volume-1",
"service": "bind9",
"container_path": "/etc/bind",
"mode": "managed-volume",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "bind9-volume-2",
"service": "bind9",
"container_path": "/var/lib/bind",
"mode": "managed-volume",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
@@ -349,7 +405,11 @@
"validation": "not-requested-by-compose"
}
],
"installer_profile": {},
"installer_profile": {
"non_persistent_image_volumes": [
"/var/log"
]
},
"catalog": {
"replaces_discovered_ids": []
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-cadcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "CADCraft",
"es_ES": "CADCraft"
},
"tagline": {
"en_US": "Computer-aided design and drafting in your browser",
"es_ES": "Diseño CAD y dibujo técnico en el navegador"
},
"description": {
"en_US": "CADCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "CADCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/cadcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/cadcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/cadcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/cadcraft",
"readme_pushed_at": "",
"compose_sha256": "ab46cb8e87addb261680a50fc8bdde1f9d689a0d14f6ca570eaf11e43868655a",
"generated_at": "2026-11-03T12:57:27+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/cadcraft.yaml"
},
"container_contract": {
"service_name": "cadcraft",
"container_name": "cadcraft",
"image": {
"reference": "docker.io/junkerderprovinz/cadcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/cadcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n cadcraft:\n image: junkerderprovinz/cadcraft:latest\n container_name: cadcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "cadcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "cadcraft",
"service_count": 1,
"services": [
{
"name": "cadcraft",
"image": "junkerderprovinz/cadcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/cadcraft:latest",
"container_name": "cadcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "cadcraft-volume-0",
"service": "cadcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "cadcraft-volume-1",
"service": "cadcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"cadcraft"
],
"stop_order": [
"cadcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+7 -1
View File
@@ -339,7 +339,13 @@
"validation": "not-requested-by-compose"
}
],
"installer_profile": {}
"installer_profile": {
"non_persistent_image_volumes": [
"/etc/chrony",
"/run/chrony",
"/var/lib/chrony"
]
}
},
"compatibility": {
"automatic_install_candidate": true,
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-deckcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "DeckCraft",
"es_ES": "DeckCraft"
},
"tagline": {
"en_US": "Presentations and slide decks in your browser",
"es_ES": "Presentaciones y diapositivas en el navegador"
},
"description": {
"en_US": "DeckCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "DeckCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/deckcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/deckcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/deckcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/deckcraft",
"readme_pushed_at": "",
"compose_sha256": "38d24b673dd5fb50e00d1094e681112671cf04a8e99952021f476c8b2754ef05",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/deckcraft.yaml"
},
"container_contract": {
"service_name": "deckcraft",
"container_name": "deckcraft",
"image": {
"reference": "docker.io/junkerderprovinz/deckcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/deckcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n deckcraft:\n image: junkerderprovinz/deckcraft:latest\n container_name: deckcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "deckcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "deckcraft",
"service_count": 1,
"services": [
{
"name": "deckcraft",
"image": "junkerderprovinz/deckcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/deckcraft:latest",
"container_name": "deckcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "deckcraft-volume-0",
"service": "deckcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "deckcraft-volume-1",
"service": "deckcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"deckcraft"
],
"stop_order": [
"deckcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-designcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "DesignCraft",
"es_ES": "DesignCraft"
},
"tagline": {
"en_US": "Page layout and publishing in your browser",
"es_ES": "Maquetación y publicación en el navegador"
},
"description": {
"en_US": "DesignCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "DesignCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/designcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/designcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/designcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/designcraft",
"readme_pushed_at": "",
"compose_sha256": "68fdc2548c3ecedc792ff41e1ce7002d8f0219e78781b89265ce77761685a0fd",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/designcraft.yaml"
},
"container_contract": {
"service_name": "designcraft",
"container_name": "designcraft",
"image": {
"reference": "docker.io/junkerderprovinz/designcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/designcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n designcraft:\n image: junkerderprovinz/designcraft:latest\n container_name: designcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "designcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "designcraft",
"service_count": 1,
"services": [
{
"name": "designcraft",
"image": "junkerderprovinz/designcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/designcraft:latest",
"container_name": "designcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "designcraft-volume-0",
"service": "designcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "designcraft-volume-1",
"service": "designcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"designcraft"
],
"stop_order": [
"designcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-effectcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "EffectCraft",
"es_ES": "EffectCraft"
},
"tagline": {
"en_US": "Motion graphics and compositing in your browser",
"es_ES": "Animación gráfica y composición en el navegador"
},
"description": {
"en_US": "EffectCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "EffectCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/effectcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/effectcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/effectcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/effectcraft",
"readme_pushed_at": "",
"compose_sha256": "8dde56d083a5120e342967f15141e95d742d19ea0c6b782c5552d40438b46ef7",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/effectcraft.yaml"
},
"container_contract": {
"service_name": "effectcraft",
"container_name": "effectcraft",
"image": {
"reference": "docker.io/junkerderprovinz/effectcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/effectcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n effectcraft:\n image: junkerderprovinz/effectcraft:latest\n container_name: effectcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "effectcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "effectcraft",
"service_count": 1,
"services": [
{
"name": "effectcraft",
"image": "junkerderprovinz/effectcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/effectcraft:latest",
"container_name": "effectcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "effectcraft-volume-0",
"service": "effectcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "effectcraft-volume-1",
"service": "effectcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"effectcraft"
],
"stop_order": [
"effectcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-figcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "FigCraft",
"es_ES": "FigCraft"
},
"tagline": {
"en_US": "Interface design and prototyping in your browser",
"es_ES": "Diseño de interfaces y prototipos en el navegador"
},
"description": {
"en_US": "FigCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "FigCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/figcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/figcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/figcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/figcraft",
"readme_pushed_at": "",
"compose_sha256": "b47cfa4e01943f509964b0027b9385d00fe6d233d31e24cdc117a4a4dd153262",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/figcraft.yaml"
},
"container_contract": {
"service_name": "figcraft",
"container_name": "figcraft",
"image": {
"reference": "docker.io/junkerderprovinz/figcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/figcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n figcraft:\n image: junkerderprovinz/figcraft:latest\n container_name: figcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "figcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "figcraft",
"service_count": 1,
"services": [
{
"name": "figcraft",
"image": "junkerderprovinz/figcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/figcraft:latest",
"container_name": "figcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "figcraft-volume-0",
"service": "figcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "figcraft-volume-1",
"service": "figcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"figcraft"
],
"stop_order": [
"figcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-filmcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "FilmCraft",
"es_ES": "FilmCraft"
},
"tagline": {
"en_US": "Video editing in your browser",
"es_ES": "Edición de vídeo en el navegador"
},
"description": {
"en_US": "FilmCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "FilmCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/filmcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/filmcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/filmcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/filmcraft",
"readme_pushed_at": "",
"compose_sha256": "fa1e82ca686a530579d91c9d75184adb800453607baee37ad15ac3cfbf39d746",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/filmcraft.yaml"
},
"container_contract": {
"service_name": "filmcraft",
"container_name": "filmcraft",
"image": {
"reference": "docker.io/junkerderprovinz/filmcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/filmcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n filmcraft:\n image: junkerderprovinz/filmcraft:latest\n container_name: filmcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "filmcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "filmcraft",
"service_count": 1,
"services": [
{
"name": "filmcraft",
"image": "junkerderprovinz/filmcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/filmcraft:latest",
"container_name": "filmcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "filmcraft-volume-0",
"service": "filmcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "filmcraft-volume-1",
"service": "filmcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"filmcraft"
],
"stop_order": [
"filmcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+4 -1
View File
@@ -409,7 +409,10 @@
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"non_persistent_image_volumes": [
"/gotosocial/.cache"
]
}
},
"compatibility": {
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-gridcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "GridCraft",
"es_ES": "GridCraft"
},
"tagline": {
"en_US": "Spreadsheets in your browser",
"es_ES": "Hojas de cálculo en el navegador"
},
"description": {
"en_US": "GridCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "GridCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/gridcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/gridcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/gridcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/gridcraft",
"readme_pushed_at": "",
"compose_sha256": "dcd244dd54033b4a00e1220ff8885ba26a5508414ab5069f7ab9456476fbb420",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/gridcraft.yaml"
},
"container_contract": {
"service_name": "gridcraft",
"container_name": "gridcraft",
"image": {
"reference": "docker.io/junkerderprovinz/gridcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/gridcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n gridcraft:\n image: junkerderprovinz/gridcraft:latest\n container_name: gridcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "gridcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "gridcraft",
"service_count": 1,
"services": [
{
"name": "gridcraft",
"image": "junkerderprovinz/gridcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/gridcraft:latest",
"container_name": "gridcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "gridcraft-volume-0",
"service": "gridcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "gridcraft-volume-1",
"service": "gridcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"gridcraft"
],
"stop_order": [
"gridcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+5 -1
View File
@@ -345,7 +345,11 @@
"validation": "not-requested-by-compose"
}
],
"installer_profile": {},
"installer_profile": {
"non_persistent_image_volumes": [
"/tmp"
]
},
"catalog": {
"replaces_discovered_ids": []
}
+35 -1
View File
@@ -94,6 +94,22 @@
"backup": true,
"default_size_gb": 8
}
},
{
"id": "volume-2",
"container_path": "/etc/nginx/ssl",
"compose_source_example": "./ssl",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
@@ -134,7 +150,8 @@
],
"volumes": [
"./data:/var/www/app/data",
"./plugins:/var/www/app/plugins"
"./plugins:/var/www/app/plugins",
"./ssl:/etc/nginx/ssl"
]
}
}
@@ -171,6 +188,17 @@
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "kanboard-volume-2",
"service": "kanboard",
"container_path": "/etc/nginx/ssl",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
@@ -391,6 +419,12 @@
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/etc/nginx/ssl",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
+383
View File
@@ -0,0 +1,383 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-kitchenowl",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "KitchenOwl"
},
"tagline": {
"en_US": "Self-hosted grocery list and recipe manager"
},
"description": {
"en_US": "Manage shared shopping lists, recipes and meal plans in one self-hosted app."
},
"category": "productivity",
"category_label": "Productivity & Workflows",
"author": "Tom Bursch",
"developer": "Tom Bursch",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/kitchenowl.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 80,
"path": "/"
},
"website": "https://kitchenowl.org/",
"documentation": "https://docs.kitchenowl.org/self-hosting/",
"repository": "https://github.com/TomBursch/kitchenowl",
"tips": [
"This recipe follows KitchenOwl’s standard official Compose deployment: a web frontend and backend in separate OCI LXCs.",
"The upstream sample uses PLEASE_CHANGE_ME for JWT_SECRET_KEY; this recipe generates a unique signing key at install time."
],
"mini_changelog": [],
"display_version": null,
"updated_at": "2026-11-01"
},
"source": {
"provider": "tombursch",
"repository": "https://github.com/TomBursch/kitchenowl",
"revision": "60a012ea5cae829878f78a46a585a7ee530b069a",
"image_repository_url": "https://hub.docker.com/r/tombursch/kitchenowl-web",
"readme_pushed_at": "2026-11-01T23:22:22Z",
"compose_sha256": "f620124c2a4943d4f2465ee304677bc9ed172a088f0fe43f5db7cbc8f6424263",
"generated_at": "2026-11-02T20:13:05+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/TomBursch/kitchenowl/main/docker-compose.yml"
},
"container_contract": {
"service_name": "front",
"container_name": "front",
"image": {
"reference": "tombursch/kitchenowl-web:latest",
"registry": "docker.io",
"repository": "tombursch/kitchenowl-web",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [],
"volumes": [],
"ports": [
{
"container_port": 80,
"published_example": 80,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [
{
"name": "back",
"image": "tombursch/kitchenowl-backend:latest"
}
],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n back:\n environment:\n JWT_SECRET_KEY: ${GENERATED_JWT_SECRET_KEY}\n image: tombursch/kitchenowl-backend:latest\n restart: unless-stopped\n volumes:\n - read_only: false\n source: kitchenowl_data\n target: /data\n front:\n depends_on:\n - back\n image: tombursch/kitchenowl-web:latest\n ports:\n - 80:80\n restart: unless-stopped\n volumes: []\nvolumes:\n kitchenowl_data: null\n"
},
"compose_stack": {
"project_name": "kitchenowl",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "front",
"service_count": 2,
"services": [
{
"name": "back",
"image": "tombursch/kitchenowl-backend:latest",
"is_main": false,
"role": "dependency",
"vmid_offset": 1,
"depends_on": [],
"frontend_network": false,
"private_network": true,
"compose": {
"environment": {
"JWT_SECRET_KEY": "${GENERATED_JWT_SECRET_KEY}"
},
"image": "tombursch/kitchenowl-backend:latest",
"restart": "unless-stopped",
"volumes": [
{
"source": "kitchenowl_data",
"target": "/data",
"read_only": false
}
],
"healthcheck": {
"test": [
"CMD-SHELL",
"uwsgi_curl localhost:5000 /api/health/8M4F88S8ooi4sMbLBfkkV7ctWwgibW6V || exit 1"
],
"interval": "60s",
"timeout": "3s",
"retries": 3
}
}
},
{
"name": "front",
"image": "tombursch/kitchenowl-web:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [
"back"
],
"frontend_network": true,
"private_network": true,
"compose": {
"depends_on": [
"back"
],
"image": "tombursch/kitchenowl-web:latest",
"ports": [
"80:80"
],
"restart": "unless-stopped",
"volumes": [],
"healthcheck": {
"test": [
"CMD-SHELL",
"curl -f http://localhost/ || exit 1"
],
"interval": "30s",
"timeout": "3s",
"retries": 3
}
}
}
],
"top_level": {
"volumes": {
"kitchenowl_data": null
}
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": true,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "back-volume-0",
"service": "back",
"container_path": "/data",
"mode": "managed-volume",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 2,
"start_order": [
"back",
"front"
],
"stop_order": [
"front",
"back"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "generated-jwt-secret-key",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "back",
"environment_variable": "JWT_SECRET_KEY"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "KitchenOwl",
"scheme": "http",
"port": 80,
"path": "/",
"source": "upstream-documentation"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "generated-jwt-signing-key",
"upstream_behavior": "The official Compose example uses the placeholder PLEASE_CHANGE_ME for JWT_SECRET_KEY and instructs operators to replace it.",
"native_lxc_behavior": "ProxMenux generates a unique cryptographically random JWT signing key and supplies it to the backend service.",
"reason": "Avoid deploying the documented placeholder or placing a signing secret in the public recipe.",
"behavioral_impact": "The generated key is not an app login credential; KitchenOwl has no catalog-provided default account.",
"validation": "pending-runtime"
},
{
"id": "image-healthchecks-preserved",
"upstream_behavior": "The web and backend OCI images declare Docker healthchecks in image metadata.",
"native_lxc_behavior": "The current image healthchecks are recorded in the stack so ProxMenux can check backend readiness and frontend availability during first start.",
"reason": "The Compose file inherits these checks from its images instead of declaring them itself.",
"behavioral_impact": "Checks gate stack startup; Docker does not run as a separate health-monitoring daemon inside the LXCs.",
"validation": "pending-runtime"
}
],
"custom_compose_stack": true,
"custom_compose_interpolated": false,
"stack_image_entrypoints": {},
"installer_profile": {
"stack_driver": "generic-multi-lxc-stack",
"volume_preparations": [
{
"container_path": "/data",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
]
},
"stack_completion_notes": [
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured."
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "The official two-image Compose stack is mapped to native Proxmox OCI LXCs with private service networking. Lab checks confirmed installation, web/API behavior, persistence, backup and recovery, modification, managed storage, and host-bind storage. Advanced custom settings have not been validated."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "passed-default-official-two-service-stack-and-first-start",
"advanced_install": "pending-custom-install-summary-validation",
"service_health": "passed-web-api-and-created-user-household-list-item",
"restart_persistence": "passed-managed-and-host-bind-data",
"backup_restore": "passed-manager-recover-new-vmids-stack-network-and-data",
"update_preserves_data": "no-update-available-at-check",
"modification": "passed-added-managed-volume-without-image-pull-or-container-recreate",
"volumes": "passed-managed-storage-and-host-bind-with-owner-and-data-check",
"removal": "passed-manager-removal-temporary-data-cleaned-after-retention-check"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false,
"dependency_lifecycle": {
"implementation": "proxmox-hookscript",
"trigger": "main-lxc-pre-start",
"waits_for_dependency_healthchecks": true,
"stops_dependencies_with_main": false
}
}
}
+490
View File
@@ -0,0 +1,490 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-krusader",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Krusader",
"es_ES": "Krusader"
},
"tagline": {
"en_US": "KDE's twin-panel file manager in a browser-based desktop.",
"es_ES": "El gestor de archivos de dos paneles de KDE, disponible desde el navegador."
},
"description": {
"en_US": "Open Krusader in a browser and manage files from a directory you explicitly mount at /storage. The maintained jlesage image provides the graphical desktop; ProxMenux runs it as one native OCI LXC.",
"es_ES": "Abre Krusader en el navegador y gestiona los archivos de una carpeta que montes expresamente en /storage. La imagen mantenida por jlesage incluye el escritorio gráfico; ProxMenux la ejecuta como un LXC OCI nativo."
},
"category": "desktop",
"category_label": "Browsers & Web Desktops",
"author": "jlesage",
"developer": "jlesage",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/krusader.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 5800,
"path": "/"
},
"website": "https://krusader.org/",
"documentation": "https://github.com/jlesage/docker-krusader",
"repository": "https://github.com/jlesage/docker-krusader",
"tips": [
"The web login uses HTTPS with an automatically generated self-signed certificate and password. Accept the certificate warning on the first visit or configure a trusted certificate.",
"Krusader can read, change and delete files in the directory mounted at /storage. Mount only the directory you intend to manage; the rest of the Proxmox host is not exposed.",
"The VNC port is not published. Use the browser interface on port 5800."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "jlesage",
"repository": "https://github.com/jlesage/docker-krusader",
"revision": "855c8140e1bb65b2a2526d82db44c808f23eb49f",
"image_repository_url": "https://hub.docker.com/r/jlesage/krusader",
"readme_pushed_at": "2026-09-22T15:18:17Z",
"compose_sha256": "9dd16cc30aa19afe7e148598c9cfb0c65c31606d67f3f22254c33a4d05212c7f",
"generated_at": "2026-11-02T20:05:40+00:00",
"default_branch": "master",
"readme_raw_url": "https://raw.githubusercontent.com/jlesage/docker-krusader/855c8140e1bb65b2a2526d82db44c808f23eb49f/README.md"
},
"container_contract": {
"service_name": "krusader",
"container_name": "krusader",
"image": {
"reference": "jlesage/krusader:latest",
"registry": "docker.io",
"repository": "jlesage/krusader",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "USER_ID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-image-default"
},
{
"name": "GROUP_ID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-image-default"
},
{
"name": "TZ",
"example": "Europe/Madrid",
"required": true,
"sensitive": false,
"source": "ProxMenux-local-timezone"
},
{
"name": "VNC_LOCALHOST_ONLY",
"example": "1",
"required": true,
"sensitive": false,
"source": "upstream-image-security-setting"
},
{
"name": "WEB_AUTHENTICATION",
"example": "1",
"required": true,
"sensitive": false,
"source": "upstream-image-security-setting"
},
{
"name": "WEB_AUTHENTICATION_USERNAME",
"example": "admin",
"required": true,
"sensitive": false,
"source": "upstream-image-security-setting"
},
{
"name": "WEB_AUTHENTICATION_PASSWORD",
"example": "${GENERATED_WEB_PASSWORD}",
"required": true,
"sensitive": true,
"source": "ProxMenux-generated-credential"
},
{
"name": "SECURE_CONNECTION",
"example": "1",
"required": true,
"sensitive": false,
"source": "upstream-image-security-setting"
}
],
"volumes": [
{
"id": "krusader-config",
"container_path": "/config",
"compose_source_example": "krusader-config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
},
{
"id": "krusader-storage",
"container_path": "/storage",
"compose_source_example": "/mnt/oci-shared/krusader/storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "host-bind",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
}
],
"ports": [
{
"container_port": 5800,
"published_example": 5800,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "name: krusader\nservices:\n krusader:\n image: jlesage/krusader:latest\n container_name: krusader\n restart: unless-stopped\n environment:\n USER_ID: '1000'\n GROUP_ID: '1000'\n TZ: Europe/Madrid\n VNC_LOCALHOST_ONLY: '1'\n WEB_AUTHENTICATION: '1'\n WEB_AUTHENTICATION_USERNAME: admin\n WEB_AUTHENTICATION_PASSWORD: ${GENERATED_WEB_PASSWORD}\n SECURE_CONNECTION: '1'\n ports:\n - 5800:5800/tcp\n volumes:\n - krusader-config:/config\n - /mnt/oci-shared/krusader/storage:/storage\nvolumes:\n krusader-config: {}\n"
},
"compose_stack": {
"project_name": "krusader",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "krusader",
"service_count": 1,
"services": [
{
"name": "krusader",
"image": "jlesage/krusader:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"environment": {
"GROUP_ID": "1000",
"SECURE_CONNECTION": "1",
"TZ": "Europe/Madrid",
"USER_ID": "1000",
"VNC_LOCALHOST_ONLY": "1",
"WEB_AUTHENTICATION": "1",
"WEB_AUTHENTICATION_PASSWORD": "${GENERATED_GENERATED_WEB_PASSWORD}",
"WEB_AUTHENTICATION_USERNAME": "admin"
},
"image": "jlesage/krusader:latest",
"ports": [
"5800:5800"
],
"volumes": [
"./config:/config",
"./storage:/storage"
]
}
}
],
"top_level": {
"name": "krusader"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "krusader-volume-0",
"service": "krusader",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "krusader-volume-1",
"service": "krusader",
"container_path": "/storage",
"mode": "user-selectable",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": "Host directory for Krusader:/storage",
"default": "host-bind",
"installation_choice": [
"managed-volume",
"host-bind"
]
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"krusader"
],
"stop_order": [
"krusader"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "generated-web-password",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "krusader",
"environment_variable": "WEB_AUTHENTICATION_PASSWORD"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "Krusader Web UI",
"scheme": "https",
"port": 5800,
"path": "/",
"source": "upstream-jlesage-secure-connection-and-web-authentication"
}
],
"credentials": [
{
"label": "Krusader Web UI",
"type": "configured-or-installer-generated",
"username": "admin",
"password": null,
"username_environment": "WEB_AUTHENTICATION_USERNAME",
"password_environment": "WEB_AUTHENTICATION_PASSWORD",
"change_required": false,
"source": "ProxMenux generated password and upstream image environment",
"retrieval": null
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "web-authentication-https",
"upstream_behavior": "The jlesage image can protect its browser GUI with WEB_AUTHENTICATION and requires SECURE_CONNECTION for authenticated web access.",
"native_lxc_behavior": "Enable authenticated HTTPS on port 5800, generate a unique password at install and keep VNC bound to localhost.",
"reason": "Krusader can modify files exposed under /storage, so the browser endpoint must not be unauthenticated.",
"behavioral_impact": "The image generates a self-signed TLS certificate; a browser may ask to trust it on first access.",
"validation": "pending"
},
{
"id": "scoped-storage-mount",
"upstream_behavior": "Docker Compose mounts the selected host directory at /storage.",
"native_lxc_behavior": "The same selected directory is mounted in the dedicated OCI LXC; no other host paths are exposed.",
"reason": "The file manager must only see data explicitly selected by the user.",
"behavioral_impact": "Write access permits changing or deleting files in that one directory.",
"validation": "pending"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes web port 5800 on the Docker host.",
"native_lxc_behavior": "The native LXC listens on its own IP at port 5800 without Docker NAT.",
"reason": "The LXC has a dedicated network namespace and address.",
"behavioral_impact": "The port is reached at the LXC address rather than through a host-published port.",
"validation": "pending"
}
],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"uid": 1000,
"gid": 1000,
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"uid": 1000,
"gid": 1000,
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
"scheme": "https",
"port": 5800,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": false
},
"generated_sensitive_environment": {
"WEB_AUTHENTICATION_PASSWORD": {
"strategy": "token-hex",
"bytes": 16,
"prompt": false
}
},
"volume_owner": {
"uid": 1000,
"gid": 1000
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "passed-first-start",
"service_health": "passed-login-page-and-authenticated-session-http-200",
"restart_persistence": "passed-container-restart-and-host-bind-write-check",
"backup_restore": "pending",
"update_preserves_data": "pending",
"image_resolution": "passed-skopeo-327mb-11-layers-integrity",
"credentials": "passed-generated-password-login-and-session-cookie",
"advanced_install": "pending-custom-install-summary-validation",
"managed_volume": "passed-managed-config-volume",
"host_bind": "passed-storage-bind-owner-and-app-user-write",
"browser_visual": "pending-self-signed-certificate-review",
"modification": "pending",
"removal": "passed-manager-remove-ct-disks-record-and-empty-test-path-cleaned",
"web_authentication": "passed-generated-credential-post-and-session-cookie"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": "amd64",
"resolved_digest": "sha256:ecb77bb73b1d3c66720eefb07805f70289349b449d1ddaa15d120c399bd89cc4",
"image_version_label": "26.09.1",
"image_created": "2026-09-22T15:22:56.230858151Z"
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-lightcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "LightCraft",
"es_ES": "LightCraft"
},
"tagline": {
"en_US": "Photo library and RAW development in your browser",
"es_ES": "Biblioteca de fotos y revelado RAW en el navegador"
},
"description": {
"en_US": "LightCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "LightCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/lightcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/lightcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/lightcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/lightcraft",
"readme_pushed_at": "",
"compose_sha256": "26d20ee6d028b198f569b66116ff5b55d7ab08f2cc26a13400d0e444ce10ba0f",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/lightcraft.yaml"
},
"container_contract": {
"service_name": "lightcraft",
"container_name": "lightcraft",
"image": {
"reference": "docker.io/junkerderprovinz/lightcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/lightcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n lightcraft:\n image: junkerderprovinz/lightcraft:latest\n container_name: lightcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "lightcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "lightcraft",
"service_count": 1,
"services": [
{
"name": "lightcraft",
"image": "junkerderprovinz/lightcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/lightcraft:latest",
"container_name": "lightcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "lightcraft-volume-0",
"service": "lightcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "lightcraft-volume-1",
"service": "lightcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"lightcraft"
],
"stop_order": [
"lightcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+42 -6
View File
@@ -68,11 +68,18 @@
"source": "docker-compose"
},
{
"name": "LLAMA_ARG_CONTEXT_SIZE",
"name": "LLAMA_ARG_CTX_SIZE",
"example": "8192",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "LLAMA_ARG_MODELS_DIR",
"example": "/models",
"required": true,
"sensitive": false,
"source": "upstream-documentation"
}
],
"volumes": [
@@ -89,7 +96,7 @@
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
"default_size_gb": 32
}
}
],
@@ -135,7 +142,8 @@
],
"environment": [
"LLAMA_ARG_N_GPU_LAYERS=999",
"LLAMA_ARG_CONTEXT_SIZE=8192"
"LLAMA_ARG_CTX_SIZE=8192",
"LLAMA_ARG_MODELS_DIR=/models"
],
"devices": [
"/dev/dri:/dev/dri"
@@ -229,8 +237,8 @@
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"cores": 4,
"memory_mb": 8192,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
@@ -334,6 +342,28 @@
"0x1002"
]
}
],
"environment": [
{
"name": "LLAMA_ARG_FLASH_ATTN",
"value": "off"
},
{
"name": "LLAMA_ARG_UBATCH",
"value": "32"
},
{
"name": "LLAMA_ARG_BATCH",
"value": "128"
},
{
"name": "GGML_VK_DISABLE_F16",
"value": "1"
},
{
"name": "GGML_VK_DISABLE_ASYNC",
"value": "1"
}
]
},
{
@@ -420,7 +450,13 @@
]
}
]
}
},
"completion_notes": [
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"Then restart the container so the new model appears in the list."
]
},
"adaptations": [
{
+609
View File
@@ -0,0 +1,609 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-movistar-webdav-proxy",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Movistar / O2 Cloud WebDAV Proxy"
},
"tagline": {
"en_US": "Access Movistar and O2 Cloud from WebDAV clients and backup tools."
},
"description": {
"en_US": "Official uniextra image with a web dashboard for Movistar/O2 Cloud account linking. Persistent OAuth credentials, authenticated WebDAV and disk-backed temporary uploads."
},
"category": "backup",
"category_label": "Backup & Recovery",
"author": "uniextra",
"developer": "uniextra",
"icon": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/main/static/favicon.svg",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 5000,
"path": "/"
},
"website": "https://github.com/uniextra/MovistarWebDAVProxy",
"documentation": "https://github.com/uniextra/MovistarWebDAVProxy#readme",
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
"tips": [
"Link your Movistar or O2 account from the dashboard after installation.",
"Use the container IP and port 8080 for WebDAV. Docker's published port 5050 is not used by native OCI LXC.",
"Temporary uploads use a separate disk volume, excluded from backups, to avoid filling RAM."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "uniextra",
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
"revision": "e48485bc8bdf9745caa6249fdc92db6d28214549",
"image_repository_url": "https://hub.docker.com/r/uniextra/movistar-webdav-proxy",
"readme_pushed_at": "",
"compose_sha256": "e51607e979c1a776ececda038caeffb4195f443ebc017eba753a4b4ff8fd5c28",
"generated_at": "2026-11-02T23:42:04+00:00",
"readme_raw_url": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/e48485bc8bdf9745caa6249fdc92db6d28214549/README.md"
},
"container_contract": {
"service_name": "movistar-webdav-proxy",
"container_name": "movistar-webdav-proxy",
"image": {
"reference": "uniextra/movistar-webdav-proxy:latest",
"registry": "docker.io",
"repository": "uniextra/movistar-webdav-proxy",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "WEBDAV_USER",
"example": "admin",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "WEBDAV_PASSWORD",
"example": "",
"required": true,
"sensitive": true,
"source": "docker-compose",
"prompt": "WebDAV and dashboard password (leave empty to generate)"
},
{
"name": "REQUIRE_AUTH",
"example": "true",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "TOKENS_ENCRYPTION_KEY",
"example": "",
"required": true,
"sensitive": true,
"source": "docker-compose"
},
{
"name": "MAX_UPLOAD_MB",
"example": "4096",
"required": false,
"sensitive": false,
"source": "docker-compose"
}
],
"volumes": [
{
"id": "tokens",
"container_path": "/app/tokens",
"compose_source_example": "./tokens",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
},
{
"id": "uploads",
"container_path": "/tmp",
"compose_source_example": "./tmp",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 5000,
"published_example": 5000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 8080,
"published_example": 8080,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n movistar-webdav-proxy:\n image: uniextra/movistar-webdav-proxy:v2.1.0\n container_name: movistar-webdav-proxy\n restart: unless-stopped\n read_only: true\n tmpfs:\n - /tmp\n security_opt:\n - no-new-privileges:true\n environment:\n - WEBDAV_USER=${WEBDAV_USER:-}\n - WEBDAV_PASSWORD=${WEBDAV_PASSWORD:-}\n - WEBUI_USER=${WEBUI_USER:-}\n - WEBUI_PASSWORD=${WEBUI_PASSWORD:-}\n ports:\n - \"${BIND_IP:-0.0.0.0}:${WEB_PORT:-5000}:5000\" # Panel Web de gestión y logs (usa BIND_IP=127.0.0.1 para acceso solo local)\n - \"${BIND_IP:-0.0.0.0}:${WEBDAV_PORT:-5050}:8080\" # Endpoint WebDAV (Duplicati / Synology HyperBackup)\n volumes:\n - movistar_tokens:/app/tokens\n\nvolumes:\n movistar_tokens:\n name: movistar_webdav_tokens\n"
},
"compose_stack": {
"project_name": "movistar-webdav-proxy",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "movistar-webdav-proxy",
"service_count": 1,
"services": [
{
"name": "movistar-webdav-proxy",
"image": "uniextra/movistar-webdav-proxy:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"environment": {
"MAX_UPLOAD_MB": "4096",
"REQUIRE_AUTH": "true",
"TOKENS_ENCRYPTION_KEY": "${GENERATED_TOKENS_ENCRYPTION_KEY}",
"WEBDAV_PASSWORD": "${GENERATED_WEBDAV_PASSWORD}",
"WEBDAV_USER": "admin"
},
"image": "uniextra/movistar-webdav-proxy:latest",
"ports": [
"5000:5000",
"8080:8080"
],
"volumes": [
"./tokens:/app/tokens",
"./tmp:/tmp"
]
}
}
],
"top_level": {
"name": "movistar-webdav-proxy"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "movistar-webdav-proxy-volume-0",
"service": "movistar-webdav-proxy",
"container_path": "/app/tokens",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "movistar-webdav-proxy-volume-1",
"service": "movistar-webdav-proxy",
"container_path": "/tmp",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"movistar-webdav-proxy"
],
"stop_order": [
"movistar-webdav-proxy"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "tokens-encryption-key",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "movistar-webdav-proxy",
"environment_variable": "TOKENS_ENCRYPTION_KEY"
}
]
},
{
"id": "webdav-password",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "movistar-webdav-proxy",
"environment_variable": "WEBDAV_PASSWORD"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "Web dashboard",
"scheme": "http",
"port": 5000,
"path": "/",
"source": "upstream-documentation"
},
{
"label": "WebDAV",
"scheme": "http",
"port": 8080,
"path": "/",
"source": "native-container-port"
}
],
"credentials": [
{
"label": "Web dashboard and WebDAV",
"type": "configured-or-installer-generated",
"username": "admin",
"username_environment": "WEBDAV_USER",
"password": null,
"password_environment": "WEBDAV_PASSWORD",
"change_required": false,
"source": "installer-generated",
"retrieval": null
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 1,
"memory_mb": 512,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
},
{
"id": "disk-backed-upload-scratch",
"upstream_behavior": "Compose mounts /tmp as a tmpfs.",
"native_lxc_behavior": "A separate managed disk volume provides /tmp and is excluded from backups.",
"reason": "Uploads can reach 4096 MB; a disk-backed scratch volume avoids consuming the LXC RAM limit.",
"behavioral_impact": "Scratch data uses disk and can survive a restart; the application removes completed temporary uploads.",
"validation": "passed-in-lab"
},
{
"id": "native-rootfs-permissions",
"upstream_behavior": "Docker Compose requests read_only for the root filesystem.",
"native_lxc_behavior": "Proxmox uses a writable native root disk; /app is owned by root, while the upstream entrypoint drops to UID 10001. Tokens and upload scratch have separate writable volumes.",
"reason": "The Proxmox pre-start setup requires a writable root disk. Protect application code through root ownership instead of declaring unsupported read-only startup.",
"behavioral_impact": "This is not a fully read-only root filesystem; the application user cannot replace the root-owned application directory or binaries.",
"validation": "passed-in-lab"
}
],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/app",
"remove_lost_found": false,
"owner_strategy": "mapped-root",
"mode": "0755"
},
{
"container_path": "/app/tokens",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"mode": "0700"
},
{
"container_path": "/tmp",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"mode": "1777"
}
],
"volume_owner": {
"uid": 10001,
"gid": 10001
},
"generated_sensitive_environment": {
"WEBDAV_PASSWORD": {
"strategy": "token-hex",
"bytes": 16,
"prompt": true
},
"TOKENS_ENCRYPTION_KEY": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
}
},
"security": {
"options": {
"no_new_privileges": true
}
},
"startup_healthcheck": {
"scheme": "http",
"port": 5000,
"path": "/health",
"timeout_seconds": 90,
"request_timeout_seconds": 5,
"stability_seconds": 4,
"verify_tls": false
},
"completion_notes": [
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations."
]
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "passed",
"service_health": "passed",
"restart_persistence": "passed",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+505
View File
@@ -0,0 +1,505 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-paperclip",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Paperclip"
},
"tagline": {
"en_US": "Manage teams of AI agents from a web dashboard."
},
"description": {
"en_US": "Official Paperclip image with its embedded PostgreSQL database, persistent agent workspaces and authenticated web interface."
},
"category": "ai",
"category_label": "AI / Coding & Dev-Tools",
"author": "Paperclip",
"developer": "Paperclip",
"icon": "https://raw.githubusercontent.com/paperclipai/paperclip/master/ui/public/favicon.svg",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 3100,
"path": "/"
},
"website": "https://paperclip.ing",
"documentation": "https://github.com/paperclipai/paperclip/blob/master/doc/DOCKER.md",
"repository": "https://github.com/paperclipai/paperclip",
"tips": [
"Create an account and claim the instance from the first-run setup screen.",
"Configure provider credentials or external agents after installation; no API key is required to start the dashboard.",
"For HTTPS access, set PAPERCLIP_PUBLIC_URL to the canonical URL in Advanced settings.",
"Restore with the original network identity, or update PAPERCLIP_PUBLIC_URL in Modify when the address or hostname changes."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "official",
"repository": "https://github.com/paperclipai/paperclip",
"revision": "1b4c803816e82b0265c8422e1a804327a7ed8c54",
"image_repository_url": "https://github.com/paperclipai/paperclip/pkgs/container/paperclip",
"readme_pushed_at": "",
"compose_sha256": "53a71e7d1c6a47fb25ad68d5570140c525df30fcecf33a00cf84bd2b65bd15f4",
"generated_at": "2026-11-02T18:43:18+00:00",
"readme_raw_url": "https://github.com/paperclipai/paperclip/blob/master/doc/DOCKER.md"
},
"container_contract": {
"service_name": "paperclip",
"container_name": "paperclip",
"image": {
"reference": "ghcr.io/paperclipai/paperclip:latest",
"registry": "ghcr.io",
"repository": "ghcr.io/paperclipai/paperclip",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "HOST",
"example": "0.0.0.0",
"required": true,
"sensitive": false,
"source": "docker-compose",
"prompt_user": false
},
{
"name": "PAPERCLIP_HOME",
"example": "/paperclip",
"required": true,
"sensitive": false,
"source": "docker-compose",
"prompt_user": false
},
{
"name": "PAPERCLIP_DEPLOYMENT_MODE",
"example": "authenticated",
"required": true,
"sensitive": false,
"source": "docker-compose",
"prompt_user": false
},
{
"name": "PAPERCLIP_DEPLOYMENT_EXPOSURE",
"example": "private",
"required": true,
"sensitive": false,
"source": "docker-compose",
"prompt_user": false
},
{
"name": "PAPERCLIP_PUBLIC_URL",
"example": "http://localhost:3100",
"required": true,
"sensitive": false,
"source": "docker-compose",
"container_address": "http://@CONTAINER_ADDRESS@:3100"
},
{
"name": "BETTER_AUTH_SECRET",
"example": "${GENERATED_BETTER_AUTH_SECRET}",
"required": true,
"sensitive": true,
"source": "docker-compose"
},
{
"name": "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET",
"example": "${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}",
"required": true,
"sensitive": true,
"source": "docker-compose"
},
{
"name": "OPENAI_API_KEY",
"example": "",
"required": false,
"sensitive": true,
"source": "official-documentation"
},
{
"name": "ANTHROPIC_API_KEY",
"example": "",
"required": false,
"sensitive": true,
"source": "official-documentation"
},
{
"name": "GEMINI_API_KEY",
"example": "",
"required": false,
"sensitive": true,
"source": "official-documentation"
},
{
"name": "OPENROUTER_API_KEY",
"example": "",
"required": false,
"sensitive": true,
"source": "official-documentation"
},
{
"name": "PAPERCLIP_ALLOWED_HOSTNAMES",
"example": "",
"required": false,
"sensitive": false,
"source": "official-documentation"
},
{
"name": "PAPERCLIP_MIGRATION_AUTO_APPLY",
"example": "true",
"required": true,
"sensitive": false,
"prompt_user": false,
"source": "official-server-startup"
}
],
"volumes": [
{
"id": "volume-0",
"container_path": "/paperclip",
"compose_source_example": "paperclip-data",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
}
],
"ports": [
{
"container_port": 3100,
"published_example": 3100,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": "90s",
"original_compose": "name: paperclip\nservices:\n paperclip:\n image: ghcr.io/paperclipai/paperclip:latest\n restart: unless-stopped\n stop_grace_period: 90s\n ports:\n - 3100:3100\n environment:\n HOST: 0.0.0.0\n PAPERCLIP_HOME: /paperclip\n PAPERCLIP_MIGRATION_AUTO_APPLY: \"true\"\n PAPERCLIP_DEPLOYMENT_MODE: authenticated\n PAPERCLIP_DEPLOYMENT_EXPOSURE: private\n PAPERCLIP_PUBLIC_URL: http://localhost:3100\n BETTER_AUTH_SECRET: ${GENERATED_BETTER_AUTH_SECRET}\n PAPERCLIP_TOOL_ACTION_SIGNING_SECRET: ${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}\n volumes:\n - paperclip-data:/paperclip\nvolumes:\n paperclip-data: {}\n"
},
"compose_stack": {
"project_name": "paperclip",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "paperclip",
"service_count": 1,
"services": [
{
"name": "paperclip",
"image": "ghcr.io/paperclipai/paperclip:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "ghcr.io/paperclipai/paperclip:latest",
"restart": "unless-stopped",
"stop_grace_period": "90s",
"ports": [
"3100:3100"
],
"environment": {
"HOST": "0.0.0.0",
"PAPERCLIP_HOME": "/paperclip",
"PAPERCLIP_DEPLOYMENT_MODE": "authenticated",
"PAPERCLIP_DEPLOYMENT_EXPOSURE": "private",
"PAPERCLIP_PUBLIC_URL": "http://localhost:3100",
"BETTER_AUTH_SECRET": "${GENERATED_BETTER_AUTH_SECRET}",
"PAPERCLIP_TOOL_ACTION_SIGNING_SECRET": "${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}",
"PAPERCLIP_MIGRATION_AUTO_APPLY": "true"
},
"volumes": [
"paperclip-data:/paperclip"
]
}
}
],
"top_level": {
"name": "paperclip",
"volumes": {
"paperclip-data": {}
}
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "paperclip-volume-0",
"service": "paperclip",
"container_path": "/paperclip",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"paperclip"
],
"stop_order": [
"paperclip"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "better-auth-secret",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "paperclip",
"environment_variable": "BETTER_AUTH_SECRET"
}
]
},
{
"id": "paperclip-tool-action-signing-secret",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "paperclip",
"environment_variable": "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "http",
"port": 3100,
"path": "/",
"source": "compose-metadata"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 4096,
"swap_mb": 512,
"rootfs_size_gb": 32,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 90
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "official-embedded-postgresql-image",
"upstream_behavior": "The official image starts Paperclip and its embedded PostgreSQL database.",
"native_lxc_behavior": "Import the original Entrypoint, Cmd and WorkingDir into one unprivileged LXC.",
"reason": "Keep the developer image without Docker Engine or a custom image build.",
"behavioral_impact": "Provider credentials are configured separately after the first account is created.",
"validation": "passed-amd64-web-login-and-api-data"
},
{
"id": "persistent-application-home",
"upstream_behavior": "The root entrypoint prepares /paperclip and then switches to the node user.",
"native_lxc_behavior": "Prepare the volume for mapped root and let the official entrypoint set application ownership.",
"reason": "Preserve the embedded database, uploads, workspaces and local secrets across image replacement and restore.",
"behavioral_impact": "Managed volumes are backed up; host directories remain outside the LXC backup.",
"validation": "passed-managed-volume-host-bind-restart-and-restore"
},
{
"id": "noninteractive-database-migrations",
"upstream_behavior": "Existing databases with pending migrations trigger an interactive confirmation during startup.",
"native_lxc_behavior": "Set the upstream PAPERCLIP_MIGRATION_AUTO_APPLY=true option.",
"reason": "An OCI update must finish without waiting for input at a migration prompt.",
"behavioral_impact": "Paperclip applies its schema migrations when starting an updated image; the native update backup protects the previous installation.",
"validation": "passed-real-upgrade-2026.1012.0-to-2026.1023.0"
},
{
"id": "authenticated-instance-address",
"upstream_behavior": "Paperclip uses its canonical public URL for authentication origins and hostname checks.",
"native_lxc_behavior": "Use the installer container-address placeholder by default and allow a canonical URL in Advanced settings.",
"reason": "Avoid the upstream localhost URL on an LXC with its own address.",
"behavioral_impact": "When restoring under another address, change PAPERCLIP_PUBLIC_URL through Modify. Restoring the original network identity retains the URL.",
"validation": "passed-direct-ip-authenticated-setup-and-original-network-restore"
},
{
"id": "independent-signing-secrets",
"upstream_behavior": "Session signing and approval-gated tool actions use independent secrets.",
"native_lxc_behavior": "Generate two separate 32-byte hexadecimal secrets and keep their values sensitive.",
"reason": "Do not ship a shared password or regenerate signing keys during an update.",
"behavioral_impact": "The first administrator creates an account in the web interface. Provider API keys are optional and sensitive.",
"validation": "passed-first-admin-claim-and-update-account-persistence"
}
],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/paperclip",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
}
],
"generated_sensitive_environment": {
"BETTER_AUTH_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"PAPERCLIP_TOOL_ACTION_SIGNING_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
}
},
"startup_healthcheck": {
"scheme": "http",
"port": 3100,
"path": "/api/health",
"timeout_seconds": 300,
"request_timeout_seconds": 10,
"stability_seconds": 5,
"verify_tls": true
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
},
"validation": {
"schema": "passed",
"clean_install": "passed-default-resource-profile-and-advanced-settings-amd64",
"service_health": "passed-http-api-health-browser-login-and-first-admin-claim",
"restart_persistence": "passed-host-bind-reboot-and-managed-volume-restore",
"backup_restore": "passed-different-vmid-oci-recovery-with-original-network-identity",
"update_preserves_data": "passed-2026.1012.0-to-2026.1023.0-with-automatic-schema-migrations",
"rollback": "passed-explicit-native-Recover-after-failed-image-not-claimed-automatic",
"modification": "passed-native-cpu-and-ram-change-without-image-download-or-recreation",
"removal": "passed-guests-disks-records-and-test-backups-cleaned-host-data-preserved-by-Remove",
"browser_ui": "passed-account-login-and-company-dashboard",
"runtime_architecture": "amd64-tested-arm64-manifest-only",
"provider_agent_runs": "not-tested-no-real-provider-credentials-used",
"oci_engine_tests": "1158-run-4-skipped",
"offline_i18n_tests": "626-passed"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-pdfcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "PdfCraft",
"es_ES": "PdfCraft"
},
"tagline": {
"en_US": "Read and edit PDF documents in your browser",
"es_ES": "Lectura y edición de documentos PDF en el navegador"
},
"description": {
"en_US": "PdfCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "PdfCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/pdfcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/pdfcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/pdfcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/pdfcraft",
"readme_pushed_at": "",
"compose_sha256": "4416cf187df8cccbc11fc14af6e4d5155cd386871f9514ae1ca10968a8b4a372",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/pdfcraft.yaml"
},
"container_contract": {
"service_name": "pdfcraft",
"container_name": "pdfcraft",
"image": {
"reference": "docker.io/junkerderprovinz/pdfcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/pdfcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n pdfcraft:\n image: junkerderprovinz/pdfcraft:latest\n container_name: pdfcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "pdfcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "pdfcraft",
"service_count": 1,
"services": [
{
"name": "pdfcraft",
"image": "junkerderprovinz/pdfcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/pdfcraft:latest",
"container_name": "pdfcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "pdfcraft-volume-0",
"service": "pdfcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "pdfcraft-volume-1",
"service": "pdfcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"pdfcraft"
],
"stop_order": [
"pdfcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-photocraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "PhotoCraft",
"es_ES": "PhotoCraft"
},
"tagline": {
"en_US": "Photo editing in your browser",
"es_ES": "Edición de fotos en el navegador"
},
"description": {
"en_US": "PhotoCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "PhotoCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/photocraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/photocraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/photocraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/photocraft",
"readme_pushed_at": "",
"compose_sha256": "459ac4e3adbd7544f3d0acb2f34230e8a396566ff910288898f689d54a78e722",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/photocraft.yaml"
},
"container_contract": {
"service_name": "photocraft",
"container_name": "photocraft",
"image": {
"reference": "docker.io/junkerderprovinz/photocraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/photocraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n photocraft:\n image: junkerderprovinz/photocraft:latest\n container_name: photocraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "photocraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "photocraft",
"service_count": 1,
"services": [
{
"name": "photocraft",
"image": "junkerderprovinz/photocraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/photocraft:latest",
"container_name": "photocraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "photocraft-volume-0",
"service": "photocraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "photocraft-volume-1",
"service": "photocraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"photocraft"
],
"stop_order": [
"photocraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+4 -1
View File
@@ -329,7 +329,10 @@
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"non_persistent_image_volumes": [
"/tmp/jetty"
]
}
},
"compatibility": {
+3
View File
@@ -788,6 +788,9 @@
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
}
],
"non_persistent_image_volumes": [
"/romm"
]
}
},
+35 -1
View File
@@ -85,6 +85,22 @@
"backup": true,
"default_size_gb": 8
}
},
{
"id": "volume-1",
"container_path": "/etc/searxng",
"compose_source_example": "./config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
@@ -127,7 +143,8 @@
"8080:8080"
],
"volumes": [
"./cache:/var/cache/searxng"
"./cache:/var/cache/searxng",
"./config:/etc/searxng"
]
}
}
@@ -153,6 +170,17 @@
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "searxng-volume-1",
"service": "searxng",
"container_path": "/etc/searxng",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
@@ -378,6 +406,12 @@
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/etc/searxng",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-soundcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "SoundCraft",
"es_ES": "SoundCraft"
},
"tagline": {
"en_US": "Audio recording and mixing in your browser",
"es_ES": "Grabación y mezcla de audio en el navegador"
},
"description": {
"en_US": "SoundCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "SoundCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/soundcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/soundcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/soundcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/soundcraft",
"readme_pushed_at": "",
"compose_sha256": "8fef65b5330dd21035acbd8bc587c597610e6db5fdf8a70a07b54dcab25b3695",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/soundcraft.yaml"
},
"container_contract": {
"service_name": "soundcraft",
"container_name": "soundcraft",
"image": {
"reference": "docker.io/junkerderprovinz/soundcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/soundcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n soundcraft:\n image: junkerderprovinz/soundcraft:latest\n container_name: soundcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "soundcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "soundcraft",
"service_count": 1,
"services": [
{
"name": "soundcraft",
"image": "junkerderprovinz/soundcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/soundcraft:latest",
"container_name": "soundcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "soundcraft-volume-0",
"service": "soundcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "soundcraft-volume-1",
"service": "soundcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"soundcraft"
],
"stop_order": [
"soundcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+477
View File
@@ -0,0 +1,477 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-spoolman",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Spoolman"
},
"tagline": {
"en_US": "Track 3D printer filament spools and usage."
},
"description": {
"en_US": "A self-hosted filament inventory for 3D printers. Manage spools, materials, manufacturers, locations and labels in the web UI, and integrate with Moonraker, OctoPrint and other printer tools. The official image uses SQLite by default; no separate database container is required."
},
"category": "tools",
"category_label": "Tools",
"author": "Donkie",
"developer": "Donkie",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/spoolman.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 8000,
"path": "/"
},
"website": "https://github.com/Donkie/Spoolman",
"documentation": "https://github.com/Donkie/Spoolman/wiki/Installation",
"repository": "https://github.com/Donkie/Spoolman",
"tips": [
"Spoolman has no built-in authentication. Keep it on a trusted network; do not expose it directly to the internet.",
"The official image uses SQLite by default and stores the database, automatic backups, logs and cache in the persistent data directory."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "Donkie",
"repository": "https://github.com/Donkie/Spoolman",
"revision": "ff8efd517b76a4b2783f29c89e9b9fbcd8cd167b",
"image_repository_url": "https://github.com/Donkie/Spoolman/pkgs/container/spoolman",
"readme_pushed_at": "2026-10-31T09:39:19Z",
"compose_sha256": "d9b115c4c37589f9813e54f926fdd22e7a10a44a6e56160f837b1247638fac83",
"generated_at": "2026-11-02T20:02:46+00:00",
"default_branch": "master",
"readme_raw_url": "https://github.com/Donkie/Spoolman/wiki/Installation"
},
"container_contract": {
"service_name": "spoolman",
"container_name": "spoolman",
"image": {
"reference": "ghcr.io/donkie/spoolman:latest",
"registry": "ghcr.io",
"repository": "ghcr.io/donkie/spoolman",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-image-default",
"prompt_user": false
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-image-default",
"prompt_user": false
},
{
"name": "TZ",
"example": "Etc/UTC",
"required": true,
"sensitive": false,
"source": "upstream-compose",
"prompt_user": false
}
],
"volumes": [
{
"id": "volume-0",
"container_path": "/home/app/.local/share/spoolman",
"compose_source_example": "./data",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
}
],
"ports": [
{
"container_port": 8000,
"published_example": 7912,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n spoolman:\n image: ghcr.io/donkie/spoolman:latest\n container_name: spoolman\n restart: unless-stopped\n ports:\n - \"7912:8000/tcp\"\n volumes:\n - ./data:/home/app/.local/share/spoolman\n environment:\n PUID: \"1000\"\n PGID: \"1000\"\n TZ: Etc/UTC\n"
},
"compose_stack": {
"project_name": "spoolman",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "spoolman",
"service_count": 1,
"services": [
{
"name": "spoolman",
"image": "ghcr.io/donkie/spoolman:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "ghcr.io/donkie/spoolman:latest",
"container_name": "spoolman",
"restart": "unless-stopped",
"ports": [
"7912:8000/tcp"
],
"volumes": [
"./data:/home/app/.local/share/spoolman"
],
"environment": {
"PUID": "1000",
"PGID": "1000",
"TZ": "Etc/UTC"
}
}
}
],
"top_level": {
"name": "spoolman"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "spoolman-volume-0",
"service": "spoolman",
"container_path": "/home/app/.local/share/spoolman",
"mode": "managed-volume",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"spoolman"
],
"stop_order": [
"spoolman"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Spoolman web interface",
"scheme": "http",
"port": 8000,
"path": "/",
"source": "upstream-image"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
],
"installer_profile": {
"startup_healthcheck": {
"scheme": "http",
"port": 8000,
"path": "/",
"timeout_seconds": 180,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
},
"volume_preparations": [
{
"container_path": "/home/app/.local/share/spoolman",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"volume_owner": {
"uid": 1000,
"gid": 1000
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "passed-default-official-image-skopeo-and-first-start-http",
"advanced_install": "pending-custom-install-summary-validation",
"service_health": "passed-web-api-crud",
"restart_persistence": "passed-managed-and-host-bind-database-and-records",
"backup_restore": "passed-pbs-backup-and-manager-recover-record-preserved",
"update_preserves_data": "no-update-available-at-check",
"modification": "passed-cpu-ram-up-and-down-without-image-pull-or-recreate",
"volumes": "passed-managed-storage-and-host-bind-crud-owner-and-data-check",
"removal": "passed-manager-removal-host-path-retained-then-temporary-data-cleaned"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+17 -27
View File
@@ -82,22 +82,6 @@
"backup": true,
"default_size_gb": 8
}
},
{
"id": "volume-1",
"container_path": "/dev/net/tun",
"compose_source_example": "/dev/net/tun",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
}
],
"ports": [],
@@ -180,17 +164,6 @@
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "tailscale-volume-1",
"service": "tailscale",
"container_path": "/dev/net/tun",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
@@ -288,6 +261,23 @@
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
}
],
"device_requests": [
{
"id": "dev-net-tun",
"kind": "character-device",
"purpose": "tun",
"enable_prompt": "Pass /dev/net/tun to the LXC",
"enabled_default": true,
"required_by_compose": true,
"path_prompt": "Host device for /dev/net/tun",
"host_path_default": "/dev/net/tun",
"container_path": "/dev/net/tun",
"mode": "preserve-host",
"deny_write": false,
"gid_strategy": "host-device-gid",
"source_mapping": "/dev/net/tun:/dev/net/tun"
}
]
},
"adaptations": [
+47 -3
View File
@@ -60,7 +60,24 @@
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [],
"volumes": [],
"volumes": [
{
"id": "volume-0",
"container_path": "/var/lib/tor",
"compose_source_example": "./tor-data",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
{
"container_port": 9050,
@@ -103,6 +120,9 @@
"ports": [
"9050:9050",
"8118:8118"
],
"volumes": [
"./tor-data:/var/lib/tor"
]
}
}
@@ -119,7 +139,19 @@
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [],
"storage": [
{
"id": "tor-volume-0",
"service": "tor",
"container_path": "/var/lib/tor",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
@@ -323,7 +355,19 @@
"SOCKS5 proxy: configure your application with the LXC IP address shown above and port 9050.",
"HTTP CONNECT proxy: use the same IP address and port 8118. These addresses are proxy settings, not web links.",
"Only applications configured to use this proxy send their traffic through Tor."
]
],
"volume_preparations": [
{
"container_path": "/var/lib/tor",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"volume_owner": {
"uid": 101,
"gid": 102
}
}
},
"compatibility": {
+292
View File
@@ -0,0 +1,292 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-unbound",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Unbound"
},
"tagline": {
"en_US": "A validating, recursive DNS resolver for your private network."
},
"description": {
"en_US": "Run the community-maintained klutchell image of Unbound as a DNS resolver on its own Proxmox LXC. It listens on TCP and UDP port 53 and can load optional custom configuration files."
},
"category": "adblock",
"category_label": "Adblock & DNS",
"author": "Kyle Harding",
"developer": "Kyle Harding (klutchell)",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/unbound.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64",
"armhf"
],
"launch": {
"scheme": "http",
"port": null,
"path": "/"
},
"website": "https://unbound.net/",
"documentation": "https://github.com/klutchell/unbound-docker#readme",
"repository": "https://github.com/klutchell/unbound-docker",
"tips": [
"Unbound has no web interface. Use the LXC IP as a DNS server on TCP and UDP port 53.",
"The default image config listens on all interfaces and accepts clients from private IPv4 ranges. Keep it behind your trusted LAN firewall; do not expose recursive DNS publicly.",
"The original GitHub repository has moved to klutchell/unbound-docker; the published Docker Hub image remains klutchell/unbound:main. The image is an unofficial community image, not published by NLnet Labs.",
"Optional custom .conf files go under /etc/unbound/custom.conf.d and must be readable by UID/GID 101:102 or world-readable."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "klutchell",
"repository": "https://github.com/klutchell/unbound-docker",
"revision": "1efbea960bf9462b6fb6dd71aa702ad32d6820d7",
"default_branch": "main",
"image_repository_url": "https://hub.docker.com/r/klutchell/unbound",
"readme_pushed_at": "2026-11-02T14:31:22Z",
"compose_sha256": "faf73a93c1f7d4d43f1eb61ba2e62a4418bd501f0c827b080ea9897964e75848",
"generated_at": "2026-11-02T21:21:54+00:00",
"readme_raw_url": "https://raw.githubusercontent.com/klutchell/unbound-docker/main/README.md"
},
"container_contract": {
"service_name": "unbound",
"container_name": "unbound",
"image": {
"reference": "klutchell/unbound:main",
"registry": "docker.io",
"repository": "klutchell/unbound",
"tag": "main",
"digest": null,
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
},
"environment": [],
"volumes": [
{
"id": "volume-0",
"container_path": "/etc/unbound/custom.conf.d",
"compose_source_example": "./config",
"read_only": false,
"required": false,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "host-bind",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
{
"container_port": 53,
"published_example": 53,
"protocol": "udp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 53,
"published_example": 53,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "name: unbound\nservices:\n unbound:\n image: klutchell/unbound:main\n container_name: unbound\n restart: unless-stopped\n ports:\n - 53:53/udp\n - 53:53/tcp\n volumes:\n - ./config:/etc/unbound/custom.conf.d\n"
},
"compose_stack": {
"project_name": "unbound",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "unbound",
"service_count": 1,
"services": [
{
"name": "unbound",
"image": "klutchell/unbound:main",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "klutchell/unbound:main",
"container_name": "unbound",
"restart": "unless-stopped",
"ports": [
"53:53/udp",
"53:53/tcp"
],
"volumes": [
"./config:/etc/unbound/custom.conf.d"
]
}
}
],
"top_level": {
"name": "unbound"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "unbound-volume-0",
"service": "unbound",
"container_path": "/etc/unbound/custom.conf.d",
"mode": "user-selectable",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": "Host directory containing optional custom Unbound .conf files",
"default": "host-bind",
"installation_choice": [
"managed-volume",
"host-bind"
]
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"unbound"
],
"stop_order": [
"unbound"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
]
}
},
"first_run": {
"endpoints": [],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 512,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 120
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/etc/unbound/custom.conf.d",
"owner_strategy": "mapped-root",
"remove_lost_found": true,
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
"type": "running",
"timeout_seconds": 90,
"stability_seconds": 20
}
},
"catalog": {
"replaces_discovered_ids": []
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"container_name",
"image",
"ports",
"restart",
"volumes"
],
"untranslated_blockers": [],
"policy": "This single-image Compose contract maps to one unprivileged Proxmox LXC. The optional custom-config directory can use a Proxmox-managed volume or a host directory; the image defaults work with an empty directory."
},
"validation": {
"schema": "passed-at-generation",
"image_resolution": "passed-skopeo-16-layers",
"clean_install": "passed-default-install-and-first-start-healthcheck",
"advanced_install": "pending",
"service_health": "passed-recursion-and-custom-local-data-over-udp-and-tcp",
"restart_persistence": "passed-custom-zone-after-pct-reboot",
"backup_restore": "pending",
"update_preserves_data": "pending-update-check-not-run",
"modification": "pending-manager-ui-unresponsive-no-changes-applied",
"managed_volume": "passed-config-volume-1g",
"host_bind": "pending",
"removal": "passed-manager-remove-ct-disks-and-record-cleaned"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+4 -1
View File
@@ -323,7 +323,10 @@
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"non_persistent_image_volumes": [
"/var/log"
]
},
"adaptations": [
{
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-vectorcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "VectorCraft",
"es_ES": "VectorCraft"
},
"tagline": {
"en_US": "Vector illustration in your browser",
"es_ES": "Ilustración vectorial en el navegador"
},
"description": {
"en_US": "VectorCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "VectorCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/vectorcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/vectorcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/vectorcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/vectorcraft",
"readme_pushed_at": "",
"compose_sha256": "a62cf232ee367ccb49096aec28637b0e9b78fce44b52574a57fe05e918468a14",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/vectorcraft.yaml"
},
"container_contract": {
"service_name": "vectorcraft",
"container_name": "vectorcraft",
"image": {
"reference": "docker.io/junkerderprovinz/vectorcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/vectorcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n vectorcraft:\n image: junkerderprovinz/vectorcraft:latest\n container_name: vectorcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "vectorcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "vectorcraft",
"service_count": 1,
"services": [
{
"name": "vectorcraft",
"image": "junkerderprovinz/vectorcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/vectorcraft:latest",
"container_name": "vectorcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "vectorcraft-volume-0",
"service": "vectorcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "vectorcraft-volume-1",
"service": "vectorcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"vectorcraft"
],
"stop_order": [
"vectorcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+47 -3
View File
@@ -77,7 +77,24 @@
"source": "upstream-documentation"
}
],
"volumes": [],
"volumes": [
{
"id": "volume-0",
"container_path": "/config",
"compose_source_example": "./config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
{
"container_port": 5000,
@@ -117,7 +134,10 @@
"environment": {
"WHOOGLE_USER": "admin",
"WHOOGLE_PASS": "${GENERATED_WHOOGLE_PASS}"
}
},
"volumes": [
"./config:/config"
]
}
}
],
@@ -133,7 +153,19 @@
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [],
"storage": [
{
"id": "whoogle-volume-0",
"service": "whoogle",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
@@ -378,6 +410,18 @@
"bytes": 24,
"prompt": false
}
},
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"volume_owner": {
"uid": 927,
"gid": 927
}
},
"catalog": {
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-wordcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "WordCraft",
"es_ES": "WordCraft"
},
"tagline": {
"en_US": "Word processing in your browser",
"es_ES": "Procesador de textos en el navegador"
},
"description": {
"en_US": "WordCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "WordCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/wordcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/wordcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/wordcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/wordcraft",
"readme_pushed_at": "",
"compose_sha256": "cc6ac9c1448000c780e93d69e0ced1f39f3256fb2478fda4453442f62e2aa23f",
"generated_at": "2026-11-03T12:57:30+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/wordcraft.yaml"
},
"container_contract": {
"service_name": "wordcraft",
"container_name": "wordcraft",
"image": {
"reference": "docker.io/junkerderprovinz/wordcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/wordcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n wordcraft:\n image: junkerderprovinz/wordcraft:latest\n container_name: wordcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "wordcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "wordcraft",
"service_count": 1,
"services": [
{
"name": "wordcraft",
"image": "junkerderprovinz/wordcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/wordcraft:latest",
"container_name": "wordcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "wordcraft-volume-0",
"service": "wordcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "wordcraft-volume-1",
"service": "wordcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"wordcraft"
],
"stop_order": [
"wordcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+302
View File
@@ -0,0 +1,302 @@
{
"schema_version": "0.3.0",
"kind": "proxmenux.oci-template",
"id": "image-zwave-js-ui",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Z-Wave JS UI"
},
"tagline": {
"en_US": "Manage a Z-Wave network from a web dashboard and WebSocket gateway."
},
"description": {
"en_US": "A self-hosted Z-Wave control panel and MQTT gateway. Its web interface can start without a Z-Wave controller; device control requires a compatible USB or serial controller and network security keys."
},
"category": "smarthome",
"author": "Z-Wave JS",
"developer": "Z-Wave JS",
"icon": "https://raw.githubusercontent.com/zwave-js/zwave-js-ui/c38e0d2cbbb826bf2bab2db596a3452e59ce0e8e/public/apple-touch-icon-180x180.png",
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 8091,
"path": "/"
},
"website": "https://zwave-js.github.io/zwave-js-ui/",
"documentation": "https://zwave-js.github.io/zwave-js-ui/#/getting-started/docker",
"repository": "https://github.com/zwave-js/zwave-js-ui",
"tips": [
"The web UI can start without a Z-Wave controller. To control devices, pass through a compatible USB/serial controller and select its stable /dev/serial/by-id/... path in Settings → Z-Wave → Serial Port.",
"Configure and securely back up the S0/S2 network keys in Settings → Z-Wave before pairing security-enabled devices.",
"Port 3000 is the Z-Wave JS WebSocket server for integrations such as Home Assistant; it listens only after a Z-Wave client is configured. Upstream documents it as unauthenticated, so expose it only to trusted integrations and networks.",
"ProxMenux enables the web login and generates the initial admin password. Configure trusted HTTPS before remote access over an untrusted network."
],
"mini_changelog": [],
"display_version": "11.25.2",
"updated_at": "2026-11-02",
"category_label": "IoT & Smart Home"
},
"source": {
"provider": "Z-Wave JS",
"repository": "https://github.com/zwave-js/zwave-js-ui",
"default_branch": "master",
"revision": "c38e0d2cbbb826bf2bab2db596a3452e59ce0e8e",
"readme_raw_url": "https://raw.githubusercontent.com/zwave-js/zwave-js-ui/c38e0d2cbbb826bf2bab2db596a3452e59ce0e8e/README.md",
"image_repository_url": "https://hub.docker.com/r/zwavejs/zwave-js-ui",
"compose_sha256": "ed371d9e9805db5d2abd356b54e3ff5fdb677d637857313f6aac3f498f480f87",
"generated_at": "2026-11-02T20:10:33+00:00"
},
"container_contract": {
"service_name": "zwave-js-ui",
"container_name": "zwave-js-ui",
"image": {
"reference": "docker.io/zwavejs/zwave-js-ui:latest",
"registry": "docker.io",
"repository": "zwavejs/zwave-js-ui",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
},
"environment": [
{
"name": "SESSION_SECRET",
"example": "${GENERATED_SESSION_SECRET}",
"required": true,
"sensitive": true,
"source": "ProxMenux-generated; supported by upstream image"
},
{
"name": "DEFAULT_PASSWORD",
"example": "${GENERATED_ADMIN_PASSWORD}",
"prompt": "Initial Z-Wave JS UI admin password",
"required": true,
"sensitive": true,
"source": "Upstream image; generated by ProxMenux"
}
],
"volumes": [
{
"id": "zwave-config",
"container_path": "/usr/src/app/store",
"compose_source_example": "zwave-config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
}
],
"ports": [
{
"container_port": 8091,
"published_example": 8091,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": false,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "always",
"stop_grace_period": null,
"original_compose": "version: '3.7'\nservices:\n zwave-js-ui:\n container_name: zwave-js-ui\n image: zwavejs/zwave-js-ui:latest\n restart: always\n tty: true\n stop_signal: SIGINT\n environment:\n SESSION_SECRET: ${GENERATED_SESSION_SECRET}\n DEFAULT_PASSWORD: ${GENERATED_ADMIN_PASSWORD}\n networks:\n - zwave\n devices:\n - /dev/serial/by-id/insert_stick_reference_here:/dev/zwave\n volumes:\n - zwave-config:/usr/src/app/store\n ports:\n - '8091:8091'\n - '3000:3000'\nnetworks:\n zwave:\nvolumes:\n zwave-config:\n name: zwave-config\n"
},
"first_run": {
"endpoints": [
{
"label": "Z-Wave JS UI",
"scheme": "http",
"port": 8091,
"path": "/",
"source": "official-docker-documentation"
}
],
"credentials": [
{
"label": "Z-Wave JS UI admin login",
"type": "configured-or-installer-generated",
"username": "admin",
"password": null,
"password_environment": "DEFAULT_PASSWORD",
"change_required": false,
"source": "Upstream DEFAULT_PASSWORD, generated by ProxMenux",
"retrieval": null
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": true,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 60
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "apply-compose-override"
},
"adaptations": [
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes ports on a Docker host address and attaches the service to its Compose network.",
"native_lxc_behavior": "The OCI process listens on the dedicated LXC address; ProxMenux maps the single-service network to the LXC network namespace.",
"reason": "A one-service native OCI LXC has its own network namespace and address.",
"behavioral_impact": "Use the LXC address directly; no Docker port NAT or separate bridge is created.",
"validation": "pending-per-application"
},
{
"id": "generated-login-and-session-secret",
"upstream_behavior": "The image defaults to user admin and password zwave; web authentication is disabled by default, and the Compose example uses a sample session secret.",
"native_lxc_behavior": "ProxMenux generates a unique initial admin password and session secret, and seeds gateway.authEnabled=true before first boot.",
"reason": "Avoid shipping a shared password, sample session key or unauthenticated web UI.",
"behavioral_impact": "The installer must display the generated admin password; change it after first login.",
"validation": "pending-per-application"
},
{
"id": "stop-signal",
"upstream_behavior": "Compose requests SIGINT when stopping the container.",
"native_lxc_behavior": "ProxMenux uses the same signal for the OCI process shutdown lifecycle.",
"reason": "Preserve the upstream graceful-shutdown behavior.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
}
],
"installer_profile": {
"generated_sensitive_environment": {
"SESSION_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"DEFAULT_PASSWORD": {
"strategy": "token-hex",
"bytes": 20,
"prompt": true
}
},
"generated_files": [
{
"container_path": "/usr/src/app/store/settings.json",
"mode": "0600",
"owner": "mapped-root",
"content": "{\"gateway\":{\"authEnabled\":true}}\n",
"only_if_missing": true
}
],
"volume_preparations": [
{
"container_path": "/usr/src/app/store",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
}
],
"optional_devices": [
{
"id": "zwave-serial-controller",
"kind": "character-device",
"purpose": "serial",
"enable_prompt": "Pass through a Z-Wave USB or serial controller",
"enabled_default": false,
"required_by_compose": false,
"path_prompt": "Controller path on the Proxmox host; prefer /dev/serial/by-id/...",
"host_path_default": "/dev/serial/by-id/insert_stick_reference_here",
"container_path_strategy": "same-as-host",
"mode": "preserve-host",
"deny_write": false,
"gid_strategy": "host-device-gid"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 8091,
"path": "/",
"timeout_seconds": 180,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": false
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"container_name",
"devices",
"environment",
"image",
"networks",
"ports",
"restart",
"stop_signal",
"tty",
"volumes"
],
"untranslated_blockers": [],
"policy": "The single-image recipe has passed installation, UI/login, restart, backup and recovery, modification, and engine checks. Host-bind storage has not been checked. Radio control remains untested because no compatible Z-Wave coordinator was attached during the lab test."
},
"validation": {
"schema": "passed-static-validation",
"image_resolution": "passed-skopeo-download-and-layer-verification",
"clean_install": "passed-default-install-and-health-check",
"advanced_install": "pending-custom-install-summary-validation",
"web_response": "passed-ui-and-generated-login",
"credentials": "passed-generated-login-before-and-after-restore",
"restart_persistence": "passed-restart-with-store-preserved",
"backup_restore": "passed-proxmox-backup-and-manager-recover-new-vmid",
"update_preserves_data": "no-update-available-at-check",
"modification": "passed-cpu-ram-up-down-without-recreation",
"managed_volume": "passed-store-volume-and-recovery",
"host_bind": "pending",
"hardware_radio": "not-tested-no-z-wave-coordinator-on-host",
"removal": "passed-remove-original-and-restored-ct-and-local-backup-cleanup"
},
"lifecycle": {
"update_strategy": "replace-rootfs-from-new-oci-image-preserve-managed-volumes",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": "11.25.2",
"image_created": null
},
"change_detection": "compare-resolved-architecture-digest",
"automatic_unattended_updates": false
}
}
+5 -1
View File
@@ -432,6 +432,10 @@
"metabase": "monitoring",
"kopia": "backup",
"restic-rest-server": "backup",
"netalertx": "monitoring"
"netalertx": "monitoring",
"kitchenowl": "productivity",
"unbound": "adblock",
"spoolman": "tools",
"zwave-js-ui": "smarthome"
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"engine_api": 1,
"description": "Increment engine_api when catalog recipes require runtime capabilities unavailable in earlier catalog-refresh clients."
}
@@ -323,6 +323,9 @@
"AceStream HTTP Proxy has no web interface: a media player opens its streams.",
"HLS stream: port 6878, path /ace/manifest.m3u8?id= followed by the channel ID.",
"MPEG-TS stream: port 6878, path /ace/getstream?id= followed by the channel ID."
],
"non_persistent_image_volumes": [
"/home/appuser/.ACEStream"
]
}
},
+585
View File
@@ -0,0 +1,585 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-airdcpp-webclient",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "AirDC++ Web Client",
"es_ES": "AirDC++ Web Client"
},
"tagline": {
"en_US": "Direct Connect file sharing with a web interface",
"es_ES": "Intercambio de archivos Direct Connect con interfaz web"
},
"description": {
"en_US": "AirDC++ Web Client using the community-maintained gangefors image. Configuration, downloads and shared content use separate persistent paths.",
"es_ES": "AirDC++ Web Client con la imagen comunitaria de gangefors. La configuración, las descargas y los archivos compartidos usan rutas persistentes separadas."
},
"category": "downloads",
"category_label": "Files & Downloads",
"author": "gangefors",
"developer": "AirDC++",
"icon": "https://raw.githubusercontent.com/airdcpp-web/airdcpp-webui/eeeea5025a5e720f38dac53ced8e002940f00a74/resources/images/logo.svg",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64"
],
"launch": {
"scheme": "http",
"port": 5600,
"path": "/"
},
"website": "https://airdcpp-web.github.io/",
"documentation": "https://github.com/gangefors/docker-airdcpp-webclient",
"repository": "https://github.com/gangefors/docker-airdcpp-webclient",
"tips": [
"The upstream initial login is admin / password. Change it in Settings > System > Users before allowing access beyond a trusted LAN.",
"Configuration uses /.airdcpp on a managed Proxmox volume included in backups. /Downloads and /Share can use managed volumes or explicitly selected host directories.",
"Files under /Share are shared by AirDC++. Select the contents deliberately; router forwarding and hub configuration are separate administrator actions.",
"PUID and PGID default to 1000 and must be at least 101. The original entrypoint creates the application account; volume ownership follows these values.",
"Open HTTP port 5600 on the dedicated LXC address. HTTPS port 5601 uses the upstream self-signed certificate; use a trusted reverse proxy certificate for remote web access.",
"Incoming Direct Connect traffic uses TCP and UDP 21248 and TLS TCP 21249. ProxMenux keeps those native ports and does not configure your router."
],
"mini_changelog": [],
"display_version": null,
"updated_at": "2026-10-25"
},
"source": {
"provider": "gangefors",
"repository": "https://github.com/gangefors/docker-airdcpp-webclient",
"revision": "37f2e939c152fb2c0158bc83bc76cc972aed965e",
"image_repository_url": "https://hub.docker.com/r/gangefors/airdcpp-webclient",
"readme_pushed_at": "2026-10-25T11:51:53Z",
"compose_sha256": "4ce8aec542cfc3e7f5ca142e309a41f04aca444bd1724ca1741c96acb5c3d5bf",
"generated_at": "2026-11-03T11:47:04+00:00",
"default_branch": "master",
"readme_raw_url": "https://raw.githubusercontent.com/gangefors/docker-airdcpp-webclient/37f2e939c152fb2c0158bc83bc76cc972aed965e/docker-compose.yml"
},
"container_contract": {
"service_name": "airdcpp",
"container_name": "airdcpp",
"image": {
"reference": "docker.io/gangefors/airdcpp-webclient:latest",
"registry": "docker.io",
"repository": "docker.io/gangefors/airdcpp-webclient",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "0022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
}
],
"volumes": [
{
"id": "config",
"container_path": "/.airdcpp",
"compose_source_example": "./config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
},
{
"id": "downloads",
"container_path": "/Downloads",
"compose_source_example": "./downloads",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 32
}
},
{
"id": "share",
"container_path": "/Share",
"compose_source_example": "./share",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 32
}
}
],
"ports": [
{
"container_port": 5600,
"published_example": 5600,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 5601,
"published_example": 5601,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 21248,
"published_example": 21248,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 21248,
"published_example": 21248,
"protocol": "udp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 21249,
"published_example": 21249,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "name: airdcpp-webclient\nservices:\n airdcpp:\n image: docker.io/gangefors/airdcpp-webclient:latest\n restart: unless-stopped\n environment:\n PUID: '1000'\n PGID: '1000'\n UMASK: '0022'\n ports:\n - 5600:5600\n - 5601:5601\n - 21248:21248/tcp\n - 21248:21248/udp\n - 21249:21249/tcp\n volumes:\n - ./config:/.airdcpp\n - ./downloads:/Downloads\n - ./share:/Share\n"
},
"compose_stack": {
"project_name": "airdcpp-webclient",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "airdcpp",
"service_count": 1,
"services": [
{
"name": "airdcpp",
"image": "docker.io/gangefors/airdcpp-webclient:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "docker.io/gangefors/airdcpp-webclient:latest",
"restart": "unless-stopped",
"environment": {
"PUID": "1000",
"PGID": "1000",
"UMASK": "0022"
},
"ports": [
"5600:5600",
"5601:5601",
"21248:21248/tcp",
"21248:21248/udp",
"21249:21249/tcp"
],
"volumes": [
"./config:/.airdcpp",
"./downloads:/Downloads",
"./share:/Share"
]
}
}
],
"top_level": {
"name": "airdcpp-webclient"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "airdcpp-volume-0",
"service": "airdcpp",
"container_path": "/.airdcpp",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "airdcpp-volume-1",
"service": "airdcpp",
"container_path": "/Downloads",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "airdcpp-volume-2",
"service": "airdcpp",
"container_path": "/Share",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"airdcpp"
],
"stop_order": [
"airdcpp"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "http",
"port": 5600,
"path": "/",
"source": "https://github.com/gangefors/docker-airdcpp-webclient"
}
],
"credentials": [
{
"label": "AirDC++ administrator",
"type": "static-default",
"username": "admin",
"password": "password",
"change_required": true,
"source": "https://github.com/gangefors/docker-airdcpp-webclient#run-the-application"
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/.airdcpp",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/Downloads",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/Share",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 5600,
"path": "/index.html",
"timeout_seconds": 180,
"request_timeout_seconds": 5,
"stability_seconds": 4,
"verify_tls": true
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community image and single-LXC contract reviewed against the publisher Compose and entrypoint; Linux amd64 confirmed in the registry manifest. Runtime lifecycle checks remain pending."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending",
"authenticated_login": "pending",
"advanced_install": "pending",
"host_bind_storage": "pending",
"managed_storage": "pending",
"removal": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+453
View File
@@ -0,0 +1,453 @@
{
"schema_version": "0.4.0",
"kind": "proxmenux.oci-template",
"id": "image-authelia",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Authelia",
"es_ES": "Authelia"
},
"tagline": {
"en_US": "Single sign-on and multi-factor authentication",
"es_ES": "Inicio de sesión único y autenticación multifactor"
},
"description": {
"en_US": "An open-source authentication and authorization server for protecting web applications. This single-image profile provides a local SQLite database and file notifications; configure your domain, reverse proxy and access rules before protecting other services.",
"es_ES": "Servidor de autenticación y autorización de código abierto para proteger aplicaciones web. Este perfil de una sola imagen incluye una base de datos SQLite local y notificaciones en archivo; configura el dominio, el proxy inverso y las reglas de acceso antes de proteger otros servicios."
},
"category": "security",
"category_label": "Authentication & Security",
"author": "Authelia",
"developer": "Authelia",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/authelia.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 9091,
"path": "/"
},
"website": "https://www.authelia.com/",
"documentation": "https://www.authelia.com/integration/deployment/docker/",
"repository": "https://github.com/authelia/authelia",
"tips": [
"The installer creates a unique admin password and stores only its Argon2id hash in /config/users_database.yml. The password is shown in the installation result.",
"Authelia requires an HTTPS portal URL and a cookie domain matching that hostname. If you use Nginx Proxy Manager, follow the official integration guide and configure trusted proxies and forward-auth separately.",
"The default notifier writes messages to /config/notification.txt. Configure SMTP in /config/configuration.yml if you want email delivery.",
"The initial access-control policy is one_factor. Add explicit access-control rules before attaching Authelia to protected proxy hosts."
],
"mini_changelog": [],
"display_version": "4.39.28",
"updated_at": "2026-09-17"
},
"source": {
"provider": "authelia",
"repository": "https://github.com/authelia/authelia",
"default_branch": "master",
"revision": "8da42b2348b0351c6284a2940a9c5eec3d4cd3fd",
"readme_raw_url": "https://raw.githubusercontent.com/authelia/authelia/v4.39.28/examples/compose/lite/compose.yml",
"readme_pushed_at": "2026-09-17T12:13:30Z",
"compose_sha256": "848ce0f70e502981a050ac200d9d1882978a6c3b0f9f0dfcc6d52ce66ca37fb5",
"generated_at": "2026-11-03T09:10:57+00:00",
"image_repository_url": "https://hub.docker.com/r/authelia/authelia"
},
"container_contract": {
"service_name": "authelia",
"container_name": "authelia",
"image": {
"reference": "docker.io/authelia/authelia:4.39.28",
"registry": "docker.io",
"repository": "docker.io/authelia/authelia",
"tag": "4.39.28",
"digest": null,
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
},
"environment": [
{
"name": "PROXMENUX_ADMIN_PASSWORD",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-first-start"
},
{
"name": "AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "AUTHELIA_SESSION_SECRET",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "AUTHELIA_STORAGE_ENCRYPTION_KEY",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "X_AUTHELIA_CONFIG_FILTERS",
"example": "template",
"required": true,
"sensitive": false,
"source": "authelia-container"
},
{
"name": "PROXMENUX_AUTHELIA_COOKIE_DOMAIN",
"example": "",
"prompt": "Authelia session cookie domain for this portal (for example example.com)",
"required": true,
"sensitive": false,
"source": "administrator"
},
{
"name": "PROXMENUX_AUTHELIA_URL",
"example": "",
"prompt": "Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)",
"required": true,
"sensitive": false,
"source": "administrator"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./authelia",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
}
],
"ports": [
{
"container_port": 9091,
"published_example": 9091,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n authelia:\n entrypoint:\n - /bin/sh\n - /usr/local/bin/proxmenux-authelia-bootstrap\n environment:\n AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET: ${GENERATED_RESET_PASSWORD_JWT_SECRET}\n AUTHELIA_SESSION_SECRET: ${GENERATED_SESSION_SECRET}\n AUTHELIA_STORAGE_ENCRYPTION_KEY: ${GENERATED_STORAGE_ENCRYPTION_KEY}\n PROXMENUX_ADMIN_PASSWORD: ${GENERATED_ADMIN_PASSWORD}\n PROXMENUX_AUTHELIA_COOKIE_DOMAIN: ${AUTHELIA_COOKIE_DOMAIN}\n PROXMENUX_AUTHELIA_URL: ${AUTHELIA_URL}\n X_AUTHELIA_CONFIG_FILTERS: template\n image: docker.io/authelia/authelia:4.39.28\n ports:\n - 9091:9091\n restart: unless-stopped\n volumes:\n - ./authelia:/config\n"
},
"first_run": {
"endpoints": [
{
"label": "Authelia Web UI",
"scheme": "http",
"port": 9091,
"path": "/",
"source": "official-image"
}
],
"credentials": [
{
"label": "Authelia administrator",
"type": "configured-or-installer-generated",
"username": "admin",
"password": null,
"password_environment": "PROXMENUX_ADMIN_PASSWORD",
"change_required": false,
"source": "Generated on first start and stored as an Argon2id hash in the persistent users file."
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 512,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 60
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"runtime": {
"compose_entrypoint": [
"/bin/sh",
"/usr/local/bin/proxmenux-authelia-bootstrap"
]
},
"generated_sensitive_environment": {
"PROXMENUX_ADMIN_PASSWORD": {
"strategy": "token-hex",
"bytes": 24,
"prompt": false
},
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"AUTHELIA_SESSION_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"AUTHELIA_STORAGE_ENCRYPTION_KEY": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
}
},
"minimum_secret_length": {
"PROXMENUX_ADMIN_PASSWORD": 24,
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET": 32,
"AUTHELIA_SESSION_SECRET": 32,
"AUTHELIA_STORAGE_ENCRYPTION_KEY": 32
},
"generated_files": [
{
"container_path": "/config/configuration.yml",
"mode": "0600",
"owner": "mapped-root",
"only_if_missing": true,
"content": "---\nserver:\n address: 'tcp://:9091'\n\nlog:\n level: 'info'\n\ntotp:\n issuer: 'Authelia'\n\nidentity_validation:\n reset_password:\n jwt_secret: 'configured-by-environment'\n\nauthentication_backend:\n file:\n path: '/config/users_database.yml'\n watch: true\n\naccess_control:\n default_policy: 'one_factor'\n\nsession:\n secret: 'configured-by-environment'\n cookies:\n - name: 'authelia_session'\n domain: '{{ env \"PROXMENUX_AUTHELIA_COOKIE_DOMAIN\" }}'\n authelia_url: '{{ env \"PROXMENUX_AUTHELIA_URL\" }}'\n expiration: '1 hour'\n inactivity: '5 minutes'\n\nstorage:\n encryption_key: 'configured-by-environment'\n local:\n path: '/config/db.sqlite3'\n\nnotifier:\n filesystem:\n filename: '/config/notification.txt'\n"
},
{
"container_path": "/usr/local/bin/proxmenux-authelia-bootstrap",
"mode": "0700",
"owner": "mapped-root",
"only_if_missing": false,
"content": "#!/bin/sh\nset -eu\numask 077\n\nusers_file=/config/users_database.yml\nif [ ! -s \"$users_file\" ]; then\n : \"${PROXMENUX_ADMIN_PASSWORD:?ProxMenux did not provide an initial administrator password}\"\n mkdir -p /config\n hash_output=$(authelia crypto hash generate argon2 --password \"$PROXMENUX_ADMIN_PASSWORD\" --no-confirm)\n password_hash=$(printf '%s\\n' \"$hash_output\" | sed -n 's/^Digest: //p')\n case \"$password_hash\" in\n '$argon2id$'*) ;;\n *) printf '%s\\n' 'Authelia did not return an Argon2id password hash' >&2; exit 1 ;;\n esac\n temporary_file=\"${users_file}.tmp.$$\"\n cat >\"$temporary_file\" <<EOF\nusers:\n admin:\n disabled: false\n displayname: 'Authelia Administrator'\n password: \"$password_hash\"\n groups:\n - 'admins'\nEOF\n chmod 0600 \"$temporary_file\"\n mv -f \"$temporary_file\" \"$users_file\"\nfi\nunset PROXMENUX_ADMIN_PASSWORD\nexec /app/entrypoint.sh \"$@\"\n"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 9091,
"path": "/api/health",
"timeout_seconds": 240,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"adaptations": [
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "The application listens on the same container ports at its dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Users open the LXC address instead of the Proxmox host address.",
"validation": "pending-per-application"
},
{
"id": "compose-environment-overlay",
"upstream_behavior": "Compose environment values override OCI image environment values.",
"native_lxc_behavior": "ProxMenux merges the same values into lxc.environment.runtime while the CT is stopped.",
"reason": "PVE imports image Env automatically; Compose values still need to override it.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "stop-grace-period",
"upstream_behavior": "Docker waits for Compose stop_grace_period before forcing termination.",
"native_lxc_behavior": "ProxMenux records the same timeout for its pct shutdown lifecycle operations.",
"reason": "Proxmox has no equivalent per-CT persistent restart-policy field; startup.down is not a shutdown timeout.",
"behavioral_impact": "Normal Proxmox node shutdown remains governed by the node-wide shutdown policy.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "pending-per-application"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "A single-image profile for the Authelia authentication portal. ProxMenux creates a unique initial administrator account; the local notifier and SQLite storage are kept in /config. Reverse-proxy trust and explicit access-control rules remain administrator settings."
},
"validation": {
"schema": "pending-local-validation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "replace-rootfs-from-new-oci-image-preserve-managed-volumes",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+62 -2
View File
@@ -76,6 +76,38 @@
"backup": true,
"default_size_gb": 2
}
},
{
"id": "volume-1",
"container_path": "/etc/bind",
"compose_source_example": "./config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
},
{
"id": "volume-2",
"container_path": "/var/lib/bind",
"compose_source_example": "./lib",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
@@ -123,7 +155,9 @@
"53:53/tcp"
],
"volumes": [
"./bind:/var/cache/bind"
"./bind:/var/cache/bind",
"./config:/etc/bind",
"./lib:/var/lib/bind"
]
}
}
@@ -151,6 +185,28 @@
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "bind9-volume-1",
"service": "bind9",
"container_path": "/etc/bind",
"mode": "managed-volume",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "bind9-volume-2",
"service": "bind9",
"container_path": "/var/lib/bind",
"mode": "managed-volume",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
@@ -349,7 +405,11 @@
"validation": "not-requested-by-compose"
}
],
"installer_profile": {},
"installer_profile": {
"non_persistent_image_volumes": [
"/var/log"
]
},
"catalog": {
"replaces_discovered_ids": []
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-cadcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "CADCraft",
"es_ES": "CADCraft"
},
"tagline": {
"en_US": "Computer-aided design and drafting in your browser",
"es_ES": "Diseño CAD y dibujo técnico en el navegador"
},
"description": {
"en_US": "CADCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "CADCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/cadcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/cadcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/cadcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/cadcraft",
"readme_pushed_at": "",
"compose_sha256": "ab46cb8e87addb261680a50fc8bdde1f9d689a0d14f6ca570eaf11e43868655a",
"generated_at": "2026-11-03T12:57:27+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/cadcraft.yaml"
},
"container_contract": {
"service_name": "cadcraft",
"container_name": "cadcraft",
"image": {
"reference": "docker.io/junkerderprovinz/cadcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/cadcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n cadcraft:\n image: junkerderprovinz/cadcraft:latest\n container_name: cadcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "cadcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "cadcraft",
"service_count": 1,
"services": [
{
"name": "cadcraft",
"image": "junkerderprovinz/cadcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/cadcraft:latest",
"container_name": "cadcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "cadcraft-volume-0",
"service": "cadcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "cadcraft-volume-1",
"service": "cadcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"cadcraft"
],
"stop_order": [
"cadcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+7 -1
View File
@@ -339,7 +339,13 @@
"validation": "not-requested-by-compose"
}
],
"installer_profile": {}
"installer_profile": {
"non_persistent_image_volumes": [
"/etc/chrony",
"/run/chrony",
"/var/lib/chrony"
]
}
},
"compatibility": {
"automatic_install_candidate": true,
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-deckcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "DeckCraft",
"es_ES": "DeckCraft"
},
"tagline": {
"en_US": "Presentations and slide decks in your browser",
"es_ES": "Presentaciones y diapositivas en el navegador"
},
"description": {
"en_US": "DeckCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "DeckCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/deckcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/deckcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/deckcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/deckcraft",
"readme_pushed_at": "",
"compose_sha256": "38d24b673dd5fb50e00d1094e681112671cf04a8e99952021f476c8b2754ef05",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/deckcraft.yaml"
},
"container_contract": {
"service_name": "deckcraft",
"container_name": "deckcraft",
"image": {
"reference": "docker.io/junkerderprovinz/deckcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/deckcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n deckcraft:\n image: junkerderprovinz/deckcraft:latest\n container_name: deckcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "deckcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "deckcraft",
"service_count": 1,
"services": [
{
"name": "deckcraft",
"image": "junkerderprovinz/deckcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/deckcraft:latest",
"container_name": "deckcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "deckcraft-volume-0",
"service": "deckcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "deckcraft-volume-1",
"service": "deckcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"deckcraft"
],
"stop_order": [
"deckcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-designcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "DesignCraft",
"es_ES": "DesignCraft"
},
"tagline": {
"en_US": "Page layout and publishing in your browser",
"es_ES": "Maquetación y publicación en el navegador"
},
"description": {
"en_US": "DesignCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "DesignCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/designcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/designcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/designcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/designcraft",
"readme_pushed_at": "",
"compose_sha256": "68fdc2548c3ecedc792ff41e1ce7002d8f0219e78781b89265ce77761685a0fd",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/designcraft.yaml"
},
"container_contract": {
"service_name": "designcraft",
"container_name": "designcraft",
"image": {
"reference": "docker.io/junkerderprovinz/designcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/designcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n designcraft:\n image: junkerderprovinz/designcraft:latest\n container_name: designcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "designcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "designcraft",
"service_count": 1,
"services": [
{
"name": "designcraft",
"image": "junkerderprovinz/designcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/designcraft:latest",
"container_name": "designcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "designcraft-volume-0",
"service": "designcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "designcraft-volume-1",
"service": "designcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"designcraft"
],
"stop_order": [
"designcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-effectcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "EffectCraft",
"es_ES": "EffectCraft"
},
"tagline": {
"en_US": "Motion graphics and compositing in your browser",
"es_ES": "Animación gráfica y composición en el navegador"
},
"description": {
"en_US": "EffectCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "EffectCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/effectcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/effectcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/effectcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/effectcraft",
"readme_pushed_at": "",
"compose_sha256": "8dde56d083a5120e342967f15141e95d742d19ea0c6b782c5552d40438b46ef7",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/effectcraft.yaml"
},
"container_contract": {
"service_name": "effectcraft",
"container_name": "effectcraft",
"image": {
"reference": "docker.io/junkerderprovinz/effectcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/effectcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n effectcraft:\n image: junkerderprovinz/effectcraft:latest\n container_name: effectcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "effectcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "effectcraft",
"service_count": 1,
"services": [
{
"name": "effectcraft",
"image": "junkerderprovinz/effectcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/effectcraft:latest",
"container_name": "effectcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "effectcraft-volume-0",
"service": "effectcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "effectcraft-volume-1",
"service": "effectcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"effectcraft"
],
"stop_order": [
"effectcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-figcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "FigCraft",
"es_ES": "FigCraft"
},
"tagline": {
"en_US": "Interface design and prototyping in your browser",
"es_ES": "Diseño de interfaces y prototipos en el navegador"
},
"description": {
"en_US": "FigCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "FigCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/figcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/figcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/figcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/figcraft",
"readme_pushed_at": "",
"compose_sha256": "b47cfa4e01943f509964b0027b9385d00fe6d233d31e24cdc117a4a4dd153262",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/figcraft.yaml"
},
"container_contract": {
"service_name": "figcraft",
"container_name": "figcraft",
"image": {
"reference": "docker.io/junkerderprovinz/figcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/figcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n figcraft:\n image: junkerderprovinz/figcraft:latest\n container_name: figcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "figcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "figcraft",
"service_count": 1,
"services": [
{
"name": "figcraft",
"image": "junkerderprovinz/figcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/figcraft:latest",
"container_name": "figcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "figcraft-volume-0",
"service": "figcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "figcraft-volume-1",
"service": "figcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"figcraft"
],
"stop_order": [
"figcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-filmcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "FilmCraft",
"es_ES": "FilmCraft"
},
"tagline": {
"en_US": "Video editing in your browser",
"es_ES": "Edición de vídeo en el navegador"
},
"description": {
"en_US": "FilmCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "FilmCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/filmcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/filmcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/filmcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/filmcraft",
"readme_pushed_at": "",
"compose_sha256": "fa1e82ca686a530579d91c9d75184adb800453607baee37ad15ac3cfbf39d746",
"generated_at": "2026-11-03T12:57:28+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/filmcraft.yaml"
},
"container_contract": {
"service_name": "filmcraft",
"container_name": "filmcraft",
"image": {
"reference": "docker.io/junkerderprovinz/filmcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/filmcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n filmcraft:\n image: junkerderprovinz/filmcraft:latest\n container_name: filmcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "filmcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "filmcraft",
"service_count": 1,
"services": [
{
"name": "filmcraft",
"image": "junkerderprovinz/filmcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/filmcraft:latest",
"container_name": "filmcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "filmcraft-volume-0",
"service": "filmcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "filmcraft-volume-1",
"service": "filmcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"filmcraft"
],
"stop_order": [
"filmcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+4 -1
View File
@@ -409,7 +409,10 @@
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"non_persistent_image_volumes": [
"/gotosocial/.cache"
]
}
},
"compatibility": {
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-gridcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "GridCraft",
"es_ES": "GridCraft"
},
"tagline": {
"en_US": "Spreadsheets in your browser",
"es_ES": "Hojas de cálculo en el navegador"
},
"description": {
"en_US": "GridCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "GridCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/gridcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/gridcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/gridcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/gridcraft",
"readme_pushed_at": "",
"compose_sha256": "dcd244dd54033b4a00e1220ff8885ba26a5508414ab5069f7ab9456476fbb420",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/gridcraft.yaml"
},
"container_contract": {
"service_name": "gridcraft",
"container_name": "gridcraft",
"image": {
"reference": "docker.io/junkerderprovinz/gridcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/gridcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n gridcraft:\n image: junkerderprovinz/gridcraft:latest\n container_name: gridcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "gridcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "gridcraft",
"service_count": 1,
"services": [
{
"name": "gridcraft",
"image": "junkerderprovinz/gridcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/gridcraft:latest",
"container_name": "gridcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "gridcraft-volume-0",
"service": "gridcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "gridcraft-volume-1",
"service": "gridcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"gridcraft"
],
"stop_order": [
"gridcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+5 -1
View File
@@ -345,7 +345,11 @@
"validation": "not-requested-by-compose"
}
],
"installer_profile": {},
"installer_profile": {
"non_persistent_image_volumes": [
"/tmp"
]
},
"catalog": {
"replaces_discovered_ids": []
}
+35 -1
View File
@@ -94,6 +94,22 @@
"backup": true,
"default_size_gb": 8
}
},
{
"id": "volume-2",
"container_path": "/etc/nginx/ssl",
"compose_source_example": "./ssl",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
@@ -134,7 +150,8 @@
],
"volumes": [
"./data:/var/www/app/data",
"./plugins:/var/www/app/plugins"
"./plugins:/var/www/app/plugins",
"./ssl:/etc/nginx/ssl"
]
}
}
@@ -171,6 +188,17 @@
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "kanboard-volume-2",
"service": "kanboard",
"container_path": "/etc/nginx/ssl",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
@@ -391,6 +419,12 @@
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/etc/nginx/ssl",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
+383
View File
@@ -0,0 +1,383 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-kitchenowl",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "KitchenOwl"
},
"tagline": {
"en_US": "Self-hosted grocery list and recipe manager"
},
"description": {
"en_US": "Manage shared shopping lists, recipes and meal plans in one self-hosted app."
},
"category": "productivity",
"category_label": "Productivity & Workflows",
"author": "Tom Bursch",
"developer": "Tom Bursch",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/kitchenowl.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 80,
"path": "/"
},
"website": "https://kitchenowl.org/",
"documentation": "https://docs.kitchenowl.org/self-hosting/",
"repository": "https://github.com/TomBursch/kitchenowl",
"tips": [
"This recipe follows KitchenOwl’s standard official Compose deployment: a web frontend and backend in separate OCI LXCs.",
"The upstream sample uses PLEASE_CHANGE_ME for JWT_SECRET_KEY; this recipe generates a unique signing key at install time."
],
"mini_changelog": [],
"display_version": null,
"updated_at": "2026-11-01"
},
"source": {
"provider": "tombursch",
"repository": "https://github.com/TomBursch/kitchenowl",
"revision": "60a012ea5cae829878f78a46a585a7ee530b069a",
"image_repository_url": "https://hub.docker.com/r/tombursch/kitchenowl-web",
"readme_pushed_at": "2026-11-01T23:22:22Z",
"compose_sha256": "f620124c2a4943d4f2465ee304677bc9ed172a088f0fe43f5db7cbc8f6424263",
"generated_at": "2026-11-02T20:13:05+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/TomBursch/kitchenowl/main/docker-compose.yml"
},
"container_contract": {
"service_name": "front",
"container_name": "front",
"image": {
"reference": "tombursch/kitchenowl-web:latest",
"registry": "docker.io",
"repository": "tombursch/kitchenowl-web",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [],
"volumes": [],
"ports": [
{
"container_port": 80,
"published_example": 80,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [
{
"name": "back",
"image": "tombursch/kitchenowl-backend:latest"
}
],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n back:\n environment:\n JWT_SECRET_KEY: ${GENERATED_JWT_SECRET_KEY}\n image: tombursch/kitchenowl-backend:latest\n restart: unless-stopped\n volumes:\n - read_only: false\n source: kitchenowl_data\n target: /data\n front:\n depends_on:\n - back\n image: tombursch/kitchenowl-web:latest\n ports:\n - 80:80\n restart: unless-stopped\n volumes: []\nvolumes:\n kitchenowl_data: null\n"
},
"compose_stack": {
"project_name": "kitchenowl",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "front",
"service_count": 2,
"services": [
{
"name": "back",
"image": "tombursch/kitchenowl-backend:latest",
"is_main": false,
"role": "dependency",
"vmid_offset": 1,
"depends_on": [],
"frontend_network": false,
"private_network": true,
"compose": {
"environment": {
"JWT_SECRET_KEY": "${GENERATED_JWT_SECRET_KEY}"
},
"image": "tombursch/kitchenowl-backend:latest",
"restart": "unless-stopped",
"volumes": [
{
"source": "kitchenowl_data",
"target": "/data",
"read_only": false
}
],
"healthcheck": {
"test": [
"CMD-SHELL",
"uwsgi_curl localhost:5000 /api/health/8M4F88S8ooi4sMbLBfkkV7ctWwgibW6V || exit 1"
],
"interval": "60s",
"timeout": "3s",
"retries": 3
}
}
},
{
"name": "front",
"image": "tombursch/kitchenowl-web:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [
"back"
],
"frontend_network": true,
"private_network": true,
"compose": {
"depends_on": [
"back"
],
"image": "tombursch/kitchenowl-web:latest",
"ports": [
"80:80"
],
"restart": "unless-stopped",
"volumes": [],
"healthcheck": {
"test": [
"CMD-SHELL",
"curl -f http://localhost/ || exit 1"
],
"interval": "30s",
"timeout": "3s",
"retries": 3
}
}
}
],
"top_level": {
"volumes": {
"kitchenowl_data": null
}
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": true,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "back-volume-0",
"service": "back",
"container_path": "/data",
"mode": "managed-volume",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 2,
"start_order": [
"back",
"front"
],
"stop_order": [
"front",
"back"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "generated-jwt-secret-key",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "back",
"environment_variable": "JWT_SECRET_KEY"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "KitchenOwl",
"scheme": "http",
"port": 80,
"path": "/",
"source": "upstream-documentation"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "generated-jwt-signing-key",
"upstream_behavior": "The official Compose example uses the placeholder PLEASE_CHANGE_ME for JWT_SECRET_KEY and instructs operators to replace it.",
"native_lxc_behavior": "ProxMenux generates a unique cryptographically random JWT signing key and supplies it to the backend service.",
"reason": "Avoid deploying the documented placeholder or placing a signing secret in the public recipe.",
"behavioral_impact": "The generated key is not an app login credential; KitchenOwl has no catalog-provided default account.",
"validation": "pending-runtime"
},
{
"id": "image-healthchecks-preserved",
"upstream_behavior": "The web and backend OCI images declare Docker healthchecks in image metadata.",
"native_lxc_behavior": "The current image healthchecks are recorded in the stack so ProxMenux can check backend readiness and frontend availability during first start.",
"reason": "The Compose file inherits these checks from its images instead of declaring them itself.",
"behavioral_impact": "Checks gate stack startup; Docker does not run as a separate health-monitoring daemon inside the LXCs.",
"validation": "pending-runtime"
}
],
"custom_compose_stack": true,
"custom_compose_interpolated": false,
"stack_image_entrypoints": {},
"installer_profile": {
"stack_driver": "generic-multi-lxc-stack",
"volume_preparations": [
{
"container_path": "/data",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
]
},
"stack_completion_notes": [
"Open the web address and follow KitchenOwl’s onboarding to create the first account; no default account is configured."
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "The official two-image Compose stack is mapped to native Proxmox OCI LXCs with private service networking. Lab checks confirmed installation, web/API behavior, persistence, backup and recovery, modification, managed storage, and host-bind storage. Advanced custom settings have not been validated."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "passed-default-official-two-service-stack-and-first-start",
"advanced_install": "pending-custom-install-summary-validation",
"service_health": "passed-web-api-and-created-user-household-list-item",
"restart_persistence": "passed-managed-and-host-bind-data",
"backup_restore": "passed-manager-recover-new-vmids-stack-network-and-data",
"update_preserves_data": "no-update-available-at-check",
"modification": "passed-added-managed-volume-without-image-pull-or-container-recreate",
"volumes": "passed-managed-storage-and-host-bind-with-owner-and-data-check",
"removal": "passed-manager-removal-temporary-data-cleaned-after-retention-check"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false,
"dependency_lifecycle": {
"implementation": "proxmox-hookscript",
"trigger": "main-lxc-pre-start",
"waits_for_dependency_healthchecks": true,
"stops_dependencies_with_main": false
}
}
}
+490
View File
@@ -0,0 +1,490 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-krusader",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Krusader",
"es_ES": "Krusader"
},
"tagline": {
"en_US": "KDE's twin-panel file manager in a browser-based desktop.",
"es_ES": "El gestor de archivos de dos paneles de KDE, disponible desde el navegador."
},
"description": {
"en_US": "Open Krusader in a browser and manage files from a directory you explicitly mount at /storage. The maintained jlesage image provides the graphical desktop; ProxMenux runs it as one native OCI LXC.",
"es_ES": "Abre Krusader en el navegador y gestiona los archivos de una carpeta que montes expresamente en /storage. La imagen mantenida por jlesage incluye el escritorio gráfico; ProxMenux la ejecuta como un LXC OCI nativo."
},
"category": "desktop",
"category_label": "Browsers & Web Desktops",
"author": "jlesage",
"developer": "jlesage",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/krusader.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 5800,
"path": "/"
},
"website": "https://krusader.org/",
"documentation": "https://github.com/jlesage/docker-krusader",
"repository": "https://github.com/jlesage/docker-krusader",
"tips": [
"The web login uses HTTPS with an automatically generated self-signed certificate and password. Accept the certificate warning on the first visit or configure a trusted certificate.",
"Krusader can read, change and delete files in the directory mounted at /storage. Mount only the directory you intend to manage; the rest of the Proxmox host is not exposed.",
"The VNC port is not published. Use the browser interface on port 5800."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "jlesage",
"repository": "https://github.com/jlesage/docker-krusader",
"revision": "855c8140e1bb65b2a2526d82db44c808f23eb49f",
"image_repository_url": "https://hub.docker.com/r/jlesage/krusader",
"readme_pushed_at": "2026-09-22T15:18:17Z",
"compose_sha256": "9dd16cc30aa19afe7e148598c9cfb0c65c31606d67f3f22254c33a4d05212c7f",
"generated_at": "2026-11-02T20:05:40+00:00",
"default_branch": "master",
"readme_raw_url": "https://raw.githubusercontent.com/jlesage/docker-krusader/855c8140e1bb65b2a2526d82db44c808f23eb49f/README.md"
},
"container_contract": {
"service_name": "krusader",
"container_name": "krusader",
"image": {
"reference": "jlesage/krusader:latest",
"registry": "docker.io",
"repository": "jlesage/krusader",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "USER_ID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-image-default"
},
{
"name": "GROUP_ID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-image-default"
},
{
"name": "TZ",
"example": "Europe/Madrid",
"required": true,
"sensitive": false,
"source": "ProxMenux-local-timezone"
},
{
"name": "VNC_LOCALHOST_ONLY",
"example": "1",
"required": true,
"sensitive": false,
"source": "upstream-image-security-setting"
},
{
"name": "WEB_AUTHENTICATION",
"example": "1",
"required": true,
"sensitive": false,
"source": "upstream-image-security-setting"
},
{
"name": "WEB_AUTHENTICATION_USERNAME",
"example": "admin",
"required": true,
"sensitive": false,
"source": "upstream-image-security-setting"
},
{
"name": "WEB_AUTHENTICATION_PASSWORD",
"example": "${GENERATED_WEB_PASSWORD}",
"required": true,
"sensitive": true,
"source": "ProxMenux-generated-credential"
},
{
"name": "SECURE_CONNECTION",
"example": "1",
"required": true,
"sensitive": false,
"source": "upstream-image-security-setting"
}
],
"volumes": [
{
"id": "krusader-config",
"container_path": "/config",
"compose_source_example": "krusader-config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
},
{
"id": "krusader-storage",
"container_path": "/storage",
"compose_source_example": "/mnt/oci-shared/krusader/storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "host-bind",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
}
],
"ports": [
{
"container_port": 5800,
"published_example": 5800,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "name: krusader\nservices:\n krusader:\n image: jlesage/krusader:latest\n container_name: krusader\n restart: unless-stopped\n environment:\n USER_ID: '1000'\n GROUP_ID: '1000'\n TZ: Europe/Madrid\n VNC_LOCALHOST_ONLY: '1'\n WEB_AUTHENTICATION: '1'\n WEB_AUTHENTICATION_USERNAME: admin\n WEB_AUTHENTICATION_PASSWORD: ${GENERATED_WEB_PASSWORD}\n SECURE_CONNECTION: '1'\n ports:\n - 5800:5800/tcp\n volumes:\n - krusader-config:/config\n - /mnt/oci-shared/krusader/storage:/storage\nvolumes:\n krusader-config: {}\n"
},
"compose_stack": {
"project_name": "krusader",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "krusader",
"service_count": 1,
"services": [
{
"name": "krusader",
"image": "jlesage/krusader:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"environment": {
"GROUP_ID": "1000",
"SECURE_CONNECTION": "1",
"TZ": "Europe/Madrid",
"USER_ID": "1000",
"VNC_LOCALHOST_ONLY": "1",
"WEB_AUTHENTICATION": "1",
"WEB_AUTHENTICATION_PASSWORD": "${GENERATED_GENERATED_WEB_PASSWORD}",
"WEB_AUTHENTICATION_USERNAME": "admin"
},
"image": "jlesage/krusader:latest",
"ports": [
"5800:5800"
],
"volumes": [
"./config:/config",
"./storage:/storage"
]
}
}
],
"top_level": {
"name": "krusader"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "krusader-volume-0",
"service": "krusader",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "krusader-volume-1",
"service": "krusader",
"container_path": "/storage",
"mode": "user-selectable",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": "Host directory for Krusader:/storage",
"default": "host-bind",
"installation_choice": [
"managed-volume",
"host-bind"
]
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"krusader"
],
"stop_order": [
"krusader"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "generated-web-password",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "krusader",
"environment_variable": "WEB_AUTHENTICATION_PASSWORD"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "Krusader Web UI",
"scheme": "https",
"port": 5800,
"path": "/",
"source": "upstream-jlesage-secure-connection-and-web-authentication"
}
],
"credentials": [
{
"label": "Krusader Web UI",
"type": "configured-or-installer-generated",
"username": "admin",
"password": null,
"username_environment": "WEB_AUTHENTICATION_USERNAME",
"password_environment": "WEB_AUTHENTICATION_PASSWORD",
"change_required": false,
"source": "ProxMenux generated password and upstream image environment",
"retrieval": null
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "web-authentication-https",
"upstream_behavior": "The jlesage image can protect its browser GUI with WEB_AUTHENTICATION and requires SECURE_CONNECTION for authenticated web access.",
"native_lxc_behavior": "Enable authenticated HTTPS on port 5800, generate a unique password at install and keep VNC bound to localhost.",
"reason": "Krusader can modify files exposed under /storage, so the browser endpoint must not be unauthenticated.",
"behavioral_impact": "The image generates a self-signed TLS certificate; a browser may ask to trust it on first access.",
"validation": "pending"
},
{
"id": "scoped-storage-mount",
"upstream_behavior": "Docker Compose mounts the selected host directory at /storage.",
"native_lxc_behavior": "The same selected directory is mounted in the dedicated OCI LXC; no other host paths are exposed.",
"reason": "The file manager must only see data explicitly selected by the user.",
"behavioral_impact": "Write access permits changing or deleting files in that one directory.",
"validation": "pending"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes web port 5800 on the Docker host.",
"native_lxc_behavior": "The native LXC listens on its own IP at port 5800 without Docker NAT.",
"reason": "The LXC has a dedicated network namespace and address.",
"behavioral_impact": "The port is reached at the LXC address rather than through a host-published port.",
"validation": "pending"
}
],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"uid": 1000,
"gid": 1000,
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"uid": 1000,
"gid": 1000,
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
"scheme": "https",
"port": 5800,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": false
},
"generated_sensitive_environment": {
"WEB_AUTHENTICATION_PASSWORD": {
"strategy": "token-hex",
"bytes": 16,
"prompt": false
}
},
"volume_owner": {
"uid": 1000,
"gid": 1000
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "passed-first-start",
"service_health": "passed-login-page-and-authenticated-session-http-200",
"restart_persistence": "passed-container-restart-and-host-bind-write-check",
"backup_restore": "pending",
"update_preserves_data": "pending",
"image_resolution": "passed-skopeo-327mb-11-layers-integrity",
"credentials": "passed-generated-password-login-and-session-cookie",
"advanced_install": "pending-custom-install-summary-validation",
"managed_volume": "passed-managed-config-volume",
"host_bind": "passed-storage-bind-owner-and-app-user-write",
"browser_visual": "pending-self-signed-certificate-review",
"modification": "pending",
"removal": "passed-manager-remove-ct-disks-record-and-empty-test-path-cleaned",
"web_authentication": "passed-generated-credential-post-and-session-cookie"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": "amd64",
"resolved_digest": "sha256:ecb77bb73b1d3c66720eefb07805f70289349b449d1ddaa15d120c399bd89cc4",
"image_version_label": "26.09.1",
"image_created": "2026-09-22T15:22:56.230858151Z"
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-lightcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "LightCraft",
"es_ES": "LightCraft"
},
"tagline": {
"en_US": "Photo library and RAW development in your browser",
"es_ES": "Biblioteca de fotos y revelado RAW en el navegador"
},
"description": {
"en_US": "LightCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "LightCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/lightcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/lightcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/lightcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/lightcraft",
"readme_pushed_at": "",
"compose_sha256": "26d20ee6d028b198f569b66116ff5b55d7ab08f2cc26a13400d0e444ce10ba0f",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/lightcraft.yaml"
},
"container_contract": {
"service_name": "lightcraft",
"container_name": "lightcraft",
"image": {
"reference": "docker.io/junkerderprovinz/lightcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/lightcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n lightcraft:\n image: junkerderprovinz/lightcraft:latest\n container_name: lightcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "lightcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "lightcraft",
"service_count": 1,
"services": [
{
"name": "lightcraft",
"image": "junkerderprovinz/lightcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/lightcraft:latest",
"container_name": "lightcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "lightcraft-volume-0",
"service": "lightcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "lightcraft-volume-1",
"service": "lightcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"lightcraft"
],
"stop_order": [
"lightcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+42 -6
View File
@@ -68,11 +68,18 @@
"source": "docker-compose"
},
{
"name": "LLAMA_ARG_CONTEXT_SIZE",
"name": "LLAMA_ARG_CTX_SIZE",
"example": "8192",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "LLAMA_ARG_MODELS_DIR",
"example": "/models",
"required": true,
"sensitive": false,
"source": "upstream-documentation"
}
],
"volumes": [
@@ -89,7 +96,7 @@
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
"default_size_gb": 32
}
}
],
@@ -135,7 +142,8 @@
],
"environment": [
"LLAMA_ARG_N_GPU_LAYERS=999",
"LLAMA_ARG_CONTEXT_SIZE=8192"
"LLAMA_ARG_CTX_SIZE=8192",
"LLAMA_ARG_MODELS_DIR=/models"
],
"devices": [
"/dev/dri:/dev/dri"
@@ -229,8 +237,8 @@
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"cores": 4,
"memory_mb": 8192,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
@@ -334,6 +342,28 @@
"0x1002"
]
}
],
"environment": [
{
"name": "LLAMA_ARG_FLASH_ATTN",
"value": "off"
},
{
"name": "LLAMA_ARG_UBATCH",
"value": "32"
},
{
"name": "LLAMA_ARG_BATCH",
"value": "128"
},
{
"name": "GGML_VK_DISABLE_F16",
"value": "1"
},
{
"name": "GGML_VK_DISABLE_ASYNC",
"value": "1"
}
]
},
{
@@ -420,7 +450,13 @@
]
}
]
}
},
"completion_notes": [
"llama.cpp shows every GGUF model saved in /models in its web UI and loads the one you choose.",
"To add a model, open the console of the container in Proxmox and download it into /models, for example:",
"curl -L -o /models/gemma-3-1b-it-Q4_K_M.gguf https://huggingface.co/ggml-org/gemma-3-1b-it-GGUF/resolve/main/gemma-3-1b-it-Q4_K_M.gguf",
"Then restart the container so the new model appears in the list."
]
},
"adaptations": [
{
@@ -0,0 +1,609 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-movistar-webdav-proxy",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Movistar / O2 Cloud WebDAV Proxy"
},
"tagline": {
"en_US": "Access Movistar and O2 Cloud from WebDAV clients and backup tools."
},
"description": {
"en_US": "Official uniextra image with a web dashboard for Movistar/O2 Cloud account linking. Persistent OAuth credentials, authenticated WebDAV and disk-backed temporary uploads."
},
"category": "backup",
"category_label": "Backup & Recovery",
"author": "uniextra",
"developer": "uniextra",
"icon": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/main/static/favicon.svg",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 5000,
"path": "/"
},
"website": "https://github.com/uniextra/MovistarWebDAVProxy",
"documentation": "https://github.com/uniextra/MovistarWebDAVProxy#readme",
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
"tips": [
"Link your Movistar or O2 account from the dashboard after installation.",
"Use the container IP and port 8080 for WebDAV. Docker's published port 5050 is not used by native OCI LXC.",
"Temporary uploads use a separate disk volume, excluded from backups, to avoid filling RAM."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "uniextra",
"repository": "https://github.com/uniextra/MovistarWebDAVProxy",
"revision": "e48485bc8bdf9745caa6249fdc92db6d28214549",
"image_repository_url": "https://hub.docker.com/r/uniextra/movistar-webdav-proxy",
"readme_pushed_at": "",
"compose_sha256": "e51607e979c1a776ececda038caeffb4195f443ebc017eba753a4b4ff8fd5c28",
"generated_at": "2026-11-02T23:42:04+00:00",
"readme_raw_url": "https://raw.githubusercontent.com/uniextra/MovistarWebDAVProxy/e48485bc8bdf9745caa6249fdc92db6d28214549/README.md"
},
"container_contract": {
"service_name": "movistar-webdav-proxy",
"container_name": "movistar-webdav-proxy",
"image": {
"reference": "uniextra/movistar-webdav-proxy:latest",
"registry": "docker.io",
"repository": "uniextra/movistar-webdav-proxy",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "WEBDAV_USER",
"example": "admin",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "WEBDAV_PASSWORD",
"example": "",
"required": true,
"sensitive": true,
"source": "docker-compose",
"prompt": "WebDAV and dashboard password (leave empty to generate)"
},
{
"name": "REQUIRE_AUTH",
"example": "true",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "TOKENS_ENCRYPTION_KEY",
"example": "",
"required": true,
"sensitive": true,
"source": "docker-compose"
},
{
"name": "MAX_UPLOAD_MB",
"example": "4096",
"required": false,
"sensitive": false,
"source": "docker-compose"
}
],
"volumes": [
{
"id": "tokens",
"container_path": "/app/tokens",
"compose_source_example": "./tokens",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
},
{
"id": "uploads",
"container_path": "/tmp",
"compose_source_example": "./tmp",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 5000,
"published_example": 5000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 8080,
"published_example": 8080,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n movistar-webdav-proxy:\n image: uniextra/movistar-webdav-proxy:v2.1.0\n container_name: movistar-webdav-proxy\n restart: unless-stopped\n read_only: true\n tmpfs:\n - /tmp\n security_opt:\n - no-new-privileges:true\n environment:\n - WEBDAV_USER=${WEBDAV_USER:-}\n - WEBDAV_PASSWORD=${WEBDAV_PASSWORD:-}\n - WEBUI_USER=${WEBUI_USER:-}\n - WEBUI_PASSWORD=${WEBUI_PASSWORD:-}\n ports:\n - \"${BIND_IP:-0.0.0.0}:${WEB_PORT:-5000}:5000\" # Panel Web de gestión y logs (usa BIND_IP=127.0.0.1 para acceso solo local)\n - \"${BIND_IP:-0.0.0.0}:${WEBDAV_PORT:-5050}:8080\" # Endpoint WebDAV (Duplicati / Synology HyperBackup)\n volumes:\n - movistar_tokens:/app/tokens\n\nvolumes:\n movistar_tokens:\n name: movistar_webdav_tokens\n"
},
"compose_stack": {
"project_name": "movistar-webdav-proxy",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "movistar-webdav-proxy",
"service_count": 1,
"services": [
{
"name": "movistar-webdav-proxy",
"image": "uniextra/movistar-webdav-proxy:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"environment": {
"MAX_UPLOAD_MB": "4096",
"REQUIRE_AUTH": "true",
"TOKENS_ENCRYPTION_KEY": "${GENERATED_TOKENS_ENCRYPTION_KEY}",
"WEBDAV_PASSWORD": "${GENERATED_WEBDAV_PASSWORD}",
"WEBDAV_USER": "admin"
},
"image": "uniextra/movistar-webdav-proxy:latest",
"ports": [
"5000:5000",
"8080:8080"
],
"volumes": [
"./tokens:/app/tokens",
"./tmp:/tmp"
]
}
}
],
"top_level": {
"name": "movistar-webdav-proxy"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "movistar-webdav-proxy-volume-0",
"service": "movistar-webdav-proxy",
"container_path": "/app/tokens",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "movistar-webdav-proxy-volume-1",
"service": "movistar-webdav-proxy",
"container_path": "/tmp",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"movistar-webdav-proxy"
],
"stop_order": [
"movistar-webdav-proxy"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "tokens-encryption-key",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "movistar-webdav-proxy",
"environment_variable": "TOKENS_ENCRYPTION_KEY"
}
]
},
{
"id": "webdav-password",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "movistar-webdav-proxy",
"environment_variable": "WEBDAV_PASSWORD"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "Web dashboard",
"scheme": "http",
"port": 5000,
"path": "/",
"source": "upstream-documentation"
},
{
"label": "WebDAV",
"scheme": "http",
"port": 8080,
"path": "/",
"source": "native-container-port"
}
],
"credentials": [
{
"label": "Web dashboard and WebDAV",
"type": "configured-or-installer-generated",
"username": "admin",
"username_environment": "WEBDAV_USER",
"password": null,
"password_environment": "WEBDAV_PASSWORD",
"change_required": false,
"source": "installer-generated",
"retrieval": null
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 1,
"memory_mb": 512,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
},
{
"id": "disk-backed-upload-scratch",
"upstream_behavior": "Compose mounts /tmp as a tmpfs.",
"native_lxc_behavior": "A separate managed disk volume provides /tmp and is excluded from backups.",
"reason": "Uploads can reach 4096 MB; a disk-backed scratch volume avoids consuming the LXC RAM limit.",
"behavioral_impact": "Scratch data uses disk and can survive a restart; the application removes completed temporary uploads.",
"validation": "passed-in-lab"
},
{
"id": "native-rootfs-permissions",
"upstream_behavior": "Docker Compose requests read_only for the root filesystem.",
"native_lxc_behavior": "Proxmox uses a writable native root disk; /app is owned by root, while the upstream entrypoint drops to UID 10001. Tokens and upload scratch have separate writable volumes.",
"reason": "The Proxmox pre-start setup requires a writable root disk. Protect application code through root ownership instead of declaring unsupported read-only startup.",
"behavioral_impact": "This is not a fully read-only root filesystem; the application user cannot replace the root-owned application directory or binaries.",
"validation": "passed-in-lab"
}
],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/app",
"remove_lost_found": false,
"owner_strategy": "mapped-root",
"mode": "0755"
},
{
"container_path": "/app/tokens",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"mode": "0700"
},
{
"container_path": "/tmp",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"mode": "1777"
}
],
"volume_owner": {
"uid": 10001,
"gid": 10001
},
"generated_sensitive_environment": {
"WEBDAV_PASSWORD": {
"strategy": "token-hex",
"bytes": 16,
"prompt": true
},
"TOKENS_ENCRYPTION_KEY": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
}
},
"security": {
"options": {
"no_new_privileges": true
}
},
"startup_healthcheck": {
"scheme": "http",
"port": 5000,
"path": "/health",
"timeout_seconds": 90,
"request_timeout_seconds": 5,
"stability_seconds": 4,
"verify_tls": false
},
"completion_notes": [
"Open the web dashboard and link your Movistar/O2 account using its SMS flow.",
"WebDAV is available on container port 8080. Account linking is required before cloud file operations."
]
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "passed",
"service_health": "passed",
"restart_persistence": "passed",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+505
View File
@@ -0,0 +1,505 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-paperclip",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Paperclip"
},
"tagline": {
"en_US": "Manage teams of AI agents from a web dashboard."
},
"description": {
"en_US": "Official Paperclip image with its embedded PostgreSQL database, persistent agent workspaces and authenticated web interface."
},
"category": "ai",
"category_label": "AI / Coding & Dev-Tools",
"author": "Paperclip",
"developer": "Paperclip",
"icon": "https://raw.githubusercontent.com/paperclipai/paperclip/master/ui/public/favicon.svg",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 3100,
"path": "/"
},
"website": "https://paperclip.ing",
"documentation": "https://github.com/paperclipai/paperclip/blob/master/doc/DOCKER.md",
"repository": "https://github.com/paperclipai/paperclip",
"tips": [
"Create an account and claim the instance from the first-run setup screen.",
"Configure provider credentials or external agents after installation; no API key is required to start the dashboard.",
"For HTTPS access, set PAPERCLIP_PUBLIC_URL to the canonical URL in Advanced settings.",
"Restore with the original network identity, or update PAPERCLIP_PUBLIC_URL in Modify when the address or hostname changes."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "official",
"repository": "https://github.com/paperclipai/paperclip",
"revision": "1b4c803816e82b0265c8422e1a804327a7ed8c54",
"image_repository_url": "https://github.com/paperclipai/paperclip/pkgs/container/paperclip",
"readme_pushed_at": "",
"compose_sha256": "53a71e7d1c6a47fb25ad68d5570140c525df30fcecf33a00cf84bd2b65bd15f4",
"generated_at": "2026-11-02T18:43:18+00:00",
"readme_raw_url": "https://github.com/paperclipai/paperclip/blob/master/doc/DOCKER.md"
},
"container_contract": {
"service_name": "paperclip",
"container_name": "paperclip",
"image": {
"reference": "ghcr.io/paperclipai/paperclip:latest",
"registry": "ghcr.io",
"repository": "ghcr.io/paperclipai/paperclip",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "HOST",
"example": "0.0.0.0",
"required": true,
"sensitive": false,
"source": "docker-compose",
"prompt_user": false
},
{
"name": "PAPERCLIP_HOME",
"example": "/paperclip",
"required": true,
"sensitive": false,
"source": "docker-compose",
"prompt_user": false
},
{
"name": "PAPERCLIP_DEPLOYMENT_MODE",
"example": "authenticated",
"required": true,
"sensitive": false,
"source": "docker-compose",
"prompt_user": false
},
{
"name": "PAPERCLIP_DEPLOYMENT_EXPOSURE",
"example": "private",
"required": true,
"sensitive": false,
"source": "docker-compose",
"prompt_user": false
},
{
"name": "PAPERCLIP_PUBLIC_URL",
"example": "http://localhost:3100",
"required": true,
"sensitive": false,
"source": "docker-compose",
"container_address": "http://@CONTAINER_ADDRESS@:3100"
},
{
"name": "BETTER_AUTH_SECRET",
"example": "${GENERATED_BETTER_AUTH_SECRET}",
"required": true,
"sensitive": true,
"source": "docker-compose"
},
{
"name": "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET",
"example": "${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}",
"required": true,
"sensitive": true,
"source": "docker-compose"
},
{
"name": "OPENAI_API_KEY",
"example": "",
"required": false,
"sensitive": true,
"source": "official-documentation"
},
{
"name": "ANTHROPIC_API_KEY",
"example": "",
"required": false,
"sensitive": true,
"source": "official-documentation"
},
{
"name": "GEMINI_API_KEY",
"example": "",
"required": false,
"sensitive": true,
"source": "official-documentation"
},
{
"name": "OPENROUTER_API_KEY",
"example": "",
"required": false,
"sensitive": true,
"source": "official-documentation"
},
{
"name": "PAPERCLIP_ALLOWED_HOSTNAMES",
"example": "",
"required": false,
"sensitive": false,
"source": "official-documentation"
},
{
"name": "PAPERCLIP_MIGRATION_AUTO_APPLY",
"example": "true",
"required": true,
"sensitive": false,
"prompt_user": false,
"source": "official-server-startup"
}
],
"volumes": [
{
"id": "volume-0",
"container_path": "/paperclip",
"compose_source_example": "paperclip-data",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
}
],
"ports": [
{
"container_port": 3100,
"published_example": 3100,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": "90s",
"original_compose": "name: paperclip\nservices:\n paperclip:\n image: ghcr.io/paperclipai/paperclip:latest\n restart: unless-stopped\n stop_grace_period: 90s\n ports:\n - 3100:3100\n environment:\n HOST: 0.0.0.0\n PAPERCLIP_HOME: /paperclip\n PAPERCLIP_MIGRATION_AUTO_APPLY: \"true\"\n PAPERCLIP_DEPLOYMENT_MODE: authenticated\n PAPERCLIP_DEPLOYMENT_EXPOSURE: private\n PAPERCLIP_PUBLIC_URL: http://localhost:3100\n BETTER_AUTH_SECRET: ${GENERATED_BETTER_AUTH_SECRET}\n PAPERCLIP_TOOL_ACTION_SIGNING_SECRET: ${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}\n volumes:\n - paperclip-data:/paperclip\nvolumes:\n paperclip-data: {}\n"
},
"compose_stack": {
"project_name": "paperclip",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "paperclip",
"service_count": 1,
"services": [
{
"name": "paperclip",
"image": "ghcr.io/paperclipai/paperclip:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "ghcr.io/paperclipai/paperclip:latest",
"restart": "unless-stopped",
"stop_grace_period": "90s",
"ports": [
"3100:3100"
],
"environment": {
"HOST": "0.0.0.0",
"PAPERCLIP_HOME": "/paperclip",
"PAPERCLIP_DEPLOYMENT_MODE": "authenticated",
"PAPERCLIP_DEPLOYMENT_EXPOSURE": "private",
"PAPERCLIP_PUBLIC_URL": "http://localhost:3100",
"BETTER_AUTH_SECRET": "${GENERATED_BETTER_AUTH_SECRET}",
"PAPERCLIP_TOOL_ACTION_SIGNING_SECRET": "${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}",
"PAPERCLIP_MIGRATION_AUTO_APPLY": "true"
},
"volumes": [
"paperclip-data:/paperclip"
]
}
}
],
"top_level": {
"name": "paperclip",
"volumes": {
"paperclip-data": {}
}
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "paperclip-volume-0",
"service": "paperclip",
"container_path": "/paperclip",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"paperclip"
],
"stop_order": [
"paperclip"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "better-auth-secret",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "paperclip",
"environment_variable": "BETTER_AUTH_SECRET"
}
]
},
{
"id": "paperclip-tool-action-signing-secret",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "paperclip",
"environment_variable": "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "http",
"port": 3100,
"path": "/",
"source": "compose-metadata"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 4096,
"swap_mb": 512,
"rootfs_size_gb": 32,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 90
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "official-embedded-postgresql-image",
"upstream_behavior": "The official image starts Paperclip and its embedded PostgreSQL database.",
"native_lxc_behavior": "Import the original Entrypoint, Cmd and WorkingDir into one unprivileged LXC.",
"reason": "Keep the developer image without Docker Engine or a custom image build.",
"behavioral_impact": "Provider credentials are configured separately after the first account is created.",
"validation": "passed-amd64-web-login-and-api-data"
},
{
"id": "persistent-application-home",
"upstream_behavior": "The root entrypoint prepares /paperclip and then switches to the node user.",
"native_lxc_behavior": "Prepare the volume for mapped root and let the official entrypoint set application ownership.",
"reason": "Preserve the embedded database, uploads, workspaces and local secrets across image replacement and restore.",
"behavioral_impact": "Managed volumes are backed up; host directories remain outside the LXC backup.",
"validation": "passed-managed-volume-host-bind-restart-and-restore"
},
{
"id": "noninteractive-database-migrations",
"upstream_behavior": "Existing databases with pending migrations trigger an interactive confirmation during startup.",
"native_lxc_behavior": "Set the upstream PAPERCLIP_MIGRATION_AUTO_APPLY=true option.",
"reason": "An OCI update must finish without waiting for input at a migration prompt.",
"behavioral_impact": "Paperclip applies its schema migrations when starting an updated image; the native update backup protects the previous installation.",
"validation": "passed-real-upgrade-2026.1012.0-to-2026.1023.0"
},
{
"id": "authenticated-instance-address",
"upstream_behavior": "Paperclip uses its canonical public URL for authentication origins and hostname checks.",
"native_lxc_behavior": "Use the installer container-address placeholder by default and allow a canonical URL in Advanced settings.",
"reason": "Avoid the upstream localhost URL on an LXC with its own address.",
"behavioral_impact": "When restoring under another address, change PAPERCLIP_PUBLIC_URL through Modify. Restoring the original network identity retains the URL.",
"validation": "passed-direct-ip-authenticated-setup-and-original-network-restore"
},
{
"id": "independent-signing-secrets",
"upstream_behavior": "Session signing and approval-gated tool actions use independent secrets.",
"native_lxc_behavior": "Generate two separate 32-byte hexadecimal secrets and keep their values sensitive.",
"reason": "Do not ship a shared password or regenerate signing keys during an update.",
"behavioral_impact": "The first administrator creates an account in the web interface. Provider API keys are optional and sensitive.",
"validation": "passed-first-admin-claim-and-update-account-persistence"
}
],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/paperclip",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
}
],
"generated_sensitive_environment": {
"BETTER_AUTH_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"PAPERCLIP_TOOL_ACTION_SIGNING_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
}
},
"startup_healthcheck": {
"scheme": "http",
"port": 3100,
"path": "/api/health",
"timeout_seconds": 300,
"request_timeout_seconds": 10,
"stability_seconds": 5,
"verify_tls": true
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
},
"validation": {
"schema": "passed",
"clean_install": "passed-default-resource-profile-and-advanced-settings-amd64",
"service_health": "passed-http-api-health-browser-login-and-first-admin-claim",
"restart_persistence": "passed-host-bind-reboot-and-managed-volume-restore",
"backup_restore": "passed-different-vmid-oci-recovery-with-original-network-identity",
"update_preserves_data": "passed-2026.1012.0-to-2026.1023.0-with-automatic-schema-migrations",
"rollback": "passed-explicit-native-Recover-after-failed-image-not-claimed-automatic",
"modification": "passed-native-cpu-and-ram-change-without-image-download-or-recreation",
"removal": "passed-guests-disks-records-and-test-backups-cleaned-host-data-preserved-by-Remove",
"browser_ui": "passed-account-login-and-company-dashboard",
"runtime_architecture": "amd64-tested-arm64-manifest-only",
"provider_agent_runs": "not-tested-no-real-provider-credentials-used",
"oci_engine_tests": "1158-run-4-skipped",
"offline_i18n_tests": "626-passed"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-pdfcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "PdfCraft",
"es_ES": "PdfCraft"
},
"tagline": {
"en_US": "Read and edit PDF documents in your browser",
"es_ES": "Lectura y edición de documentos PDF en el navegador"
},
"description": {
"en_US": "PdfCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "PdfCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/pdfcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/pdfcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/pdfcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/pdfcraft",
"readme_pushed_at": "",
"compose_sha256": "4416cf187df8cccbc11fc14af6e4d5155cd386871f9514ae1ca10968a8b4a372",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/pdfcraft.yaml"
},
"container_contract": {
"service_name": "pdfcraft",
"container_name": "pdfcraft",
"image": {
"reference": "docker.io/junkerderprovinz/pdfcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/pdfcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n pdfcraft:\n image: junkerderprovinz/pdfcraft:latest\n container_name: pdfcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "pdfcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "pdfcraft",
"service_count": 1,
"services": [
{
"name": "pdfcraft",
"image": "junkerderprovinz/pdfcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/pdfcraft:latest",
"container_name": "pdfcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "pdfcraft-volume-0",
"service": "pdfcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "pdfcraft-volume-1",
"service": "pdfcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"pdfcraft"
],
"stop_order": [
"pdfcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-photocraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "PhotoCraft",
"es_ES": "PhotoCraft"
},
"tagline": {
"en_US": "Photo editing in your browser",
"es_ES": "Edición de fotos en el navegador"
},
"description": {
"en_US": "PhotoCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "PhotoCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/photocraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/photocraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/photocraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/photocraft",
"readme_pushed_at": "",
"compose_sha256": "459ac4e3adbd7544f3d0acb2f34230e8a396566ff910288898f689d54a78e722",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/photocraft.yaml"
},
"container_contract": {
"service_name": "photocraft",
"container_name": "photocraft",
"image": {
"reference": "docker.io/junkerderprovinz/photocraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/photocraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n photocraft:\n image: junkerderprovinz/photocraft:latest\n container_name: photocraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "photocraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "photocraft",
"service_count": 1,
"services": [
{
"name": "photocraft",
"image": "junkerderprovinz/photocraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/photocraft:latest",
"container_name": "photocraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "photocraft-volume-0",
"service": "photocraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "photocraft-volume-1",
"service": "photocraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"photocraft"
],
"stop_order": [
"photocraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+4 -1
View File
@@ -329,7 +329,10 @@
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"non_persistent_image_volumes": [
"/tmp/jetty"
]
}
},
"compatibility": {
+35 -1
View File
@@ -85,6 +85,22 @@
"backup": true,
"default_size_gb": 8
}
},
{
"id": "volume-1",
"container_path": "/etc/searxng",
"compose_source_example": "./config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
@@ -127,7 +143,8 @@
"8080:8080"
],
"volumes": [
"./cache:/var/cache/searxng"
"./cache:/var/cache/searxng",
"./config:/etc/searxng"
]
}
}
@@ -153,6 +170,17 @@
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "searxng-volume-1",
"service": "searxng",
"container_path": "/etc/searxng",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
@@ -378,6 +406,12 @@
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/etc/searxng",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-soundcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "SoundCraft",
"es_ES": "SoundCraft"
},
"tagline": {
"en_US": "Audio recording and mixing in your browser",
"es_ES": "Grabación y mezcla de audio en el navegador"
},
"description": {
"en_US": "SoundCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "SoundCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/soundcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/soundcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/soundcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/soundcraft",
"readme_pushed_at": "",
"compose_sha256": "8fef65b5330dd21035acbd8bc587c597610e6db5fdf8a70a07b54dcab25b3695",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/soundcraft.yaml"
},
"container_contract": {
"service_name": "soundcraft",
"container_name": "soundcraft",
"image": {
"reference": "docker.io/junkerderprovinz/soundcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/soundcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n soundcraft:\n image: junkerderprovinz/soundcraft:latest\n container_name: soundcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "soundcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "soundcraft",
"service_count": 1,
"services": [
{
"name": "soundcraft",
"image": "junkerderprovinz/soundcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/soundcraft:latest",
"container_name": "soundcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "soundcraft-volume-0",
"service": "soundcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "soundcraft-volume-1",
"service": "soundcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"soundcraft"
],
"stop_order": [
"soundcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+477
View File
@@ -0,0 +1,477 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-spoolman",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Spoolman"
},
"tagline": {
"en_US": "Track 3D printer filament spools and usage."
},
"description": {
"en_US": "A self-hosted filament inventory for 3D printers. Manage spools, materials, manufacturers, locations and labels in the web UI, and integrate with Moonraker, OctoPrint and other printer tools. The official image uses SQLite by default; no separate database container is required."
},
"category": "tools",
"category_label": "Tools",
"author": "Donkie",
"developer": "Donkie",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/spoolman.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 8000,
"path": "/"
},
"website": "https://github.com/Donkie/Spoolman",
"documentation": "https://github.com/Donkie/Spoolman/wiki/Installation",
"repository": "https://github.com/Donkie/Spoolman",
"tips": [
"Spoolman has no built-in authentication. Keep it on a trusted network; do not expose it directly to the internet.",
"The official image uses SQLite by default and stores the database, automatic backups, logs and cache in the persistent data directory."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "Donkie",
"repository": "https://github.com/Donkie/Spoolman",
"revision": "ff8efd517b76a4b2783f29c89e9b9fbcd8cd167b",
"image_repository_url": "https://github.com/Donkie/Spoolman/pkgs/container/spoolman",
"readme_pushed_at": "2026-10-31T09:39:19Z",
"compose_sha256": "d9b115c4c37589f9813e54f926fdd22e7a10a44a6e56160f837b1247638fac83",
"generated_at": "2026-11-02T20:02:46+00:00",
"default_branch": "master",
"readme_raw_url": "https://github.com/Donkie/Spoolman/wiki/Installation"
},
"container_contract": {
"service_name": "spoolman",
"container_name": "spoolman",
"image": {
"reference": "ghcr.io/donkie/spoolman:latest",
"registry": "ghcr.io",
"repository": "ghcr.io/donkie/spoolman",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-image-default",
"prompt_user": false
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-image-default",
"prompt_user": false
},
{
"name": "TZ",
"example": "Etc/UTC",
"required": true,
"sensitive": false,
"source": "upstream-compose",
"prompt_user": false
}
],
"volumes": [
{
"id": "volume-0",
"container_path": "/home/app/.local/share/spoolman",
"compose_source_example": "./data",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
}
],
"ports": [
{
"container_port": 8000,
"published_example": 7912,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n spoolman:\n image: ghcr.io/donkie/spoolman:latest\n container_name: spoolman\n restart: unless-stopped\n ports:\n - \"7912:8000/tcp\"\n volumes:\n - ./data:/home/app/.local/share/spoolman\n environment:\n PUID: \"1000\"\n PGID: \"1000\"\n TZ: Etc/UTC\n"
},
"compose_stack": {
"project_name": "spoolman",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "spoolman",
"service_count": 1,
"services": [
{
"name": "spoolman",
"image": "ghcr.io/donkie/spoolman:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "ghcr.io/donkie/spoolman:latest",
"container_name": "spoolman",
"restart": "unless-stopped",
"ports": [
"7912:8000/tcp"
],
"volumes": [
"./data:/home/app/.local/share/spoolman"
],
"environment": {
"PUID": "1000",
"PGID": "1000",
"TZ": "Etc/UTC"
}
}
}
],
"top_level": {
"name": "spoolman"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "spoolman-volume-0",
"service": "spoolman",
"container_path": "/home/app/.local/share/spoolman",
"mode": "managed-volume",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"spoolman"
],
"stop_order": [
"spoolman"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Spoolman web interface",
"scheme": "http",
"port": 8000,
"path": "/",
"source": "upstream-image"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
],
"installer_profile": {
"startup_healthcheck": {
"scheme": "http",
"port": 8000,
"path": "/",
"timeout_seconds": 180,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
},
"volume_preparations": [
{
"container_path": "/home/app/.local/share/spoolman",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"volume_owner": {
"uid": 1000,
"gid": 1000
}
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "passed-default-official-image-skopeo-and-first-start-http",
"advanced_install": "pending-custom-install-summary-validation",
"service_health": "passed-web-api-crud",
"restart_persistence": "passed-managed-and-host-bind-database-and-records",
"backup_restore": "passed-pbs-backup-and-manager-recover-record-preserved",
"update_preserves_data": "no-update-available-at-check",
"modification": "passed-cpu-ram-up-and-down-without-image-pull-or-recreate",
"volumes": "passed-managed-storage-and-host-bind-crud-owner-and-data-check",
"removal": "passed-manager-removal-host-path-retained-then-temporary-data-cleaned"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+47 -3
View File
@@ -60,7 +60,24 @@
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [],
"volumes": [],
"volumes": [
{
"id": "volume-0",
"container_path": "/var/lib/tor",
"compose_source_example": "./tor-data",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
{
"container_port": 9050,
@@ -103,6 +120,9 @@
"ports": [
"9050:9050",
"8118:8118"
],
"volumes": [
"./tor-data:/var/lib/tor"
]
}
}
@@ -119,7 +139,19 @@
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [],
"storage": [
{
"id": "tor-volume-0",
"service": "tor",
"container_path": "/var/lib/tor",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
@@ -323,7 +355,19 @@
"SOCKS5 proxy: configure your application with the LXC IP address shown above and port 9050.",
"HTTP CONNECT proxy: use the same IP address and port 8118. These addresses are proxy settings, not web links.",
"Only applications configured to use this proxy send their traffic through Tor."
]
],
"volume_preparations": [
{
"container_path": "/var/lib/tor",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"volume_owner": {
"uid": 101,
"gid": 102
}
}
},
"compatibility": {
+292
View File
@@ -0,0 +1,292 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-unbound",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Unbound"
},
"tagline": {
"en_US": "A validating, recursive DNS resolver for your private network."
},
"description": {
"en_US": "Run the community-maintained klutchell image of Unbound as a DNS resolver on its own Proxmox LXC. It listens on TCP and UDP port 53 and can load optional custom configuration files."
},
"category": "adblock",
"category_label": "Adblock & DNS",
"author": "Kyle Harding",
"developer": "Kyle Harding (klutchell)",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/unbound.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64",
"armhf"
],
"launch": {
"scheme": "http",
"port": null,
"path": "/"
},
"website": "https://unbound.net/",
"documentation": "https://github.com/klutchell/unbound-docker#readme",
"repository": "https://github.com/klutchell/unbound-docker",
"tips": [
"Unbound has no web interface. Use the LXC IP as a DNS server on TCP and UDP port 53.",
"The default image config listens on all interfaces and accepts clients from private IPv4 ranges. Keep it behind your trusted LAN firewall; do not expose recursive DNS publicly.",
"The original GitHub repository has moved to klutchell/unbound-docker; the published Docker Hub image remains klutchell/unbound:main. The image is an unofficial community image, not published by NLnet Labs.",
"Optional custom .conf files go under /etc/unbound/custom.conf.d and must be readable by UID/GID 101:102 or world-readable."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "klutchell",
"repository": "https://github.com/klutchell/unbound-docker",
"revision": "1efbea960bf9462b6fb6dd71aa702ad32d6820d7",
"default_branch": "main",
"image_repository_url": "https://hub.docker.com/r/klutchell/unbound",
"readme_pushed_at": "2026-11-02T14:31:22Z",
"compose_sha256": "faf73a93c1f7d4d43f1eb61ba2e62a4418bd501f0c827b080ea9897964e75848",
"generated_at": "2026-11-02T21:21:54+00:00",
"readme_raw_url": "https://raw.githubusercontent.com/klutchell/unbound-docker/main/README.md"
},
"container_contract": {
"service_name": "unbound",
"container_name": "unbound",
"image": {
"reference": "klutchell/unbound:main",
"registry": "docker.io",
"repository": "klutchell/unbound",
"tag": "main",
"digest": null,
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
},
"environment": [],
"volumes": [
{
"id": "volume-0",
"container_path": "/etc/unbound/custom.conf.d",
"compose_source_example": "./config",
"read_only": false,
"required": false,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "host-bind",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
{
"container_port": 53,
"published_example": 53,
"protocol": "udp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 53,
"published_example": 53,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "name: unbound\nservices:\n unbound:\n image: klutchell/unbound:main\n container_name: unbound\n restart: unless-stopped\n ports:\n - 53:53/udp\n - 53:53/tcp\n volumes:\n - ./config:/etc/unbound/custom.conf.d\n"
},
"compose_stack": {
"project_name": "unbound",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "unbound",
"service_count": 1,
"services": [
{
"name": "unbound",
"image": "klutchell/unbound:main",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "klutchell/unbound:main",
"container_name": "unbound",
"restart": "unless-stopped",
"ports": [
"53:53/udp",
"53:53/tcp"
],
"volumes": [
"./config:/etc/unbound/custom.conf.d"
]
}
}
],
"top_level": {
"name": "unbound"
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "unbound-volume-0",
"service": "unbound",
"container_path": "/etc/unbound/custom.conf.d",
"mode": "user-selectable",
"user_selectable": true,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": "Host directory containing optional custom Unbound .conf files",
"default": "host-bind",
"installation_choice": [
"managed-volume",
"host-bind"
]
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"unbound"
],
"stop_order": [
"unbound"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
]
}
},
"first_run": {
"endpoints": [],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 512,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 120
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"adaptations": [],
"installer_profile": {
"volume_preparations": [
{
"container_path": "/etc/unbound/custom.conf.d",
"owner_strategy": "mapped-root",
"remove_lost_found": true,
"only_when_mount_type": "managed-volume"
}
],
"startup_healthcheck": {
"type": "running",
"timeout_seconds": 90,
"stability_seconds": 20
}
},
"catalog": {
"replaces_discovered_ids": []
}
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"container_name",
"image",
"ports",
"restart",
"volumes"
],
"untranslated_blockers": [],
"policy": "This single-image Compose contract maps to one unprivileged Proxmox LXC. The optional custom-config directory can use a Proxmox-managed volume or a host directory; the image defaults work with an empty directory."
},
"validation": {
"schema": "passed-at-generation",
"image_resolution": "passed-skopeo-16-layers",
"clean_install": "passed-default-install-and-first-start-healthcheck",
"advanced_install": "pending",
"service_health": "passed-recursion-and-custom-local-data-over-udp-and-tcp",
"restart_persistence": "passed-custom-zone-after-pct-reboot",
"backup_restore": "pending",
"update_preserves_data": "pending-update-check-not-run",
"modification": "pending-manager-ui-unresponsive-no-changes-applied",
"managed_volume": "passed-config-volume-1g",
"host_bind": "pending",
"removal": "passed-manager-remove-ct-disks-and-record-cleaned"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+4 -1
View File
@@ -323,7 +323,10 @@
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"non_persistent_image_volumes": [
"/var/log"
]
},
"adaptations": [
{
+564
View File
@@ -0,0 +1,564 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-vectorcraft",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "VectorCraft",
"es_ES": "VectorCraft"
},
"tagline": {
"en_US": "Vector illustration in your browser",
"es_ES": "Ilustración vectorial en el navegador"
},
"description": {
"en_US": "VectorCraft from the ArtCraft project, streamed from a native Linux application using the community-maintained junkerderprovinz image. Files are stored on the server, not in browser storage.",
"es_ES": "VectorCraft del proyecto ArtCraft, con su aplicación nativa de Linux transmitida al navegador mediante la imagen comunitaria de junkerderprovinz. Los documentos se guardan en el servidor, no en el almacenamiento del navegador."
},
"category": "creative",
"category_label": "Creative & Design",
"author": "junkerderprovinz",
"developer": "ArtCraft",
"icon": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/.github/assets/icons/vectorcraft.png",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "https",
"port": 3001,
"path": "/"
},
"website": "https://getartcraft.com/apps/vectorcraft",
"documentation": "https://github.com/junkerderprovinz/artcraft-apps",
"repository": "https://github.com/storytold/vectorcraft",
"tips": [
"This is the native Linux application streamed by Selkies, not the WebAssembly build. Processing and documents stay in the LXC and its mounted directories.",
"The image is maintained by junkerderprovinz; ArtCraft publishes the application packages. It is not an official ArtCraft container image.",
"Use a trusted HTTPS reverse proxy for browser access. Port 3001 uses the upstream self-signed certificate; port 3000 is for an HTTP reverse-proxy backend.",
"The upstream default has no login. Optional CUSTOM_USER and PASSWORD variables enable HTTP basic authentication; do not expose an unauthenticated desktop to untrusted networks.",
"/config holds settings and desktop state and is included in Proxmox backups. /storage holds documents and supports a managed volume or an explicitly selected host directory; host directories require separate backups.",
"The default uses software rendering. GPU acceleration and other CPU architectures are not claimed tested by a CPU-only amd64 installation.",
"Without an assigned GPU, an application may ask to switch to CPU rendering. Choose the CPU option; hardware acceleration is not required for the default configuration."
],
"mini_changelog": [],
"display_version": null,
"updated_at": null
},
"source": {
"provider": "junkerderprovinz",
"repository": "https://github.com/junkerderprovinz/artcraft-apps",
"revision": "32bee0dea9bdaf5310c693210bea0d732a129ae8",
"image_repository_url": "https://hub.docker.com/r/junkerderprovinz/vectorcraft",
"readme_pushed_at": "",
"compose_sha256": "a62cf232ee367ccb49096aec28637b0e9b78fce44b52574a57fe05e918468a14",
"generated_at": "2026-11-03T12:57:29+00:00",
"default_branch": "main",
"readme_raw_url": "https://raw.githubusercontent.com/junkerderprovinz/artcraft-apps/32bee0dea9bdaf5310c693210bea0d732a129ae8/compose/vectorcraft.yaml"
},
"container_contract": {
"service_name": "vectorcraft",
"container_name": "vectorcraft",
"image": {
"reference": "docker.io/junkerderprovinz/vectorcraft:latest",
"registry": "docker.io",
"repository": "junkerderprovinz/vectorcraft",
"tag": "latest",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "TZ",
"example": "Europe/Vienna",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PUID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "PGID",
"example": "1000",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "UMASK",
"example": "022",
"required": true,
"sensitive": false,
"source": "upstream-compose"
},
{
"name": "CUSTOM_USER",
"example": "",
"required": false,
"sensitive": false,
"source": "upstream-documentation"
},
{
"name": "PASSWORD",
"example": "",
"required": false,
"sensitive": true,
"source": "upstream-documentation"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./appdata",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 8
}
},
{
"id": "storage",
"container_path": "/storage",
"compose_source_example": "./storage",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 16
}
}
],
"ports": [
{
"container_port": 3001,
"published_example": 3001,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 3000,
"published_example": 3000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n vectorcraft:\n image: junkerderprovinz/vectorcraft:latest\n container_name: vectorcraft\n restart: unless-stopped\n shm_size: 1gb\n ports:\n - 3001:3001\n - 3000:3000\n volumes:\n - ./appdata:/config\n - ./storage:/storage\n environment:\n TZ: Europe/Vienna\n PUID: '1000'\n PGID: '1000'\n UMASK: '022'\n"
},
"compose_stack": {
"project_name": "vectorcraft",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "vectorcraft",
"service_count": 1,
"services": [
{
"name": "vectorcraft",
"image": "junkerderprovinz/vectorcraft:latest",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [],
"frontend_network": true,
"private_network": false,
"compose": {
"image": "junkerderprovinz/vectorcraft:latest",
"container_name": "vectorcraft",
"restart": "unless-stopped",
"shm_size": "1gb",
"ports": [
"3001:3001",
"3000:3000"
],
"volumes": [
"./appdata:/config",
"./storage:/storage"
],
"environment": {
"TZ": "Europe/Vienna",
"PUID": "1000",
"PGID": "1000",
"UMASK": "022"
}
}
}
],
"top_level": {},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": false,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "vectorcraft-volume-0",
"service": "vectorcraft",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "vectorcraft-volume-1",
"service": "vectorcraft",
"container_path": "/storage",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
"vectorcraft"
],
"stop_order": [
"vectorcraft"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": []
}
},
"first_run": {
"endpoints": [
{
"label": "Web UI",
"scheme": "https",
"port": 3001,
"path": "/",
"source": "https://github.com/junkerderprovinz/artcraft-apps"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 2048,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"tmpfs_mounts": [
{
"id": "compose-shm",
"container_path": "/dev/shm",
"default_size_mb": 1024,
"minimum_size_mb": 1,
"size_prompt": "Size of the /dev/shm shared memory in MB",
"mount_options": [
"rw",
"nosuid",
"nodev"
]
},
{
"id": "nginx-runtime",
"container_path": "/run/nginx",
"default_size_mb": 1,
"minimum_size_mb": 1,
"prompt_size": false,
"mount_options": [
"rw",
"nosuid",
"nodev",
"mode=0755"
]
}
],
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-root",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/storage",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 3000,
"path": "/",
"timeout_seconds": 240,
"request_timeout_seconds": 5,
"stability_seconds": 8,
"accept_any_status": true,
"verify_tls": true
}
},
"adaptations": [
{
"id": "imported-compose-source",
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
"reason": "Catalog import must not imply runtime compatibility.",
"behavioral_impact": "No automatic installation before review.",
"validation": "pending-per-application"
},
{
"id": "rolling-latest-image",
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
"validation": "pending-per-application"
},
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
"validation": "pending-per-application"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-privileged-mode",
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
"validation": "native-equivalent"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "Community native-desktop image contract reviewed against its published Compose and Dockerfile. Linux amd64 and arm64 manifests exist; runtime, storage and lifecycle tests remain pending per architecture."
},
"validation": {
"schema": "passed-at-generation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+47 -3
View File
@@ -77,7 +77,24 @@
"source": "upstream-documentation"
}
],
"volumes": [],
"volumes": [
{
"id": "volume-0",
"container_path": "/config",
"compose_source_example": "./config",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume",
"host-bind"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 1
}
}
],
"ports": [
{
"container_port": 5000,
@@ -117,7 +134,10 @@
"environment": {
"WHOOGLE_USER": "admin",
"WHOOGLE_PASS": "${GENERATED_WHOOGLE_PASS}"
}
},
"volumes": [
"./config:/config"
]
}
}
],
@@ -133,7 +153,19 @@
"dependency_external_access": "disabled-unless-service-publishes-ports",
"prompt_user_for_private_network": false
},
"storage": [],
"storage": [
{
"id": "whoogle-volume-0",
"service": "whoogle",
"container_path": "/config",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
}
],
"orchestration": {
"reserve_vmids_atomically": 1,
"start_order": [
@@ -378,6 +410,18 @@
"bytes": 24,
"prompt": false
}
},
"volume_preparations": [
{
"container_path": "/config",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
],
"volume_owner": {
"uid": 927,
"gid": 927
}
},
"catalog": {

Some files were not shown because too many files have changed in this diff Show More