mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 10:52:22 +00:00
Merge remote-tracking branch 'origin/develop' into HEAD
# Conflicts: # web/messages/es/docs/hardware/switch-gpu-mode.json
This commit is contained in:
@@ -28,7 +28,12 @@
|
||||
"switcher": "Language",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"sk": "Slovenčina"
|
||||
"sk": "Slovenčina",
|
||||
"de": "Deutsch",
|
||||
"fr": "Français",
|
||||
"it": "Italiano",
|
||||
"pt": "Português",
|
||||
"sv": "Svenska"
|
||||
},
|
||||
"resources": {
|
||||
"documentation": {
|
||||
|
||||
@@ -8,5 +8,6 @@
|
||||
"errors": {
|
||||
"notFound": "Error: CODE_OF_CONDUCT.md file not found.",
|
||||
"loadFailed": "Error: Unable to load the Code of Conduct content."
|
||||
}
|
||||
},
|
||||
"contentMarkdown": "# 📝 Code of Conduct & Best Practices\n\nThis document defines the **principles and guidelines** for the use of **ProxMenux**, aiming to foster **respect, collaboration, and security** in development.\n\n## 📌 1. Code Attribution & Recognition\n\n- If **scripts, code snippets, or ideas** from other repositories or developers are used, the original author will always be credited. \n- A comment will be added in the code or documentation mentioning the source and linking to the original repository if possible. \n- When using code with a specific **license**, its terms must be respected. \n\n### ✅ Example of proper attribution in code:\n\n```bash\n# Script based on the work of [Author] at [Repository Link]\n```\n\n## 🔒 2. Security & Code Responsibility\n\n- All code in this repository follows secure development best practices.\n- Contributions introducing intentional vulnerabilities or unsafe practices are not allowed.\n- Scripts should never compromise system security or user data.\n- Before implementation, contributions should be reviewed to ensure security and stability.\n\n### ⚠️ Responsible Disclosure of Vulnerabilities\n\nIf you discover a security vulnerability, DO NOT report it in public Issues or forums.\n\nInstead, please report it privately via email:\n\n📧 proxmenux@macrimi.pro\n\nFor detailed information on security vulnerabilities and how to report them, please refer to our [Security Policy](./SECURITY.md).\n\n## 🤝 3. Community Guidelines\n\nTo maintain a respectful and professional environment, all users must follow these guidelines:\n\n- ✅ Be respectful and constructive in discussions.\n- ❌ No harassment, hate speech, or offensive behavior will be tolerated.\n- ✅ Provide feedback professionally, avoiding personal attacks.\n- ❌ Violating these guidelines may result in warnings or bans, depending on severity.\n\n\n##\n\nWith this document, we promote ethical code use, security awareness, and a respectful community.\n\n📢 Let's build something great, together!\n\n"
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
},
|
||||
"q4": {
|
||||
"question": "Can I customise ProxMenux?",
|
||||
"p1Rich": "The core scripts can't be modified directly because they're hosted on GitHub and refreshed by the auto-update flow. What you <em>can</em> customise:",
|
||||
"p1Rich": "Local changes to the core scripts can be overwritten by the update flow, so avoid editing those files directly. What you <em>can</em> customise:",
|
||||
"items": [
|
||||
"The console banner via the <strong>FastFetch</strong> tool in the Post-Install options.",
|
||||
"Which optional components are installed (Monitor, Fail2Ban, Lynis…) — pick during install or via the relevant menu later."
|
||||
@@ -63,15 +63,15 @@
|
||||
},
|
||||
"q7": {
|
||||
"question": "Can I contribute to ProxMenux?",
|
||||
"p1Rich": "<strong>Absolutely.</strong> ProxMenux is open source and collaborative. Contributions can be code (bash, Next.js / TypeScript, the translation Python venv), testing, documentation, design, or just ideas.",
|
||||
"p1Rich": "<strong>Absolutely.</strong> ProxMenux is open source and collaborative. Contributions can be code (Bash, Next.js/TypeScript and Python translation tools), testing, documentation, design, or just ideas.",
|
||||
"item1Rich": "Discuss ideas in <discusslink>GitHub Discussions</discusslink> before opening a feature request.",
|
||||
"item2Rich": "For PRs, read the <coclink>Code of Conduct & Best Practices</coclink> first.",
|
||||
"item3Rich": "See the <contriblink>Contributors page</contriblink> for current testers and reviewers."
|
||||
},
|
||||
"q8": {
|
||||
"question": "Does ProxMenux modify critical system files?",
|
||||
"p1Rich": "<strong>No.</strong> ProxMenux installs:",
|
||||
"item1Rich": "Dependencies via apt: <code>dialog</code>, <code>curl</code>, <code>jq</code>, <code>git</code> (and <code>python3</code> + <code>googletrans</code> on the Translation install).",
|
||||
"p1Rich": "<strong>Installing ProxMenux adds the following components.</strong>",
|
||||
"item1Rich": "Dependencies via apt: <code>dialog</code>, <code>curl</code>, <code>jq</code> and <code>git</code>. Translations use pre-built JSON catalogs; the installer does not add a translation virtualenv to the host.",
|
||||
"item2Rich": "The script tree at <code>/usr/local/share/proxmenux/</code>.",
|
||||
"item3Rich": "The launcher at <code>/usr/local/bin/menu</code>.",
|
||||
"item4Rich": "Optional: the Monitor systemd service at <code>proxmenux-monitor.service</code>.",
|
||||
@@ -83,12 +83,12 @@
|
||||
},
|
||||
"q10": {
|
||||
"question": "How do I uninstall ProxMenux?",
|
||||
"p1Rich": "From inside ProxMenux: <strong>Settings → Uninstall ProxMenux</strong>. The uninstaller removes the script tree, the launcher and the Monitor service, optionally removes selected dependencies, and restores <code>/root/.bashrc</code> and <code>/etc/motd</code> backups taken at install time.",
|
||||
"p1Rich": "From inside ProxMenux: <strong>Settings → Uninstall ProxMenux</strong>. The uninstaller removes the script tree, the launcher and the Monitor service, optionally removes selected dependencies, and restores <code>/root/.bashrc</code> and <code>/etc/motd</code> from the backups created by Post-Install, if they exist (otherwise it removes the ProxMenux MOTD line).",
|
||||
"p2Rich": "Full step-by-step: <uninstalllink>Uninstall ProxMenux</uninstalllink>."
|
||||
},
|
||||
"q11": {
|
||||
"question": "VirusTotal flags the install URL — is it safe?",
|
||||
"p1Rich": "A 1/95 detection by heuristic engines (e.g. <em>Chong Lua Dao</em>) is a known false positive. The installer uses the standard <code>curl | bash</code> pattern and downloads legitimate binaries (like <code>jq</code> from its official GitHub release), which aggressive scanners flag based on <em>behaviour</em> rather than actual malicious code.",
|
||||
"p1Rich": "The 1/95 result reported in Issue #162, from <em>Chong Lua Dao</em>, was identified by the maintainer as a false positive. The installer is run with a command that downloads and executes the script (<code>bash -c \"$(wget -qLO - …)\"</code>) and can download <code>jq</code> from its official GitHub release. Such <em>behaviour</em> can trigger heuristic scanners; the historical report is not a verdict on every future download.",
|
||||
"p2Rich": "ProxMenux is 100% open source and the install script is reviewable line by line: <scriptlink>install_proxmenux.sh</scriptlink>. More context in <issuelink>Issue #162</issuelink>."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,21 @@
|
||||
"heading": "The direction check",
|
||||
"intro": "During the compatibility check, <code>hb_compat_check</code> compares the kernel recorded in the backup's manifest against the target's current kernel (<code>uname -r</code>) and classifies the restore into one of three cases, stored in the internal variable <code>HB_COMPAT_KERNEL_DIRECTION</code>:",
|
||||
"rows": [
|
||||
{ "direction": "same", "condition": "The major kernel version matches between backup and target.", "behavior": "The full restore flow runs unchanged. No extra filter, no hydration, no special notice in the UI." },
|
||||
{ "direction": "bk_newer", "condition": "Backup kernel is NEWER than the target's (for example: the backup was made on kernel 7.0 and the target runs kernel 6.17).", "behavior": "The full restore flow runs unchanged, exactly like <code>same</code>. No filter is applied. Verified empirically: drivers auto-reinstall against the target's kernel, IOMMU config applies cleanly, VMs with GPU passthrough come up without issue." },
|
||||
{ "direction": "bk_older", "condition": "Backup kernel is OLDER than the target's (for example: the backup was made on kernel 6.17 and the target runs kernel 7.0).", "behavior": "The safe-subset filter and the four-phase hydration below are activated. The restore proceeds — the target reproduces the source, but boot-critical files are not copied verbatim." }
|
||||
{
|
||||
"direction": "same",
|
||||
"condition": "The major kernel version matches between backup and target.",
|
||||
"behavior": "The full restore flow runs unchanged. No extra filter, no hydration, no special notice in the UI."
|
||||
},
|
||||
{
|
||||
"direction": "bk_newer",
|
||||
"condition": "Backup kernel is NEWER than the target's (for example: the backup was made on kernel 7.0 and the target runs kernel 6.17).",
|
||||
"behavior": "The full restore flow runs unchanged, exactly like <code>same</code>. No filter is applied. Verified empirically: drivers auto-reinstall against the target's kernel, IOMMU config applies cleanly, VMs with GPU passthrough come up without issue."
|
||||
},
|
||||
{
|
||||
"direction": "bk_older",
|
||||
"condition": "Backup kernel is OLDER than the target's (for example: the backup was made on kernel 6.17 and the target runs kernel 7.0).",
|
||||
"behavior": "The safe-subset filter and the four-phase hydration below are activated. The restore proceeds — the target reproduces the source, but boot-critical files are not copied verbatim."
|
||||
}
|
||||
]
|
||||
},
|
||||
"whyBkNewerIsSafe": {
|
||||
@@ -31,25 +43,60 @@
|
||||
},
|
||||
"safeSubsetFilter": {
|
||||
"heading": "The safe-subset filter (only when the target kernel is newer)",
|
||||
"intro": "When the target kernel is newer than the backup's, the compatibility check adds 16 boot-critical paths from <code>hb_unsafe_paths_cross_version</code> to <code>RS_SKIP_PATHS</code>. These paths are excluded from the restore because writing a version of them from an older kernel over a target running a newer one has caused kernel panics in bench tests. The paths cover four categories:",
|
||||
"intro": "When the target kernel is newer than the backup's, the compatibility check adds 16 boot-critical paths from <code>hb_unsafe_paths_cross_version</code> to <code>RS_SKIP_PATHS</code>. These paths are excluded from the restore because writing a version of them from an older kernel over a target running a newer one has caused kernel panics in bench tests. The paths cover five categories:",
|
||||
"categoryRows": [
|
||||
{ "category": "Bootloader", "paths": "<code>/etc/default/grub</code>, <code>/etc/kernel</code>", "reason": "GRUB defaults tied to the prior kernel order, and proxmox-boot-tool state (cmdline, ESP UUIDs, hooks) that references paths and identifiers from the older install." },
|
||||
{ "category": "Kernel modules and boot artifacts", "paths": "<code>/etc/modules-load.d</code>, <code>/etc/modprobe.d</code>, <code>/etc/initramfs-tools</code>", "reason": "Autoload lists that may reference modules renamed between kernel majors, module options that may not apply, initramfs hooks written for the older kernel." },
|
||||
{ "category": "Storage stack and filesystem identity", "paths": "<code>/etc/fstab</code>, <code>/etc/multipath</code>, <code>/etc/iscsi</code>, <code>/etc/udev/rules.d</code>, <code>/etc/zfs</code>", "reason": "UUIDs that may not exist on this install, multipath drivers that change between kernels, iSCSI parameters that evolve, udev rules that may bind to nonexistent subsystems, ZFS state (<code>zpool.cache</code> + <code>hostid</code>) that can lock the pool as foreign." },
|
||||
{ "category": "APT sources", "paths": "<code>/etc/apt</code>", "reason": "APT source suites may trigger a downgrade of critical packages on the next upgrade." },
|
||||
{ "category": "systemd", "paths": "<code>/etc/systemd/system</code>, <code>/etc/systemd/journald.conf</code>, <code>/etc/systemd/logind.conf</code>, <code>/etc/systemd/system.conf</code>, <code>/etc/systemd/user.conf</code>", "reason": "Unit overrides and .wants tied to the older systemd major; configuration keys that may not parse on a newer systemd." }
|
||||
{
|
||||
"category": "Bootloader",
|
||||
"paths": "<code>/etc/default/grub</code>, <code>/etc/kernel</code>",
|
||||
"reason": "GRUB defaults tied to the prior kernel order, and proxmox-boot-tool state (cmdline, ESP UUIDs, hooks) that references paths and identifiers from the older install."
|
||||
},
|
||||
{
|
||||
"category": "Kernel modules and boot artifacts",
|
||||
"paths": "<code>/etc/modules-load.d</code>, <code>/etc/modprobe.d</code>, <code>/etc/initramfs-tools</code>",
|
||||
"reason": "Autoload lists that may reference modules renamed between kernel majors, module options that may not apply, initramfs hooks written for the older kernel."
|
||||
},
|
||||
{
|
||||
"category": "Storage stack and filesystem identity",
|
||||
"paths": "<code>/etc/fstab</code>, <code>/etc/multipath</code>, <code>/etc/iscsi</code>, <code>/etc/udev/rules.d</code>, <code>/etc/zfs</code>",
|
||||
"reason": "UUIDs that may not exist on this install, multipath drivers that change between kernels, iSCSI parameters that evolve, udev rules that may bind to nonexistent subsystems, ZFS state (<code>zpool.cache</code> + <code>hostid</code>) that can lock the pool as foreign."
|
||||
},
|
||||
{
|
||||
"category": "APT sources",
|
||||
"paths": "<code>/etc/apt</code>",
|
||||
"reason": "APT source suites may trigger a downgrade of critical packages on the next upgrade."
|
||||
},
|
||||
{
|
||||
"category": "systemd",
|
||||
"paths": "<code>/etc/systemd/system</code>, <code>/etc/systemd/journald.conf</code>, <code>/etc/systemd/logind.conf</code>, <code>/etc/systemd/system.conf</code>, <code>/etc/systemd/user.conf</code>",
|
||||
"reason": "Unit overrides and .wants tied to the older systemd major; configuration keys that may not parse on a newer systemd."
|
||||
}
|
||||
],
|
||||
"outroBody": "The filter runs BEFORE the confirmation dialog so the user sees the exact list of paths that will be skipped, categorised by reason. The restore still proceeds — everything else (VMs, LXCs, network, /etc/pve, users, cron, ProxMenux state, packages, drivers, /root) is restored normally."
|
||||
"outroBody": "The filter runs BEFORE the confirmation dialog so the user sees the exact list of paths that will be skipped, categorised by reason. The restore still proceeds — everything else (VM/LXC configuration, network, /etc/pve, users, cron, ProxMenux state, packages, drivers, /root) is restored normally."
|
||||
},
|
||||
"hydration": {
|
||||
"heading": "Kernel-agnostic hydration",
|
||||
"intro": "The safe-subset filter alone would leave the target without the tuning the user had inside those boot-critical files: IOMMU cmdline for GPU passthrough, VFIO device IDs, custom <code>GRUB_TIMEOUT</code>, nvidia blacklists. The hydration pass re-applies those bits kernel-agnostically. Four phases run when the target kernel is newer than the backup's, each additive (never overwrites a value the target already carries) and idempotent (running twice is a no-op).",
|
||||
"intro": "The filter omits boot-critical files, so hydration reapplies selected user tuning: IOMMU cmdline, VFIO IDs, custom <code>GRUB_TIMEOUT</code> and nvidia blacklists. It runs when the target kernel is newer. Cmdline merges preserve existing target keys and module merges append missing entries. Whitelisted GRUB values and user files may replace differing target content. Repeating the same input is idempotent.",
|
||||
"phaseRows": [
|
||||
{ "phase": "1a — GRUB path", "detail": "For hosts using GRUB (ext4/lvm installs). <code>_rs_hyd_grub</code> merges every token from the backup's <code>manifest.kernel_params.cmdline_extra</code> into the target's live <code>GRUB_CMDLINE_LINUX_DEFAULT</code>, skipping tokens whose key the target already carries. Then merges whitelisted <code>GRUB_*</code> keys (<code>GRUB_TIMEOUT</code>, <code>GRUB_TIMEOUT_STYLE</code>, <code>GRUB_DEFAULT</code>, <code>GRUB_TERMINAL</code>, <code>GRUB_DISABLE_OS_PROBER</code>, <code>GRUB_SERIAL_COMMAND</code>, <code>GRUB_GFXMODE</code>, <code>GRUB_GFXPAYLOAD_LINUX</code>) from the backup's <code>/etc/default/grub</code> if they differ from the target's." },
|
||||
{ "phase": "1b — systemd-boot / ZFS path", "detail": "For hosts using systemd-boot (typically ZFS-on-root). <code>_rs_hyd_kernel_cmdline</code> merges user tokens from <code>cmdline_extra</code> into the target's <code>/etc/kernel/cmdline</code>, keeping the target's own <code>root=</code>, <code>boot=</code> and <code>rootflags=</code> boilerplate intact." },
|
||||
{ "phase": "2 — /etc/modules merge", "detail": "<code>_rs_hyd_modules</code> appends modules from <code>manifest.kernel_params.modules_loaded_at_boot</code> that are in the whitelist (<code>vfio</code>, <code>vfio_pci</code>, <code>vfio_iommu_type1</code>, <code>vfio_virqfd</code>, <code>kvm</code>, <code>kvm_intel</code>, <code>kvm_amd</code>, <code>nvidia</code>, <code>nvidia_drm</code>, <code>nvidia_modeset</code>, <code>nvidia_uvm</code>, <code>i915</code>, <code>xe</code>) AND not already present in the target's <code>/etc/modules</code>." },
|
||||
{ "phase": "3 — Whitelisted files copy", "detail": "<code>_rs_hyd_files</code> copies user-authored files from the staging rootfs to the live target when the content differs. Whitelist covers VFIO/nvidia/blacklist files under <code>/etc/modprobe.d</code>, <code>/etc/modules-load.d</code>, and the ProxMenux VFIO bind rule + nvidia udev rules under <code>/etc/udev/rules.d</code>. Distro-owned files (<code>pve-blacklist.conf</code>, <code>mdadm.conf</code>, <code>nvme.conf</code>) are intentionally excluded — their contents evolve between releases." },
|
||||
{ "phase": "4 — Force post-boot reflows", "detail": "The four phases write directly to the live target OUTSIDE the normal restore pipeline. To make the merged tokens/modules/files take effect on the next boot, <code>HB_HYDRATION_APPLIED=1</code> propagates through <code>plan.env</code> to <code>apply_pending_restore.sh</code>, which forces <code>NEEDS_INITRAMFS=1</code> and <code>NEEDS_GRUB=1</code> regardless of what was in the apply list. The post-boot dispatcher then regenerates initramfs and refreshes the bootloader." }
|
||||
{
|
||||
"phase": "1a — GRUB path",
|
||||
"detail": "For hosts using GRUB (ext4/lvm installs). <code>_rs_hyd_grub</code> merges every token from the backup's <code>manifest.kernel_params.cmdline_extra</code> into the target's live <code>GRUB_CMDLINE_LINUX_DEFAULT</code>, skipping tokens whose key the target already carries. Then merges whitelisted <code>GRUB_*</code> keys (<code>GRUB_TIMEOUT</code>, <code>GRUB_TIMEOUT_STYLE</code>, <code>GRUB_DEFAULT</code>, <code>GRUB_TERMINAL</code>, <code>GRUB_DISABLE_OS_PROBER</code>, <code>GRUB_SERIAL_COMMAND</code>, <code>GRUB_GFXMODE</code>, <code>GRUB_GFXPAYLOAD_LINUX</code>) from the backup's <code>/etc/default/grub</code> if they differ from the target's."
|
||||
},
|
||||
{
|
||||
"phase": "1b — systemd-boot / ZFS path",
|
||||
"detail": "For hosts using systemd-boot (typically ZFS-on-root). <code>_rs_hyd_kernel_cmdline</code> merges user tokens from <code>cmdline_extra</code> into the target's <code>/etc/kernel/cmdline</code>, keeping the target's own <code>root=</code>, <code>boot=</code> and <code>rootflags=</code> boilerplate intact."
|
||||
},
|
||||
{
|
||||
"phase": "2 — /etc/modules merge",
|
||||
"detail": "<code>_rs_hyd_modules</code> appends modules from <code>manifest.kernel_params.modules_loaded_at_boot</code> that are in the whitelist (<code>vfio</code>, <code>vfio_pci</code>, <code>vfio_iommu_type1</code>, <code>vfio_virqfd</code>, <code>kvm</code>, <code>kvm_intel</code>, <code>kvm_amd</code>, <code>nvidia</code>, <code>nvidia_drm</code>, <code>nvidia_modeset</code>, <code>nvidia_uvm</code>, <code>i915</code>, <code>xe</code>) AND not already present in the target's <code>/etc/modules</code>."
|
||||
},
|
||||
{
|
||||
"phase": "3 — Whitelisted files copy",
|
||||
"detail": "<code>_rs_hyd_files</code> copies user-authored files from the staging rootfs to the live target when the content differs. Whitelist covers VFIO/nvidia/blacklist files under <code>/etc/modprobe.d</code>, <code>/etc/modules-load.d</code>, and the ProxMenux VFIO bind rule + nvidia udev rules under <code>/etc/udev/rules.d</code>. Distro-owned files (<code>pve-blacklist.conf</code>, <code>mdadm.conf</code>, <code>nvme.conf</code>) are intentionally excluded — their contents evolve between releases."
|
||||
},
|
||||
{
|
||||
"phase": "4 — Force post-boot reflows",
|
||||
"detail": "The four phases write directly to the live target OUTSIDE the normal restore pipeline. To make the merged tokens/modules/files take effect on the next boot, <code>HB_HYDRATION_APPLIED=1</code> propagates through <code>plan.env</code> to <code>apply_pending_restore.sh</code>, which forces <code>NEEDS_INITRAMFS=1</code> and <code>NEEDS_GRUB=1</code> regardless of what was in the apply list. The post-boot dispatcher then regenerates initramfs and refreshes the bootloader."
|
||||
}
|
||||
]
|
||||
},
|
||||
"planCommit": {
|
||||
@@ -65,8 +112,14 @@
|
||||
"heading": "Concrete examples",
|
||||
"intro": "The hydration pass is not abstract — it produces observable, correct outcomes for common scenarios. Two examples that hydration handles automatically:",
|
||||
"rows": [
|
||||
{ "scenario": "GPU passthrough (VFIO)", "detail": "Source had <code>intel_iommu=on iommu=pt</code> in the cmdline, <code>vfio</code>/<code>vfio_pci</code>/<code>vfio_iommu_type1</code> in <code>/etc/modules</code>, an <code>/etc/modprobe.d/vfio.conf</code> with <code>options vfio-pci ids=10de:2216</code>, and a <code>/etc/modprobe.d/blacklist-nvidia.conf</code>. Hydration merges the cmdline tokens into the target's GRUB or kernel cmdline, appends the vfio modules to <code>/etc/modules</code>, and copies the two user-authored modprobe files. On the next boot, IOMMU is active, VFIO modules load, the GPU is bound to vfio-pci and the VM comes up with passthrough working." },
|
||||
{ "scenario": "Custom GRUB defaults", "detail": "Source had <code>GRUB_TIMEOUT=1</code> and <code>GRUB_DISABLE_OS_PROBER=true</code>. Hydration reads both keys from the backup's <code>/etc/default/grub</code>, sees they differ from the fresh install's defaults, and rewrites those two lines in the target's file (leaving everything else, including <code>GRUB_DISTRIBUTOR</code>, untouched)." }
|
||||
{
|
||||
"scenario": "GPU passthrough (VFIO)",
|
||||
"detail": "Source had <code>intel_iommu=on iommu=pt</code> in the cmdline, <code>vfio</code>/<code>vfio_pci</code>/<code>vfio_iommu_type1</code> in <code>/etc/modules</code>, an <code>/etc/modprobe.d/vfio.conf</code> with <code>options vfio-pci ids=10de:2216</code>, and a <code>/etc/modprobe.d/blacklist-nvidia.conf</code>. Hydration merges the cmdline tokens into the target's GRUB or kernel cmdline, appends the vfio modules to <code>/etc/modules</code>, and copies the two user-authored modprobe files. On the next boot, IOMMU is active, VFIO modules load, the GPU is bound to vfio-pci and the VM comes up with passthrough working."
|
||||
},
|
||||
{
|
||||
"scenario": "Custom GRUB defaults",
|
||||
"detail": "Source had <code>GRUB_TIMEOUT=1</code> and <code>GRUB_DISABLE_OS_PROBER=true</code>. Hydration reads both keys from the backup's <code>/etc/default/grub</code>, sees they differ from the fresh install's defaults, and rewrites those two lines in the target's file (leaving everything else, including <code>GRUB_DISTRIBUTOR</code>, untouched)."
|
||||
}
|
||||
]
|
||||
},
|
||||
"callout": {
|
||||
@@ -77,18 +130,41 @@
|
||||
"heading": "Where the mechanisms live",
|
||||
"intro": "For developers looking to trace or extend the cross-kernel behaviour:",
|
||||
"rows": [
|
||||
{ "component": "Direction detection", "location": "<code>hb_compat_check</code> in <code>lib_host_backup_common.sh</code>. Sets <code>HB_COMPAT_KERNEL_DIRECTION</code>." },
|
||||
{ "component": "Safe-subset path list", "location": "<code>hb_unsafe_paths_cross_version</code> in <code>lib_host_backup_common.sh</code>. Emits <code>path\\treason</code> lines used by both the CLI filter and the Web endpoint <code>/api/host-backups/restore/prepare</code>." },
|
||||
{ "component": "Hydration phases", "location": "<code>_rs_hyd_grub</code>, <code>_rs_hyd_kernel_cmdline</code>, <code>_rs_hyd_modules</code>, <code>_rs_hyd_files</code> in <code>backup_host.sh</code>. Orchestrated by <code>_rs_apply_bk_older_hydration</code>." },
|
||||
{ "component": "Post-boot reflow forcing", "location": "<code>apply_pending_restore.sh</code> reads <code>HB_HYDRATION_APPLIED</code> from <code>plan.env</code> and forces <code>NEEDS_INITRAMFS=1</code>/<code>NEEDS_GRUB=1</code>." },
|
||||
{ "component": "Web preview", "location": "<code>/api/host-backups/restore/prepare</code> in <code>flask_server.py</code>. Sources the helper library, runs <code>_rs_apply_bk_older_hydration</code> in plan mode, returns the actions to the Web modal." }
|
||||
{
|
||||
"component": "Direction detection",
|
||||
"location": "<code>hb_compat_check</code> in <code>lib_host_backup_common.sh</code>. Sets <code>HB_COMPAT_KERNEL_DIRECTION</code>."
|
||||
},
|
||||
{
|
||||
"component": "Safe-subset path list",
|
||||
"location": "<code>hb_unsafe_paths_cross_version</code> in <code>lib_host_backup_common.sh</code>. Emits <code>path\\treason</code> lines used by both the CLI filter and the Web endpoint <code>/api/host-backups/restore/prepare</code>."
|
||||
},
|
||||
{
|
||||
"component": "Hydration phases",
|
||||
"location": "<code>_rs_hyd_grub</code>, <code>_rs_hyd_kernel_cmdline</code>, <code>_rs_hyd_modules</code>, <code>_rs_hyd_files</code> in <code>backup_host.sh</code>. Orchestrated by <code>_rs_apply_bk_older_hydration</code>."
|
||||
},
|
||||
{
|
||||
"component": "Post-boot reflow forcing",
|
||||
"location": "<code>apply_pending_restore.sh</code> reads <code>HB_HYDRATION_APPLIED</code> from <code>plan.env</code> and forces <code>NEEDS_INITRAMFS=1</code>/<code>NEEDS_GRUB=1</code>."
|
||||
},
|
||||
{
|
||||
"component": "Web preview",
|
||||
"location": "<code>/api/host-backups/restore/prepare</code> in <code>flask_server.py</code>. Sources the helper library, runs <code>_rs_apply_bk_older_hydration</code> in plan mode, returns the actions to the Web modal."
|
||||
}
|
||||
]
|
||||
},
|
||||
"whereNext": {
|
||||
"heading": "Where to go next",
|
||||
"items": [
|
||||
{ "label": "Restoring", "href": "/docs/backup-restore/restoring", "tail": " — the full restore pipeline this page's mechanisms plug into." },
|
||||
{ "label": "How it works", "href": "/docs/backup-restore/how-it-works", "tail": " — the manifest and collectors that produce the <code>kernel_params</code> block hydration reads from." }
|
||||
{
|
||||
"label": "Restoring",
|
||||
"href": "/docs/backup-restore/restoring",
|
||||
"tail": " — the full restore pipeline this page's mechanisms plug into."
|
||||
},
|
||||
{
|
||||
"label": "How it works",
|
||||
"href": "/docs/backup-restore/how-it-works",
|
||||
"tail": " — the manifest and collectors that produce the <code>kernel_params</code> block hydration reads from."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,19 +24,47 @@
|
||||
"heading": "The borg binary",
|
||||
"intro": "Borg is not a base dependency of the ProxMenux installer. When a backup runs, <code>hb_ensure_borg</code> resolves the binary from four sources in order and returns the first that works:",
|
||||
"rows": [
|
||||
{ "priority": "1", "source": "System <code>borg</code>", "detail": "If the host already has <code>borg</code> installed via APT (<code>which borg</code> resolves), that binary is used." },
|
||||
{ "priority": "2", "source": "State-dir cache", "detail": "<code>/usr/local/share/proxmenux/borg</code> — kept from a prior GitHub download on this host." },
|
||||
{ "priority": "3", "source": "Monitor AppImage bundle", "detail": "<code>/usr/local/share/proxmenux/monitor-app/usr/bin/borg</code> — the AppImage bundles a signed borg-linux64. This is the offline-safe path: a host with no internet still has a working <code>borg</code>." },
|
||||
{ "priority": "4", "source": "GitHub download", "detail": "<code>wget</code> against the pinned <code>borg-linux64</code> URL under <code>github.com/borgbackup/borg/releases/</code>, verified against a constant SHA-256 in <code>lib_host_backup_common.sh</code> (<code>HB_BORG_LINUX64_SHA256</code>). On checksum mismatch the binary is discarded and the backup aborts. The downloaded file is cached in the state dir so subsequent backups use path 2." }
|
||||
{
|
||||
"priority": "1",
|
||||
"source": "System <code>borg</code>",
|
||||
"detail": "If the host already has <code>borg</code> installed via APT (<code>which borg</code> resolves), that binary is used."
|
||||
},
|
||||
{
|
||||
"priority": "2",
|
||||
"source": "State-dir cache",
|
||||
"detail": "<code>/usr/local/share/proxmenux/borg</code> — kept from a prior GitHub download on this host."
|
||||
},
|
||||
{
|
||||
"priority": "3",
|
||||
"source": "Monitor AppImage bundle",
|
||||
"detail": "<code>/usr/local/share/proxmenux/monitor-app/usr/bin/borg</code> — the AppImage bundles a signed borg-linux64. This is the offline-safe path: a host with no internet still has a working <code>borg</code>."
|
||||
},
|
||||
{
|
||||
"priority": "4",
|
||||
"source": "GitHub download",
|
||||
"detail": "<code>wget</code> against the pinned <code>borg-linux64</code> URL under <code>github.com/borgbackup/borg/releases/</code>, verified against a constant SHA-256 in <code>lib_host_backup_common.sh</code> (<code>HB_BORG_LINUX64_SHA256</code>). On checksum mismatch the binary is discarded and the backup aborts. The downloaded file is cached in the state dir so subsequent backups use path 2."
|
||||
}
|
||||
]
|
||||
},
|
||||
"repoTypes": {
|
||||
"heading": "Repository types",
|
||||
"intro": "The repository type is chosen when a target is added. Each type resolves to a different repository URL that Borg understands.",
|
||||
"rows": [
|
||||
{ "type": "remote", "url": "ssh://USER@HOST/RPATH", "detail": "Repository lives on a remote server that runs <code>borg serve</code>. Requires an SSH connection to that server." },
|
||||
{ "type": "usb", "url": "/mnt/MOUNTPOINT/borgbackup", "detail": "Repository lives on a mounted external disk (typically USB). The mount is resolved via <code>hb_prompt_mounted_path</code>, which detects, mounts or formats USB partitions as needed." },
|
||||
{ "type": "local", "url": "/backup/borgbackup (any absolute path)", "detail": "Repository lives on a local directory. Meaningful only when the target directory is on a separate physical disk — a repository on the same disk as the source protects against operator error but not against disk failure." }
|
||||
{
|
||||
"type": "remote",
|
||||
"url": "ssh://USER@HOST/RPATH",
|
||||
"detail": "Repository lives on a remote server that runs <code>borg serve</code>. Requires an SSH connection to that server."
|
||||
},
|
||||
{
|
||||
"type": "usb",
|
||||
"url": "/mnt/MOUNTPOINT/borgbackup",
|
||||
"detail": "Repository lives on a mounted external disk (typically USB). The mount is resolved via <code>hb_prompt_mounted_path</code>, which detects, mounts or formats USB partitions as needed."
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"url": "/backup/borgbackup (any absolute path)",
|
||||
"detail": "Repository lives on a local directory. Meaningful only when the target directory is on a separate physical disk — a repository on the same disk as the source protects against operator error but not against disk failure."
|
||||
}
|
||||
]
|
||||
},
|
||||
"serverSetup": {
|
||||
@@ -50,30 +78,62 @@
|
||||
"Another Proxmox host on the same LAN, or a VM anywhere reachable over SSH."
|
||||
],
|
||||
"lxcWarningTitle": "LXC as Borg server",
|
||||
"lxcWarningBody": "If the Borg server runs inside an LXC, the container must have a user account with a password.",
|
||||
"lxcWarningBody": "If the Borg server runs inside an LXC, generate-auto requires an account that accepts SSH password authentication during key installation. If password login is unavailable, use manual key installation or the generate-pct alternative through the PVE host.",
|
||||
"requirementsTitle": "Requirements on the server",
|
||||
"requirementsRows": [
|
||||
{ "requirement": "borg binary at <code>/usr/bin/borg</code>", "detail": "The <code>command=\"/usr/bin/borg serve ...\"</code> line ProxMenux writes into <code>authorized_keys</code> hard-codes that path. Installing via APT (<code>apt install borgbackup</code>) puts it there. A standalone binary must be symlinked to <code>/usr/bin/borg</code>." },
|
||||
{ "requirement": "A dedicated user account (typically <code>borg</code>)", "detail": "Owns the repository directory and receives incoming SSH connections. Does not need sudo or shell access — the authorized_keys line disables interactive shells anyway." },
|
||||
{ "requirement": "A writable repository directory", "detail": "The path the operator gives ProxMenux (for example <code>/backup/borgbackup</code>) must exist on the server and be owned by the borg user." },
|
||||
{ "requirement": "SSH daemon accepting the borg user", "detail": "<code>PubkeyAuthentication yes</code> (default). Password authentication is only needed for the one-shot <em>generate-auto</em> flow — after the key is installed, the server can disable password auth entirely." }
|
||||
{
|
||||
"requirement": "borg binary at <code>/usr/bin/borg</code>",
|
||||
"detail": "The <code>command=\"/usr/bin/borg serve ...\"</code> line ProxMenux writes into <code>authorized_keys</code> hard-codes that path. Installing via APT (<code>apt install borgbackup</code>) puts it there. A standalone binary must be symlinked to <code>/usr/bin/borg</code>."
|
||||
},
|
||||
{
|
||||
"requirement": "A dedicated user account (typically <code>borg</code>)",
|
||||
"detail": "Owns the repository directory and receives incoming SSH connections. Does not need sudo or shell access — the authorized_keys line disables interactive shells anyway."
|
||||
},
|
||||
{
|
||||
"requirement": "A writable repository directory",
|
||||
"detail": "The path the operator gives ProxMenux (for example <code>/backup/borgbackup</code>) must exist on the server and be owned by the borg user."
|
||||
},
|
||||
{
|
||||
"requirement": "SSH daemon accepting the borg user",
|
||||
"detail": "<code>PubkeyAuthentication yes</code> (default). Password authentication is only needed for the one-shot <em>generate-auto</em> flow — after the key is installed, the server can disable password auth entirely."
|
||||
}
|
||||
],
|
||||
"minimalSetupTitle": "Minimal server setup",
|
||||
"minimalSetupBody": "On a Debian or Ubuntu Borg server, a working baseline is four commands as root:",
|
||||
"minimalSetupCmd": "apt install borgbackup\nuseradd -m -d /home/borg -s /bin/bash borg\nmkdir -p /backup/borgbackup\nchown borg:borg /backup/borgbackup",
|
||||
"minimalSetupNote": "After this, ProxMenux's <code>generate-auto</code> mode can connect using the borg user's password once, install its own SSH key, and every subsequent backup uses that key. No further server-side configuration is needed — the key restricts itself to <code>borg serve</code> on that path."
|
||||
"minimalSetupNote": "With the server prepared and SSH password authentication available, ProxMenux’s <code>generate-auto</code> mode can install its SSH key using an account permitted to write the borg user’s authorized_keys file. Subsequent backups use that key, restricted to <code>borg serve</code> on the configured path. Without password login, install the key manually or use the PVE-host alternative."
|
||||
},
|
||||
"sshAuth": {
|
||||
"heading": "SSH authentication (client side)",
|
||||
"intro": "Remote Borg repositories are accessed over SSH. The connection runs from the ProxMenux host to a user account on the Borg server that runs <code>borg serve</code>. This user is typically named <code>borg</code>, NOT the admin/root user of the server — the borg-serve command line locks the connection to that specific repository path (see the key strategies below).",
|
||||
"strategiesTitle": "The four key strategies",
|
||||
"strategiesIntro": "When a remote target is added, ProxMenux prompts for the SSH user, host and remote path, then asks how to authenticate. Four modes:",
|
||||
"strategiesTitle": "SSH key strategies",
|
||||
"strategiesIntro": "When a remote target is added, ProxMenux asks for the SSH user, host, port and remote path, then offers four authentication choices. The additional generate-pct path is offered when password authentication is refused. The modes are described below:",
|
||||
"strategyRows": [
|
||||
{ "mode": "generate-auto", "label": "Recommended", "detail": "ProxMenux generates a new ed25519 keypair at <code>~/.ssh/borg_proxmenux_HOST_ed25519</code>, then uses <code>sshpass</code> to log in ONCE to the server with the admin password and append the public key to <code>~borg/.ssh/authorized_keys</code>. The admin password is only used for this one call — it is never stored." },
|
||||
{ "mode": "generate-manual", "label": "No admin password on this host", "detail": "ProxMenux generates the keypair as above but displays the full <code>authorized_keys</code> line for the operator to paste manually into the server. The admin password never leaves the ProxMenux host because it is never asked for." },
|
||||
{ "mode": "generate-pct", "label": "Borg server is a PVE LXC", "detail": "The Borg server runs inside an LXC on a PVE node. ProxMenux authorises the key via <code>pct exec</code> from the PVE host — root on the PVE host writes into the LXC's <code>~borg/.ssh/authorized_keys</code> without needing SSH into the LXC itself." },
|
||||
{ "mode": "existing", "label": "Use an existing key", "detail": "ProxMenux scans <code>/root/.ssh/</code> and <code>$HOME/.ssh/</code> for parseable ed25519/RSA private keys and lists them. The operator picks one or browses manually to a non-standard path." },
|
||||
{ "mode": "none", "label": "Default SSH config", "detail": "No custom key — Borg relies on the host's default SSH configuration (typically <code>~/.ssh/id_rsa</code> or an SSH agent)." }
|
||||
{
|
||||
"mode": "generate-auto",
|
||||
"label": "Recommended",
|
||||
"detail": "ProxMenux generates or reuses an ed25519 keypair at <code>~/.ssh/borg_proxmenux_HOST_ed25519</code>, then uses <code>sshpass</code> for a login probe and installation of the public key in <code>~borg/.ssh/authorized_keys</code>. The password belongs to an account allowed to write that file, usually root or the borg user. It is used during setup and is not saved."
|
||||
},
|
||||
{
|
||||
"mode": "generate-manual",
|
||||
"label": "No admin password on this host",
|
||||
"detail": "ProxMenux generates the keypair as above but displays the full <code>authorized_keys</code> line for the operator to paste manually into the server. The admin password never leaves the ProxMenux host because it is never asked for."
|
||||
},
|
||||
{
|
||||
"mode": "generate-pct",
|
||||
"label": "Borg server is a PVE LXC",
|
||||
"detail": "The Borg server runs inside an LXC on a PVE node. ProxMenux authorises the key via <code>pct exec</code> from the PVE host — root on the PVE host writes into the LXC's <code>~borg/.ssh/authorized_keys</code> without needing SSH into the LXC itself."
|
||||
},
|
||||
{
|
||||
"mode": "existing",
|
||||
"label": "Use an existing key",
|
||||
"detail": "ProxMenux scans <code>/root/.ssh/</code> and <code>$HOME/.ssh/</code> for parseable ed25519/RSA private keys and lists them. The operator picks one or browses manually to a non-standard path."
|
||||
},
|
||||
{
|
||||
"mode": "none",
|
||||
"label": "Default SSH config",
|
||||
"detail": "No custom key — Borg relies on the host's default SSH configuration (typically <code>~/.ssh/id_rsa</code> or an SSH agent)."
|
||||
}
|
||||
],
|
||||
"restrictTitle": "The authorized_keys line",
|
||||
"restrictBody": "For every generated key, the <code>authorized_keys</code> line ProxMenux writes on the server locks the key to a single borg-serve invocation against the configured repository path:",
|
||||
@@ -84,24 +144,50 @@
|
||||
"heading": "Saved targets",
|
||||
"intro": "A saved target persists the repository configuration under a friendly name so the details do not have to be re-entered. Storage layout in the ProxMenux state directory:",
|
||||
"rows": [
|
||||
{ "file": "borg-targets.txt", "content": "One line per target: <code>NAME|REPO|SSH_KEY_PATH|ENCRYPT_MODE</code>. Read by <code>hb_collect_borg_configs</code> to populate the target-selection menu." },
|
||||
{ "file": "borg-pass-NAME.txt", "content": "Passphrase for the target NAMEd above (<code>chmod 600</code>). Only present when the operator chose repokey encryption." }
|
||||
{
|
||||
"file": "borg-targets.txt",
|
||||
"content": "One line per target: <code>NAME|REPO|SSH_KEY_PATH|ENCRYPT_MODE</code>. Read by <code>hb_collect_borg_configs</code> to populate the target-selection menu."
|
||||
},
|
||||
{
|
||||
"file": "borg-pass-NAME.txt",
|
||||
"content": "Passphrase for the target NAMEd above (<code>chmod 600</code>). Only present when the operator chose repokey encryption."
|
||||
}
|
||||
],
|
||||
"outro": "Saving is optional — the operator can decline the save prompt for a one-shot backup that leaves no credentials on the host."
|
||||
"outro": "Saving the target is optional. Declining the save prompt omits the named target configuration, but does not remove a generated SSH key. If repokey encryption is enabled without a saved target, ProxMenux still saves the passphrase in the legacy borg-pass.txt file."
|
||||
},
|
||||
"encryption": {
|
||||
"heading": "Encryption",
|
||||
"body": "Repositories are initialised with an encryption mode via <code>hb_borg_init_if_needed</code>: the modern <code>borg repo-create -e MODE</code> when available, or the legacy <code>borg init --encryption=MODE</code>. ProxMenux exposes two modes: <code>repokey</code> (default) and <code>none</code>. In <code>repokey</code> mode Borg stores the encryption key inside the repository itself; access requires a passphrase, which ProxMenux prompts for twice with match validation and stores at <code>borg-pass-NAME.txt</code>. A mandatory acknowledgement dialog is shown after the passphrase is saved: the passphrase is the only way to access the encrypted archives, and losing it makes every archive in the repository unrecoverable."
|
||||
"body": "Repositories are initialised with an encryption mode via <code>hb_borg_init_if_needed</code>: the modern <code>borg repo-create -e MODE</code> when available, or the legacy <code>borg init --encryption=MODE</code>. ProxMenux exposes two modes: <code>repokey</code> (default) and <code>none</code>. In <code>repokey</code> mode Borg stores the encryption key inside the repository itself; access requires a passphrase, which ProxMenux prompts for twice with match validation and stores at <code>borg-pass-NAME.txt</code> for saved targets (or in the legacy file described above). A mandatory acknowledgement dialog is shown after the passphrase is saved: the passphrase is the only way to access the encrypted archives, and losing it makes every archive in the repository unrecoverable."
|
||||
},
|
||||
"runtimeEnv": {
|
||||
"heading": "Runtime environment",
|
||||
"intro": "ProxMenux exports the following environment variables before invoking <code>borg</code>. They configure the connection and unlock the repository without embedding secrets in the command line.",
|
||||
"rows": [
|
||||
{ "var": "BORG_RSH", "value": "ssh -i SSH_KEY_PATH -o StrictHostKeyChecking=accept-new", "purpose": "The remote-shell command Borg uses for SSH-served repositories. Set only when a custom key was selected; otherwise unset so Borg uses the default SSH configuration." },
|
||||
{ "var": "BORG_PASSPHRASE", "value": "(passphrase from borg-pass-NAME.txt)", "purpose": "Unlocks the repokey. Set only when the target uses <code>repokey</code> encryption. Never appears in the process argument list." },
|
||||
{ "var": "BORG_ENCRYPT_MODE", "value": "repokey | none", "purpose": "Used by <code>hb_borg_init_if_needed</code> when initialising a repository that does not yet exist. Ignored by <code>borg create</code> on existing repositories." },
|
||||
{ "var": "BORG_RELOCATED_REPO_ACCESS_IS_OK", "value": "yes", "purpose": "Suppresses the interactive prompt Borg raises when the repository URL differs from the URL it was originally reached from (common after a mount-point rename or SSH-host reachable via new address)." },
|
||||
{ "var": "BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK", "value": "yes", "purpose": "Suppresses the interactive prompt Borg raises the first time an unencrypted repository is accessed from a new client." }
|
||||
{
|
||||
"var": "BORG_RSH",
|
||||
"value": "ssh -i SSH_KEY_PATH -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new [-p PORT]",
|
||||
"purpose": "The remote-shell command Borg uses for SSH repositories. A selected key adds the identity options. When a target is first added with a non-default port, ProxMenux also appends -p PORT; saved targets, scheduled jobs and the Monitor rely on the port in the ssh:// URL instead. Without a custom key, and for a newly added target with the default port, the variable is unset so Borg uses the host’s default SSH configuration."
|
||||
},
|
||||
{
|
||||
"var": "BORG_PASSPHRASE",
|
||||
"value": "(passphrase from borg-pass-NAME.txt)",
|
||||
"purpose": "Unlocks the repokey. Set only when the target uses <code>repokey</code> encryption. Never appears in the process argument list."
|
||||
},
|
||||
{
|
||||
"var": "BORG_ENCRYPT_MODE",
|
||||
"value": "repokey | none",
|
||||
"purpose": "Used by <code>hb_borg_init_if_needed</code> when initialising a repository that does not yet exist. Ignored by <code>borg create</code> on existing repositories."
|
||||
},
|
||||
{
|
||||
"var": "BORG_RELOCATED_REPO_ACCESS_IS_OK",
|
||||
"value": "yes",
|
||||
"purpose": "Suppresses the interactive prompt Borg raises when the repository URL differs from the URL it was originally reached from (common after a mount-point rename or SSH-host reachable via new address)."
|
||||
},
|
||||
{
|
||||
"var": "BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK",
|
||||
"value": "yes",
|
||||
"purpose": "Suppresses the interactive prompt Borg raises the first time an unencrypted repository is accessed from a new client."
|
||||
}
|
||||
]
|
||||
},
|
||||
"archiveFormat": {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "Same payload, three backends",
|
||||
"body": "Every backup produces the same three payloads (rootfs, manifest, applications). What changes between destinations is how those payloads are stored and how the operator retrieves them for a restore. Each backend is implemented as a separate function in <code>backup_host.sh</code> — <code>_bk_local</code>, <code>_bk_pbs</code>, <code>_bk_borg</code> — but all four share the same staging step (<code>hb_prepare_staging</code>) and the same restore code path. The choice of destination only affects the write and the retrieval; it does not change what a restore does or how it consumes the archive."
|
||||
"body": "Every backup produces the same three payloads (rootfs, manifest, applications). What changes between destinations is how those payloads are stored and how the operator retrieves them for a restore. Each backend is implemented as a separate function in <code>backup_host.sh</code> — <code>_bk_local</code>, <code>_bk_pbs</code>, <code>_bk_borg</code> — but all three share the same staging step (<code>hb_prepare_staging</code>) and the same restore code path. The choice of destination only affects the write and the retrieval; it does not change what a restore does or how it consumes the archive."
|
||||
},
|
||||
"comparison": {
|
||||
"heading": "Feature comparison",
|
||||
@@ -29,8 +29,8 @@
|
||||
{
|
||||
"feature": "Compression",
|
||||
"local": "zstd (default level) via <code>tar --zstd</code>. gzip fallback.",
|
||||
"pbs": "PBS-managed. The client streams uncompressed; the server chunks + compresses.",
|
||||
"borg": "Borg's built-in (lz4 default). Configurable at repo init."
|
||||
"pbs": "Managed by proxmox-backup-client. ProxMenux does not override compression settings.",
|
||||
"borg": "Borg’s built-in compression. ProxMenux invokes borg create without overriding compression settings."
|
||||
},
|
||||
{
|
||||
"feature": "Deduplication",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
},
|
||||
"backupCommand": {
|
||||
"heading": "The backup command",
|
||||
"intro": "The upload is a single invocation of <code>proxmox-backup-client backup</code>. ProxMenux runs it inside an <code>env</code> wrapper so credentials never appear in the process argument list.",
|
||||
"intro": "The upload is a single invocation of <code>proxmox-backup-client backup</code>. ProxMenux uses <code>env</code> to pass the password, encryption password and fingerprint to the client as environment variables.",
|
||||
"cmd": "env \\\n PBS_PASSWORD=\"$HB_PBS_SECRET\" \\\n PBS_ENCRYPTION_PASSWORD=\"$HB_PBS_ENC_PASS\" \\\n PBS_FINGERPRINT=\"$HB_PBS_FINGERPRINT\" \\\n proxmox-backup-client backup \\\n hostcfg.pxar:$staging_root \\\n --repository USER@REALM@HOST:DATASTORE \\\n --backup-type host \\\n --backup-id hostcfg-HOSTNAME \\\n --backup-time BACKUP-EPOCH \\\n [--keyfile /usr/local/share/proxmenux/pbs-key.conf]",
|
||||
"backupIdTitle": "Backup ID naming",
|
||||
"backupIdBody": "The default backup ID is <code>hostcfg-HOSTNAME</code>. The operator is asked to confirm or edit it before the upload; any characters outside <code>[A-Za-z0-9_-]</code> are stripped and trailing dashes are trimmed. Reusing the same ID across runs is intentional — PBS treats the ID as a <em>group</em>, and every subsequent backup appears as a new backup inside that group, sharing dedup with prior runs.",
|
||||
@@ -61,13 +61,13 @@
|
||||
"modesSharedTitle": "Shared keyfile (import on every host)",
|
||||
"modesSharedBody": "One master keyfile generated once and installed on every host via the <em>Use an existing keyfile</em> option. Management is simpler: a single secret to safeguard, and any host can decrypt the archives of any other (useful for consolidation, cross-host restore drills or centralised backup verification). The trade-off is that a leak of the shared keyfile exposes every host at once. Recommended for homelabs and for fleets where all hosts have the same owner and trust boundary.",
|
||||
"recoveryTitle": "Upload key to PBS — the operator decides",
|
||||
"recoveryBody": "Right after the keyfile is chosen, ProxMenux asks a single explicit question — <em>Upload key to PBS?</em> — with two answers. <strong>Nothing gets uploaded to PBS until the operator answers Yes.</strong> The default is <em>No, keep local only</em>: the keyfile stays only at the canonical local path, ProxMenux never touches PBS with any recovery artefact, and the operator handles the offsite copy themselves (the Monitor's <em>Download keyfile</em> button in the PBS destination row provides one on demand). Choosing <em>Yes, upload</em> prompts for a recovery passphrase — twice, with match validation — and ProxMenux wraps the keyfile with that passphrase using AES-256-CBC and PBKDF2 (600 000 iterations, random salt) to produce <code>pbs-key.recovery.enc</code>. Every subsequent encrypted backup uploads that envelope to PBS as a paired backup group. Neither the passphrase nor a plaintext copy of the keyfile ever leaves the host. The choice can be changed later from the Monitor at any time — the escrow toggle inline in the PBS destination row flips Yes/No and applies immediately (Start uploading, Stop uploading, or Update passphrase, matching the current state).",
|
||||
"recoveryBody": "Right after the keyfile is chosen, ProxMenux asks a single explicit question — <em>Upload key to PBS?</em> — with two answers. <strong>No recovery artifact is uploaded to PBS until the operator answers Yes.</strong> The default is <em>No, keep local only</em>: the keyfile stays at the canonical local path, ProxMenux uploads no recovery artifact to PBS, and the operator handles the offsite copy themselves (the Monitor’s <em>Download keyfile</em> button in the PBS destination row provides one on demand). Choosing <em>Yes, upload</em> prompts for a recovery passphrase — twice, with match validation — and ProxMenux wraps the keyfile with that passphrase using AES-256-CBC and PBKDF2 (600 000 iterations, random salt) to produce <code>pbs-key.recovery.enc</code>. Every subsequent encrypted backup uploads that envelope to PBS as a paired backup group. Neither the passphrase nor a plaintext copy of the keyfile is sent to PBS during these uploads. The choice can be changed later from the Monitor at any time — the escrow toggle inline in the PBS destination row flips Yes/No and applies immediately (Start uploading, Stop uploading, or Update passphrase, matching the current state).",
|
||||
"blobUploadTitle": "Paired backup group on PBS",
|
||||
"blobUploadBody1": "When the escrow mode is <em>Yes, upload</em>, ProxMenux uploads the recovery envelope to PBS after every encrypted backup as a second, paired backup group with the same name as the host group but ending in <code>-keyrecovery</code>. The two groups sit next to each other in the datastore listing — one for host backups, one for recovery envelopes. <strong>The envelope never leaves the host in plaintext</strong>: encryption happens on the host itself with AES-256-CBC and PBKDF2 before any bytes go on the wire (<code>openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt</code>). PBS receives only the already-encrypted envelope.",
|
||||
"envelopeSecurityTitle": "Is uploading the keyrecovery file to PBS a security risk?",
|
||||
"envelopeSecurityBody": "The keyrecovery file is encrypted in transit and at rest. The recovery passphrase never leaves the host: encryption happens locally before the upload, and PBS only ever sees the already-encrypted result. A PBS administrator — or anyone with access to the datastore — can download the keyrecovery file, but without the recovery passphrase they cannot read the keyfile inside: it is opaque ciphertext. Reconstructing the keyfile requires both pieces at once, the keyrecovery file and the passphrase, and only the operator holds both.",
|
||||
"blobUploadConstraintTitle": "Why two groups instead of a single encrypted one",
|
||||
"blobUploadConstraintBody": "A single <code>proxmox-backup-client backup</code> invocation encrypts every one of its archives with the same keyfile, or none at all — there is no in-between. The host backup has to be encrypted with the host keyfile, but the recovery envelope cannot ride along in that same upload, because it would end up encrypted with the very keyfile it contains: on a freshly reinstalled host there would be no way to open it (you would need the keyfile to decrypt the keyfile). That is why the two artefacts are uploaded independently and appear as two separate groups: the host backup is encrypted by PBS with the keyfile, and the recovery envelope is encrypted by ProxMenux with the passphrase before upload. Two different encryption layers protecting two different assets.",
|
||||
"blobUploadConstraintBody": "A single <code>proxmox-backup-client backup</code> invocation encrypts every one of its archives with the same keyfile, or none at all — there is no in-between. The host backup has to be encrypted with the host keyfile, but the recovery envelope cannot ride along in that same upload, because it would end up encrypted with the very keyfile it contains: on a freshly reinstalled host there would be no way to open it (you would need the keyfile to decrypt the keyfile). That is why the two artefacts are uploaded independently and appear as two separate groups: the host backup is encrypted by the PBS client with the keyfile, and the recovery envelope is encrypted by ProxMenux with the passphrase before upload. Two different encryption layers protecting two different assets.",
|
||||
"blobUploadImageAlt": "PBS UI showing the hostcfg-HOSTNAME and hostcfg-HOSTNAME-keyrecovery backup groups adjacent in the datastore listing.",
|
||||
"blobUploadImageCaption": "PBS UI — the paired backup groups. The main group holds the host backups; the -keyrecovery group holds the passphrase-wrapped keyfile.",
|
||||
"recoverTitle": "Recovery on a fresh host",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"id": "clave-cifrado",
|
||||
"term": "Keyfile (encryption key)",
|
||||
"def": "Binary file that Proxmox Backup Server uses to encrypt the <a href=\"#chunk\">chunks</a> of each backup before uploading them. Without this file, no encrypted backup can be read. ProxMenux stores it at <code>/usr/local/share/proxmenux/pbs-key.conf</code> with mode <code>600</code>. This is the asset that has to be protected; the <a href=\"#sobre-recuperacion\">recovery envelope</a> exists precisely so that this file can be rescued if it is lost."
|
||||
"def": "Key file used by proxmox-backup-client to encrypt the <a href=\"#chunk\">chunks</a> before uploading them to PBS. Without the matching key, encrypted backup data cannot be read. ProxMenux stores the file at <code>/usr/local/share/proxmenux/pbs-key.conf</code> with mode <code>600</code>. Protect it: the <a href=\"#sobre-recuperacion\">recovery envelope</a> is designed to recover this file if it is lost."
|
||||
},
|
||||
{
|
||||
"id": "contrasena-keyfile",
|
||||
@@ -156,7 +156,7 @@
|
||||
{
|
||||
"id": "modo-adjunto",
|
||||
"term": "Attach mode",
|
||||
"def": "Scheduled job with no schedule of its own; it fires automatically whenever an existing PVE <code>vzdump</code> task runs. It inherits the schedule and retention from that parent task. Supported for Local and PBS destinations only."
|
||||
"def": "Job without its own timer. A PVE <code>vzdump</code> job-end hook triggers it after guest backups when the destination storage matches. The selected parent supplies the storage and the retention, which is re-read from the parent job on every run, but the hook matches storage rather than parent job ID; another task using that storage may also trigger it. Supported for Local and PBS only."
|
||||
},
|
||||
{
|
||||
"id": "timer-systemd",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "One archive, three payloads",
|
||||
"body": "Every backup produces a directory layout with three well-defined payloads under a single staging root. The archive uploaded to the destination (local <code>.tar.zst</code>, PBS backup or Borg archive) contains this exact layout. The restore reads the three payloads independently, in a specific order that guarantees correctness: <strong>rootfs</strong> is copied first to lay down configuration, <strong>the manifest</strong> is consulted to detect drift and decide what to skip, and <strong>the application inventory</strong> drives the post-boot reinstall pass. No cross-payload dependencies — each one can be inspected or extracted independently."
|
||||
"body": "Every backup produces a directory layout with three well-defined payloads under a single staging root. The archive uploaded to the destination (local <code>.tar.zst</code>, PBS backup or Borg archive) contains this exact layout. The restore uses all three: <strong>the manifest</strong> is consulted before applying changes to detect drift and decide what to skip; <strong>rootfs</strong> supplies the configuration files, applied live or deferred until reboot; and <strong>the application inventory</strong> drives package installation and the post-boot component reinstall. Each payload can be inspected or extracted independently."
|
||||
},
|
||||
"layout": {
|
||||
"heading": "Archive layout",
|
||||
@@ -26,7 +26,7 @@
|
||||
"heading": "The rootfs payload",
|
||||
"intro": "The <code>rootfs/</code> tree is a <strong>plain filesystem copy</strong> produced by <code>rsync</code> from the source host. It contains a curated <strong>default profile</strong> of paths that matter for a Proxmox restore, plus any <strong>custom paths</strong> added by the user to the backup job or interactive session. The set is deliberately narrow: only paths that either <em>hold configuration</em> or <em>hold state that Proxmox cannot regenerate on its own</em>.",
|
||||
"defaultProfileTitle": "The default profile",
|
||||
"defaultProfileBody": "The default profile is defined by <code>hb_default_profile_paths</code> in <code>lib_host_backup_common.sh</code>. It covers eight categories that together describe a working Proxmox host:",
|
||||
"defaultProfileBody": "The default profile is defined by <code>hb_default_profile_paths</code> in <code>lib_host_backup_common.sh</code>. It covers eight fixed categories, plus conditional ZFS state, that together describe a working Proxmox host:",
|
||||
"categoriesTitle": "Path categories",
|
||||
"categoryRows": [
|
||||
{
|
||||
@@ -125,7 +125,7 @@
|
||||
},
|
||||
"applications": {
|
||||
"heading": "The application inventory",
|
||||
"intro": "Two files under <code>metadata/</code> catalogue everything installed on the source that is not part of the base Proxmox VE package set. The restore uses them to reproduce the exact set of user-installed software on the target, using either APT or ProxMenux's own installers depending on how the software was originally installed.",
|
||||
"intro": "Two inventories catalogue the software installed on the source beyond the base Proxmox VE package set: the package list under <code>metadata/</code> and the component registry inside rootfs, detailed below. The restore uses them to reproduce user-installed software with APT or ProxMenux’s own installers, depending on how it was originally installed.",
|
||||
"packagesTitle": "packages.manual.list",
|
||||
"packagesBody": "A plain-text list produced by <code>apt-mark showmanual</code>: every APT package that was <em>explicitly installed</em> on the source host, sorted alphabetically. This excludes packages installed as dependencies of the base Proxmox VE ISO (they are re-pulled automatically by the target's own APT). Read by <code>_rs_run_complete_extras</code> during restore, filtered through a three-pass <em>cascade-safe</em> filter (<code>dpkg -s</code> for already-installed, sibling-major detection for library packages, <code>apt-get install --simulate</code> for cascade-remove risk), then installed with <code>apt-get install -y</code>.",
|
||||
"componentsTitle": "components_status.json (part of the rootfs)",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "The restore reproduces the source, not just the files",
|
||||
"body": "Restoring a ProxMenux backup is not an extraction. Files are only the first step: after the filesystem is in place, the restore reads the manifest to detect differences between source and target, filters paths that would break the target's boot, hydrates user-authored tuning that cannot be copied verbatim, and — after the mandatory reboot — reinstalls every component the source had (NVIDIA driver, Coral TPU, GPU tools) against the target's own kernel. What the user picks from the menu is a single archive; what actually happens involves the compatibility check, the path classification, the on-boot dispatcher and the post-boot pass working together to produce a host that behaves like the source."
|
||||
"body": "Restoring a ProxMenux backup involves more than extracting files. Before applying changes, the restore reads the manifest to detect differences between source and target, filters paths that could break the target’s boot and adapts user-authored tuning that cannot be copied verbatim. After the required reboot, it attempts to reinstall the recorded supported components (NVIDIA driver, Coral TPU, GPU tools) for the target’s running kernel. A single selected archive drives the compatibility check, path classification, on-boot dispatcher and post-boot work. Review the per-component results and logs to confirm the outcome."
|
||||
},
|
||||
"threeActions": {
|
||||
"heading": "Three actions on a backup",
|
||||
@@ -52,7 +52,7 @@
|
||||
},
|
||||
{
|
||||
"output": "Rollback plan",
|
||||
"detail": "Computed by <code>compute_rollback_plan.sh</code>. Lists VMs, LXCs and components present on the target but not in the backup. The user opts in during the confirmation dialog to have these removed as part of the restore, so the target ends up matching the backup exactly."
|
||||
"detail": "Computed by <code>compute_rollback_plan.sh</code>. Lists VMs, LXCs and components present on the target but absent from the backup. The confirmation dialog offers optional removal of the extra guests before reboot. Component removal remains manual, and guest deletion can fail, so this does not guarantee an exact match with the backup."
|
||||
}
|
||||
],
|
||||
"reportBody": "The check also emits a structured report (<code>HB_COMPAT_RESULTS</code>) categorised as PASS / INFO / WARN / FAIL. WARN and FAIL entries surface in the pre-restore panel; the restore refuses to proceed only when a FAIL is present that the user cannot resolve by clicking Continue."
|
||||
@@ -81,11 +81,11 @@
|
||||
},
|
||||
{
|
||||
"class": "reboot",
|
||||
"detail": "Paths applied <strong>immediately</strong> as well, but whose actual effect only kicks in on the <strong>next boot</strong>: the kernel only reads <code>/etc/default/grub</code> when the bootloader starts, <code>/etc/fstab</code> when filesystems are mounted at boot, <code>/etc/modules</code> when modules are loaded, etc. The file is in place the moment it is applied but the system has to reboot to consume it. Examples: <code>/etc/default/grub</code>, <code>/etc/kernel</code>, <code>/etc/modules</code>, <code>/etc/fstab</code>, <code>/etc/zfs</code>, <code>/etc/initramfs-tools</code>."
|
||||
"detail": "Paths deferred to the <strong>next boot</strong>, rather than applied <strong>immediately</strong> by this restore flow. They affect boot-time configuration: bootloader generation reads <code>/etc/default/grub</code>, filesystem mounting uses <code>/etc/fstab</code>, and module loading uses <code>/etc/modules</code>. The pending files are applied after reboot and the required boot artifacts are then regenerated. Examples: <code>/etc/default/grub</code>, <code>/etc/kernel</code>, <code>/etc/modules</code>, <code>/etc/fstab</code>, <code>/etc/zfs</code>, <code>/etc/modprobe.d</code>."
|
||||
},
|
||||
{
|
||||
"class": "dangerous",
|
||||
"detail": "Paths that are <strong>NOT applied on the running system</strong> — a live write could corrupt state or drop the active connection. These are staged in the pending set and written by the post-boot dispatcher after the reboot, when the cluster is up but the system is not yet fully in use. Examples: <code>/etc/pve</code> (pmxcfs is a live FUSE mount; writing directly to it bypasses it), <code>/var/lib/pve-cluster</code> (live cluster data), <code>/etc/network</code> (could reconfigure the very interface the user is connected on over SSH and drop the session)."
|
||||
"detail": "Paths that are <strong>NOT applied on the running system</strong> — a live write could corrupt state or drop the active connection. These are staged in the pending set: <code>/etc/network</code> is written early in the next boot, before networking starts, and <code>/etc/pve</code> is written by the post-boot dispatcher once the cluster filesystem is up. Examples: <code>/etc/pve</code> (pmxcfs is a live FUSE mount holding active cluster configuration), <code>/var/lib/pve-cluster</code> (live cluster data, kept in the recovery directory for manual recovery only), <code>/etc/network</code> (could reconfigure the very interface the user is connected on over SSH and drop the session)."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -131,7 +131,7 @@
|
||||
},
|
||||
{
|
||||
"task": "Component auto-reinstall",
|
||||
"detail": "Reads the restored <code>components_status.json</code> and iterates over the registered installers (nvidia_driver, coral_driver, amdgpu_top, intel_gpu_tools). Each installer runs in <code>--auto-reinstall</code> mode, reads its previously-recorded version from the state file, and rebuilds against the target's current kernel. The interactive flow does not do this — reinstalling drivers against a kernel that has not yet booted is meaningless."
|
||||
"detail": "Reads the restored <code>components_status.json</code> and iterates over the registered supported installers (nvidia_driver, coral_driver, amdgpu_top, intel_gpu_tools). Each selected installer runs in <code>--auto-reinstall</code> mode, reads its recorded state and reinstalls for the target’s environment, rebuilding kernel modules when applicable. This is deferred until after reboot so the installers use the kernel then running on the target. Individual failures are recorded and do not stop the next component."
|
||||
},
|
||||
{
|
||||
"task": "Boot sanity check",
|
||||
@@ -145,7 +145,7 @@
|
||||
},
|
||||
"liveProgress": {
|
||||
"heading": "Live progress in the Monitor's Backups tab",
|
||||
"body": "After the reboot the Backups tab of ProxMenux Monitor renders a live post-restore card that reflects the state of <code>apply_cluster_postboot.service</code> as it runs. The card is driven by <code>/var/lib/proxmenux/restore-state.json</code>, which the dispatcher updates at every milestone (apply cluster config, rebuild initramfs, update bootloader, per-component reinstall, boot sanity check, finalize).",
|
||||
"body": "After the reboot the Backups tab of ProxMenux Monitor renders a live post-restore card that reflects the state of <code>proxmenux-apply-cluster-postboot.service</code> as it runs. The card is driven by <code>/var/lib/proxmenux/restore-state.json</code>, which the dispatcher updates at every milestone (apply cluster config, rebuild initramfs, update bootloader, per-component reinstall, boot sanity check, finalize).",
|
||||
"fields": [
|
||||
{
|
||||
"name": "Status badge",
|
||||
@@ -184,9 +184,9 @@
|
||||
},
|
||||
"postbootExample": {
|
||||
"heading": "What the post-boot looks like on the console",
|
||||
"body": "On the host's physical console, a successful dispatcher run ends with a <code>[ OK ] Finished proxmenux-apply-cluster-postboot.service</code> line. When that line appears — usually alongside the <code>OK</code>s for <code>multi-user.target</code> and <code>graphical.target</code> — the restore is completely finished: components reinstalled, boot artifacts regenerated, cluster reconciled.",
|
||||
"body": "On the host’s physical console, a dispatcher run that exits successfully ends with <code>[ OK ] Finished proxmenux-apply-cluster-postboot.service</code>, often near the <code>OK</code>s for <code>multi-user.target</code> and <code>graphical.target</code>. This marks the end of the dispatcher process. Individual component failures or boot warnings can still have been recorded; check the Monitor’s component states and logs before treating the host as fully restored.",
|
||||
"imageAlt": "Proxmox physical console showing '[ OK ] Finished proxmenux-apply-cluster-postboot.service - ProxMenux Apply Cluster Configs (post-boot).' followed by the OK for multi-user.target and graphical.target, with the host login prompt above.",
|
||||
"imageCaption": "Physical console after a successful post-boot. The 'Finished proxmenux-apply-cluster-postboot.service' line is the signal that the restore flow is fully complete — the same event the 'Host restore finished' notification surfaces in the Monitor."
|
||||
"imageCaption": "Physical console after the dispatcher process finishes. 'Finished proxmenux-apply-cluster-postboot.service' marks process completion, also reported by 'Host restore finished' in the Monitor. Component results and warnings still need review."
|
||||
},
|
||||
"tenMinutes": {
|
||||
"heading": "Why the last ten minutes matter",
|
||||
@@ -228,11 +228,11 @@
|
||||
"detail": "Cheap. The user learns the run completed the moment the notification fires."
|
||||
}
|
||||
],
|
||||
"outroBody": "The window matters because the user can log in during this time and see missing tools (<code>nvidia-smi</code> not found, <code>coral</code> not detected). This is expected — the reinstall is still running in the background. The completion notification signals when everything is ready."
|
||||
"outroBody": "During this window a login may show missing tools (<code>nvidia-smi</code> not found, <code>coral</code> not detected) because reinstall work is still running in the background. The completion notification marks the end of that work; check component results, warnings and logs to distinguish success from individual failures."
|
||||
},
|
||||
"destructiveRollback": {
|
||||
"heading": "The optional destructive rollback",
|
||||
"body": "A restore is additive by default: if the target has VMs, LXCs or components that are not in the backup, they survive. This preserves work but can leave stale hostpci entries, orphan components or VMs the user no longer wants. When drift is detected between target and backup, the confirmation dialog offers a second yes/no: <em>Execute destructive rollback?</em>. Accepting it triggers <code>_rs_execute_rollback</code>, which deletes the VMs, LXCs and components that exist on the target but not in the backup. The rollback runs BEFORE the reboot so that the pending restore machinery sees a clean state. This is opt-in — the default is No, and the user sees exactly what would be removed listed by name (VMID and CTID) before deciding."
|
||||
"body": "A restore is additive by default: extra VMs, LXCs and components on the target remain. When differences are detected, the confirmation dialog offers <em>Execute destructive rollback?</em>, defaulting to No. Accepting calls <code>_rs_execute_rollback</code> before reboot to attempt deletion of listed extra VMs and LXCs. Components are flagged for manual uninstall because automatic uninstall is not implemented. Guest deletion failures are reported and processing continues, so an exact match with the backup is not guaranteed. Review the listed names and VMIDs/CTIDs before choosing this destructive option."
|
||||
},
|
||||
"logs": {
|
||||
"heading": "Where the logs live",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"attachBadge": {
|
||||
"title": "Attach mode — recommended when a PVE vzdump task already exists",
|
||||
"body": "When a PVE vzdump backup task is already configured for the VMs and LXCs on this node, attaching the host backup to that task guarantees the host configuration is captured in the <strong>same window</strong> as the guests. On restore, the guest configs come from the host backup (they live under <code>/etc/pve</code>), and the guest disks come from the vzdump backup taken alongside — both sets are consistent with each other, so a full-node recovery can reproduce the host and re-attach every guest without version drift."
|
||||
"body": "When a PVE vzdump backup task is already configured for the VMs and LXCs on this node, attaching the host backup runs it after the guest backup job, in the <strong>same backup cycle</strong>. On restore, guest configurations come from the host backup (under <code>/etc/pve</code>) and guest disks come from the vzdump backups taken in that cycle. This helps coordinate a full-node recovery, but is not an atomic snapshot: changes made during the backup cycle can leave differences between host configuration and guest disk state."
|
||||
},
|
||||
"frequencyBadge": {
|
||||
"title": "Recommended frequency",
|
||||
@@ -31,29 +31,63 @@
|
||||
"modes": {
|
||||
"heading": "The two modes",
|
||||
"rows": [
|
||||
{ "mode": "New scheduled job", "backends": "Local, PBS, Borg", "schedule": "Own <code>OnCalendar</code> expression (systemd calendar syntax — e.g. <code>daily</code>, <code>Mon..Fri 03:00</code>).", "retention": "Prompted separately: <code>keep-last</code>, <code>keep-hourly</code>, <code>keep-daily</code>, <code>keep-weekly</code>, <code>keep-monthly</code>, <code>keep-yearly</code>. Applied by the runner after each successful backup." },
|
||||
{ "mode": "Attach to a PVE vzdump job", "backends": "Local, PBS (Borg has no PVE-side scheduler)", "schedule": "Inherited from the parent PVE job. No systemd timer is installed on the ProxMenux side.", "retention": "Inherited from the parent's <code>prune-backups</code> configuration (mapped one-to-one to the runner's <code>KEEP_*</code> variables via <code>hb_pve_prune_to_keep_env</code>)." }
|
||||
{
|
||||
"mode": "New scheduled job",
|
||||
"backends": "Local, PBS, Borg",
|
||||
"schedule": "Own <code>OnCalendar</code> expression (systemd calendar syntax — e.g. <code>daily</code>, <code>Mon..Fri 03:00</code>).",
|
||||
"retention": "Prompted separately: <code>keep-last</code>, <code>keep-hourly</code>, <code>keep-daily</code>, <code>keep-weekly</code>, <code>keep-monthly</code>, <code>keep-yearly</code>. Applied by the runner after each successful backup."
|
||||
},
|
||||
{
|
||||
"mode": "Attach to a PVE vzdump job",
|
||||
"backends": "Local, PBS (Borg has no PVE-side scheduler)",
|
||||
"schedule": "Inherited from the parent PVE job. No systemd timer is installed on the ProxMenux side.",
|
||||
"retention": "Inherited from the parent's <code>prune-backups</code> configuration (mapped one-to-one to the runner's <code>KEEP_*</code> variables via <code>hb_pve_prune_to_keep_env</code>)."
|
||||
}
|
||||
]
|
||||
},
|
||||
"attachDetail": {
|
||||
"heading": "How attach mode works",
|
||||
"intro": "PVE writes <code>vzdump</code> tasks to <code>/etc/pve/jobs.cfg</code> — one stanza per task, each pointing at a storage where the VM and LXC dumps land. Attach mode requires that storage to be a backend ProxMenux understands (Local or PBS); when the task fires, ProxMenux runs alongside it.",
|
||||
"intro": "PVE writes <code>vzdump</code> tasks to <code>/etc/pve/jobs.cfg</code> — one stanza per task, each pointing at a storage where the VM and LXC dumps land. Attach mode requires a backend ProxMenux understands (Local or PBS). The host backup runs from the job-end hook after the guest backup job finishes.",
|
||||
"steps": [
|
||||
{ "step": "1", "detail": "During job creation, ProxMenux lists compatible parent PVE tasks via <code>hb_pve_list_vzdump_jobs_for_backend</code>. The user picks one." },
|
||||
{ "step": "2", "detail": "The job's <code>.env</code> is written with <code>PVE_PARENT_JOB</code>, <code>PVE_STORAGE</code> and the inherited <code>KEEP_*</code> values; no systemd timer is created." },
|
||||
{ "step": "3", "detail": "<code>hb_install_vzdump_hook</code> registers a script-hook in <code>/etc/vzdump.conf</code>. When PVE runs any vzdump task, the hook script fires; if the <code>$STOREID</code> passed to it matches an attached job's <code>PVE_STORAGE</code>, the runner is invoked for that job." },
|
||||
{ "step": "4", "detail": "The archive lands in the same storage the vzdump dumps just wrote to: <code>path/dump/</code> for Local, or the PBS repository configured on the PVE storage entry." }
|
||||
{
|
||||
"step": "1",
|
||||
"detail": "During job creation, ProxMenux lists compatible parent PVE tasks via <code>hb_pve_list_vzdump_jobs_for_backend</code>. The user picks one."
|
||||
},
|
||||
{
|
||||
"step": "2",
|
||||
"detail": "The job's <code>.env</code> is written with <code>PVE_PARENT_JOB</code>, <code>PVE_STORAGE</code> and the inherited <code>KEEP_*</code> values; no systemd timer is created."
|
||||
},
|
||||
{
|
||||
"step": "3",
|
||||
"detail": "<code>hb_install_vzdump_hook</code> registers a script-hook in <code>/etc/vzdump.conf</code>. In the job-end phase of any vzdump task, it compares the supplied <code>$STOREID</code> with each enabled attached job’s <code>PVE_STORAGE</code> and invokes the runner for matching jobs. The match is by storage, not by the selected parent job ID."
|
||||
},
|
||||
{
|
||||
"step": "4",
|
||||
"detail": "The archive lands in the same storage the vzdump dumps just wrote to: <code>path/dump/</code> for Local, or the PBS repository configured on the PVE storage entry."
|
||||
}
|
||||
],
|
||||
"outroBody": "Attach mode has one operational implication: disabling or deleting the parent PVE task also disables the host backup — there is no timer of its own to fall back on. The job entry stays on disk so it can be re-attached later."
|
||||
"outroBody": "Attach mode has no timer of its own. Disabling or deleting the selected parent PVE task stops that task’s trigger, but another vzdump task using the same storage can still trigger the attached host backup. Disable or delete the ProxMenux job itself to prevent that. The job entry remains on disk when disabled and can be re-enabled or re-attached later."
|
||||
},
|
||||
"storageLayout": {
|
||||
"heading": "Files that make up a job",
|
||||
"intro": "Every scheduled job is fully described by three or four files on disk. Reading them gives the full configuration of the job without relying on the interface.",
|
||||
"rows": [
|
||||
{ "path": "/var/lib/proxmenux/backup-jobs/JOB_ID.env", "content": "Backend, backup ID or destination, schedule (New mode) or PVE parent (Attach mode), enabled flag, retention <code>KEEP_*</code> values, credentials pointers." },
|
||||
{ "path": "/var/lib/proxmenux/backup-jobs/JOB_ID.paths", "content": "One absolute path per line — the frozen selection resolved from the profile at job-creation time. Editing the file re-runs the job with the new selection on the next timer fire." },
|
||||
{ "path": "/etc/systemd/system/proxmenux-backup-JOB_ID.timer + .service", "content": "New mode only. The service invokes <code>run_scheduled_backup.sh JOB_ID</code>. The timer schedules it with <code>Persistent=true</code> (missed fires run at next boot) and a small <code>RandomizedDelaySec=120</code> to spread load when multiple jobs share the same OnCalendar expression." },
|
||||
{ "path": "/etc/vzdump.conf script-hook", "content": "Attach mode only. Installed once by <code>hb_install_vzdump_hook</code>; matches every attached job's <code>PVE_STORAGE</code> against the <code>$STOREID</code> PVE passes to the hook script." }
|
||||
{
|
||||
"path": "/var/lib/proxmenux/backup-jobs/JOB_ID.env",
|
||||
"content": "Backend, backup ID or destination, schedule (New mode) or PVE parent (Attach mode), enabled flag, retention <code>KEEP_*</code> values, credentials pointers."
|
||||
},
|
||||
{
|
||||
"path": "/var/lib/proxmenux/backup-jobs/JOB_ID.paths",
|
||||
"content": "One absolute path per line — the frozen selection resolved from the profile at job-creation time. Editing the file re-runs the job with the new selection on the next timer fire."
|
||||
},
|
||||
{
|
||||
"path": "/etc/systemd/system/proxmenux-backup-JOB_ID.timer + .service",
|
||||
"content": "New mode only. The service invokes <code>run_scheduled_backup.sh JOB_ID</code>. The timer schedules it with <code>Persistent=true</code> (missed fires run at next boot) and a small <code>RandomizedDelaySec=120</code> to spread load when multiple jobs share the same OnCalendar expression."
|
||||
},
|
||||
{
|
||||
"path": "/etc/vzdump.conf script-hook",
|
||||
"content": "Attach mode only. Installed once by <code>hb_install_vzdump_hook</code>; matches every attached job's <code>PVE_STORAGE</code> against the <code>$STOREID</code> PVE passes to the hook script."
|
||||
}
|
||||
]
|
||||
},
|
||||
"runner": {
|
||||
@@ -69,11 +103,26 @@
|
||||
"heading": "Managing jobs",
|
||||
"intro": "The scheduler menu (Scripts TUI) and the Monitor Backups tab expose the same actions on any job.",
|
||||
"rows": [
|
||||
{ "action": "Run now", "detail": "Invokes the runner immediately, bypassing the timer / vzdump hook. Useful to verify a job configuration without waiting for the next scheduled fire." },
|
||||
{ "action": "Enable / Disable", "detail": "New mode: <code>systemctl enable/disable --now</code> the timer. Attach mode: flips the <code>ENABLED</code> flag in the job env — the hook script honours it on the next PVE fire." },
|
||||
{ "action": "Edit", "detail": "Reopens the destination, schedule, profile and retention prompts and rewrites the job files. Preserves the job ID." },
|
||||
{ "action": "Delete", "detail": "Removes the job env, paths file, systemd timer + service (New mode), and disables the hook binding (Attach mode). Does not touch archives already on the destination." },
|
||||
{ "action": "View log", "detail": "Streams <code>/var/log/proxmenux/backup-jobs/JOB_ID-YYYYMMDD_HHMMSS.log</code> — one log file per run. The runner also emits a compact status line to journald under the systemd service." }
|
||||
{
|
||||
"action": "Run now",
|
||||
"detail": "Invokes the runner immediately, bypassing the timer / vzdump hook. Useful to verify a job configuration without waiting for the next scheduled fire."
|
||||
},
|
||||
{
|
||||
"action": "Enable / Disable",
|
||||
"detail": "New mode: <code>systemctl enable/disable --now</code> the timer. Attach mode: flips the <code>ENABLED</code> flag in the job env — the hook script honours it on the next PVE fire."
|
||||
},
|
||||
{
|
||||
"action": "Edit",
|
||||
"detail": "Reopens the destination, schedule, profile and retention prompts and rewrites the job files. Preserves the job ID."
|
||||
},
|
||||
{
|
||||
"action": "Delete",
|
||||
"detail": "Removes the job env, paths file, systemd timer + service (New mode), and disables the hook binding (Attach mode). Does not touch archives already on the destination."
|
||||
},
|
||||
{
|
||||
"action": "View log",
|
||||
"detail": "Streams <code>/var/log/proxmenux/backup-jobs/JOB_ID-YYYYMMDD_HHMMSS.log</code> — one log file per run. The runner also emits a compact status line to journald under the systemd service."
|
||||
}
|
||||
]
|
||||
},
|
||||
"notifications": {
|
||||
@@ -83,9 +132,21 @@
|
||||
"whereNext": {
|
||||
"heading": "Where to go next",
|
||||
"items": [
|
||||
{ "label": "Creating backups", "href": "/docs/backup-restore/creating-backups", "tail": " — the interactive flow that shares the backend with the scheduler." },
|
||||
{ "label": "Destinations", "href": "/docs/backup-restore/destinations", "tail": " — per-backend configuration used by both the interactive flow and the scheduler." },
|
||||
{ "label": "Restoring", "href": "/docs/backup-restore/restoring", "tail": " — the flow that consumes what jobs produce." }
|
||||
{
|
||||
"label": "Creating backups",
|
||||
"href": "/docs/backup-restore/creating-backups",
|
||||
"tail": " — the interactive flow that shares the backend with the scheduler."
|
||||
},
|
||||
{
|
||||
"label": "Destinations",
|
||||
"href": "/docs/backup-restore/destinations",
|
||||
"tail": " — per-backend configuration used by both the interactive flow and the scheduler."
|
||||
},
|
||||
{
|
||||
"label": "Restoring",
|
||||
"href": "/docs/backup-restore/restoring",
|
||||
"tail": " — the flow that consumes what jobs produce."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Create VMs on Proxmox VE — Synology, Windows, Linux, NAS Wizards | ProxMenux",
|
||||
"description": "Create and configure virtual machines on Proxmox VE with ProxMenux. Dedicated wizards for NAS appliances (Synology DSM, TrueNAS, OpenMediaVault, UnRAID, etc.), Windows, Linux distros, and an external macOS installer. Sensible defaults for VM hardware, storage and networking.",
|
||||
"description": "Create and configure virtual machines on Proxmox VE with ProxMenux. Dedicated wizards for NAS appliances (Synology DSM, TrueNAS, OpenMediaVault, XigmaNAS, etc.), Windows, Linux distros, and an external macOS installer. Sensible defaults for VM hardware, storage and networking.",
|
||||
"ogTitle": "Create VMs on Proxmox VE — Synology, Windows, Linux, NAS Wizards",
|
||||
"ogDescription": "ProxMenux wizards for creating Synology DSM, TrueNAS, OMV, UnRAID, Windows and Linux VMs on Proxmox VE.",
|
||||
"ogDescription": "ProxMenux wizards for creating Synology DSM, TrueNAS, OMV, XigmaNAS, Windows and Linux VMs on Proxmox VE.",
|
||||
"ogImageAlt": "ProxMenux Create VM Menu",
|
||||
"twitterTitle": "Create VMs on Proxmox VE | ProxMenux",
|
||||
"twitterDescription": "Wizards for Synology, TrueNAS, OMV, UnRAID, Windows and Linux VMs on Proxmox VE."
|
||||
"twitterDescription": "Wizards for Synology, TrueNAS, OMV, XigmaNAS, Windows and Linux VMs on Proxmox VE."
|
||||
},
|
||||
"header": {
|
||||
"title": "Create VM",
|
||||
@@ -33,13 +33,13 @@
|
||||
"href": "/docs/create-vm/system-nas",
|
||||
"accent": "border-emerald-300 bg-emerald-50",
|
||||
"iconBg": "bg-emerald-100 text-emerald-700",
|
||||
"description": "Seven NAS operating systems as dedicated VMs. Most use the auto-ISO flow; Synology DSM runs the specialised loader wizard.",
|
||||
"description": "Eight NAS operating systems as dedicated VMs. Most use the auto-ISO flow; Synology DSM runs the specialised loader wizard.",
|
||||
"bullets": [
|
||||
"Synology DSM (ARC / RR / TinyCore loaders)",
|
||||
"Synology DSM (Arc / RR / Alpine RedPill M-shell loaders)",
|
||||
"TrueNAS SCALE and CORE (ZFS)",
|
||||
"OpenMediaVault (Debian-based)",
|
||||
"XigmaNAS (FreeBSD ZFS)",
|
||||
"Rockstor (openSUSE / Btrfs), ZimaOS"
|
||||
"Rockstor (openSUSE / Btrfs), ZimaOS, FygoOS"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -106,7 +106,7 @@
|
||||
},
|
||||
{
|
||||
"path": "vm/select_nas_iso.sh",
|
||||
"role": "ISO / appliance selector for NAS systems (Synology, TrueNAS, OMV, Rockstor, ZimaOS)."
|
||||
"role": "ISO / appliance selector for NAS systems (Synology, TrueNAS, OMV, Rockstor, XigmaNAS, ZimaOS, FygoOS)."
|
||||
},
|
||||
{
|
||||
"path": "vm/select_windows_iso.sh",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"extra": ""
|
||||
},
|
||||
{
|
||||
"name": "TinyCore RedPill M-shell",
|
||||
"name": "Alpine RedPill M-shell (TinyCore project)",
|
||||
"url": "https://github.com/PeterSuh-Q3/tinycore-redpill",
|
||||
"extra": ""
|
||||
}
|
||||
@@ -115,24 +115,24 @@
|
||||
},
|
||||
"diskSelection": {
|
||||
"heading": "Disk Selection",
|
||||
"intro": "Once the machine is configured, the script allows you to choose between two types of disks:",
|
||||
"intro": "The storage plan lets you add virtual disks, physical disks, and PCI controllers or NVMe devices. The disk options are explained below.",
|
||||
"virtualHeading": "Virtual Disk",
|
||||
"virtualItems": [
|
||||
"The script lists the storage options available in Proxmox",
|
||||
"The user selects the disk and size in GB",
|
||||
"The virtual disk is automatically assigned to the VM. If more disks are configured, they will be added as <strong>SATA</strong> (e.g., sata0, sata1, etc.), up to a maximum of 6 virtual disks."
|
||||
"Virtual disks are attached as <strong>SATA</strong> (sata0, sata1, etc.). Virtual and physical data disks share the six SATA slots numbered 0–5; the loader uses a separate IDE slot."
|
||||
],
|
||||
"physicalHeading": "Physical Disk Passthrough",
|
||||
"physicalItems": [
|
||||
"The script detects all available physical disks",
|
||||
"The user selects the physical disk or disks they want to use.",
|
||||
"The physical disk is directly assigned to the VM via passthrough. If more disks are configured, they will be added as <strong>SATA</strong> (e.g., sata0, sata1, etc.), up to a maximum of 6 physical disks."
|
||||
"Physical disks are attached as <strong>SATA</strong> devices. They share the six SATA slots numbered 0–5 with virtual data disks; this is not a separate allowance of six physical disks."
|
||||
]
|
||||
},
|
||||
"loaderInstall": {
|
||||
"heading": "Loader Installation",
|
||||
"intro1": "The script automatically downloads and extracts the loader from the developer's repository. If the download fails, the script will display an error message.",
|
||||
"intro2Rich": "<strong>AuxXxilium Arc</strong>, <strong>RedPill RR</strong>, and <strong>TinyCore RedPill M-shell</strong>. Downloads and extracts automatically.",
|
||||
"intro2Rich": "<strong>AuxXxilium Arc</strong>, <strong>RedPill RR</strong>, and <strong>Alpine RedPill M-shell</strong> are downloaded and extracted automatically.",
|
||||
"customRich": "For <strong>Custom Loader</strong>, the script searches for files in <code>/var/lib/vz/template/iso</code>. If multiple files are found, you will be prompted to select the desired file.",
|
||||
"uploadIntro": "You can upload custom loaders from the local storage options:",
|
||||
"imageAlt": "Add Custom Loader",
|
||||
@@ -143,14 +143,14 @@
|
||||
"intro": "Once the loader is downloaded, the script creates the VM using the following commands:",
|
||||
"items": [
|
||||
"<code>qm create</code> – Creates the virtual machine with the configured parameters",
|
||||
"<code>qm importdisk</code> – Imports the boot loader disk to the VM. For greater compatibility the loader is imported as an IDE disk",
|
||||
"<code>qm importdisk</code> imports the loader image to Proxmox storage. The script then attaches that image to the VM as ide0 for compatibility.",
|
||||
"<code>qm set</code> – Assigns configuration values such as CPU, RAM, and storage",
|
||||
"<code>qm set -boot</code> – Configures the boot order"
|
||||
"<code>qm set VMID --boot order=ide0</code> configures the loader as the boot device. Replace VMID with the VM ID."
|
||||
]
|
||||
},
|
||||
"stepGuide": {
|
||||
"heading": "Step-by-Step Boot Loader Configuration Guide",
|
||||
"intro": "While all loaders share similarities, each one has its own structure and configuration methods. This section provides a basic guide covering the 6 steps involved in setting up a Synology DSM loader. The exact steps may vary depending on the loader and any changes introduced by the developer. Therefore, understanding these common basic steps is crucial to correctly building and configuring the loader of your choice for proper Synology DSM functionality.",
|
||||
"intro": "Each loader has its own menus and configuration methods. The six steps below explain the common process; follow the current loader’s prompts when they differ. The M-shell screenshots show an earlier TinyCore interface, while the current script downloads Alpine RedPill M-shell.",
|
||||
"selectorHeading": "Select your loader type:",
|
||||
"loaderButtons": {
|
||||
"arc": "Arc Loader",
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
},
|
||||
{
|
||||
"param": "CPU type",
|
||||
"options": "Host or KVM64"
|
||||
"options": "Host, KVM64 and other listed CPU models"
|
||||
},
|
||||
{
|
||||
"param": "Cores",
|
||||
@@ -108,19 +108,19 @@
|
||||
"virtualDiskItems": [
|
||||
"Lists the Proxmox storage volumes available on the host.",
|
||||
"You pick the target storage and the size in GB.",
|
||||
"The disk is attached to the VM as SATA (<code>sata0</code>, <code>sata1</code>, … up to 6)."
|
||||
"The disk uses the selected bus: SCSI (default), SATA, VirtIO or IDE. SATA slots are <code>sata0</code>, <code>sata1</code>, …, with six slots numbered 0–5."
|
||||
],
|
||||
"importDiskTitle": "b. Add import disk",
|
||||
"importDiskItems": [
|
||||
"Detects physical disks that are safe to import (system and protected disks are hidden).",
|
||||
"You select one or more disks via a checklist.",
|
||||
"Imported disks are attached as SATA via <code>qm set</code>."
|
||||
"Imported disks use the selected bus and are attached via <code>qm set</code>."
|
||||
],
|
||||
"pciTitle": "c. Add Controller or NVMe (PCI passthrough)",
|
||||
"pciItems": [
|
||||
"Detects SATA/SAS HBAs and NVMe devices on the host and lets you pass an <em>entire controller</em> into the VM. IOMMU must be enabled; the script offers to enable it and reboots if required.",
|
||||
"A confirmation step warns about controller-wide risk (the whole card, including every disk on it, leaves the host).",
|
||||
"The selected PCI devices are attached via <code>qm set hostpciN: …</code>."
|
||||
"The selected PCI devices are attached with commands such as <code>qm set VMID --hostpci0 PCI_ADDRESS,pcie=1</code>. Replace VMID and PCI_ADDRESS with the VM ID and PCI address, and use an unused hostpci index for each device."
|
||||
],
|
||||
"resetTitle": "Reset and finish",
|
||||
"resetBody": "The menu also offers <strong>r</strong> (reset the current selection and start over) and <strong>d</strong> (finish and continue). You cannot finish with an empty plan."
|
||||
@@ -241,15 +241,15 @@
|
||||
"postInstall": {
|
||||
"heading": "Post-install tips",
|
||||
"guestAgentHeading": "Install the QEMU Guest Agent inside the VM",
|
||||
"guestAgentBody": "ProxMenux enables the guest agent channel in the VM config, but the agent itself has to be installed inside the guest. It enables graceful shutdown, filesystem freeze for consistent snapshots and accurate memory reporting in the Proxmox UI.",
|
||||
"guestAgentBody": "ProxMenux enables the guest agent channel in the VM config, but the agent itself has to be installed inside the guest. It supports controlled shutdown and filesystem freezing during backups to improve data consistency.",
|
||||
"debian": "Debian / Ubuntu",
|
||||
"fedora": "Fedora / Rocky / RHEL",
|
||||
"arch": "Arch Linux",
|
||||
"opensuse": "openSUSE",
|
||||
"virtioHeading": "VirtIO support in Linux",
|
||||
"virtioBody": "Modern Linux kernels (2.6.25+) include VirtIO disk and network drivers out of the box, so you can switch the disk interface to <code>virtio</code> or <code>virtio-scsi</code> in the Advanced wizard and the network adapter to <code>virtio</code> without any extra driver step.",
|
||||
"virtioBody": "Modern Linux distributions normally include VirtIO disk and network drivers. Select <code>virtio</code> for VirtIO block disks, or <code>scsi</code> with the configured VirtIO SCSI controller; the network adapter also uses <code>virtio</code>. Check driver support with older installers.",
|
||||
"virtioWarnTitle": "Very old distributions",
|
||||
"virtioWarnBody": "If you are installing something predating the 2.6.25 kernel, VirtIO modules may not be available at install time. In that case keep SATA / SCSI or provide a driver disk.",
|
||||
"virtioWarnBody": "Very old installers may lack the required VirtIO drivers. In that case use an emulated SATA / SCSI controller or supply suitable drivers.",
|
||||
"trimHeading": "Enable TRIM / discard on SSD-backed storage",
|
||||
"trimBody": "When the VM sits on SSD-backed Proxmox storage and the disk was attached with the <code>discard</code> flag, you can forward trim commands from inside the guest. Two options:",
|
||||
"trimItems": [
|
||||
@@ -257,7 +257,7 @@
|
||||
"Or mount filesystems with the <code>discard</code> option in <code>/etc/fstab</code>."
|
||||
],
|
||||
"balloonHeading": "Memory ballooning",
|
||||
"balloonBody": "The <code>virtio_balloon</code> driver ships with modern Linux kernels. Proxmox uses it to reclaim unused memory from the VM and show accurate utilisation in the UI — no guest-side configuration required."
|
||||
"balloonBody": "Modern Linux kernels normally include the <code>virtio_balloon</code> driver. With a balloon device enabled, Proxmox can collect memory statistics. Dynamic memory reclamation also requires a minimum memory setting below the configured maximum; equal values keep memory allocation fixed."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "How the NAS selector works",
|
||||
"body": "The NAS selector detects the latest stable release of each appliance (querying its upstream mirror), downloads the ISO — or builds the VM from a pre-packaged image — and then hands over to the generic ProxMenux VM wizard for CPU, RAM, disk and network configuration."
|
||||
"body": "For the generic ISO flow, the NAS selector tries to detect the latest stable release from the project’s mirror, uses a fallback version if needed, downloads the ISO and opens the shared VM configurator for CPU, RAM, disks and networking. Synology DSM and ZimaOS use dedicated installer flows."
|
||||
},
|
||||
"image": {
|
||||
"alt": "ProxMenux System NAS selector",
|
||||
@@ -43,7 +43,7 @@
|
||||
},
|
||||
{
|
||||
"name": "TrueNAS SCALE",
|
||||
"tagline": "Debian-based TrueNAS with Docker / Kubernetes apps and ZFS as primary filesystem.",
|
||||
"tagline": "Debian-based TrueNAS with Docker apps in current releases and ZFS as the primary filesystem. Kubernetes was used by older SCALE releases.",
|
||||
"icon": "Database",
|
||||
"base": "Debian Linux",
|
||||
"fileSystem": "ZFS",
|
||||
@@ -52,7 +52,7 @@
|
||||
},
|
||||
{
|
||||
"name": "TrueNAS CORE",
|
||||
"tagline": "FreeBSD-based TrueNAS. Enterprise-grade ZFS storage with jails and plugins.",
|
||||
"tagline": "FreeBSD-based TrueNAS focused on ZFS storage. Jails and plugins in CORE 13.3 are obsolete and unsupported.",
|
||||
"icon": "Database",
|
||||
"base": "FreeBSD",
|
||||
"fileSystem": "ZFS",
|
||||
@@ -90,7 +90,7 @@
|
||||
"name": "ZimaOS",
|
||||
"tagline": "Lightweight NAS OS focused on media, Docker apps and home automation. Uses its own installer.",
|
||||
"icon": "MonitorIcon",
|
||||
"base": "Debian / CasaOS",
|
||||
"base": "Buildroot (evolved from CasaOS)",
|
||||
"fileSystem": "ext4",
|
||||
"href": "/docs/create-vm/system-nas/system-nas-others#zimaos",
|
||||
"flow": "dedicated"
|
||||
@@ -112,7 +112,7 @@
|
||||
},
|
||||
"zfsMem": {
|
||||
"title": "ZFS memory rule of thumb",
|
||||
"bodyRich": "If you pick a ZFS-based NAS (TrueNAS, XigmaNAS), allocate at least <strong>8 GB RAM</strong> to the VM — ZFS uses free memory as ARC cache and performance degrades noticeably below that. Rockstor (Btrfs) and OMV (ext4) are far less memory-hungry."
|
||||
"bodyRich": "For TrueNAS, allocate at least <strong>8 GB RAM</strong> for basic operation and more for demanding workloads. ZFS uses RAM for its ARC cache, but there is no universal 8 GB performance cliff for every ZFS-based NAS. Check the chosen distribution’s requirements and size memory for its disks, services and apps; lighter OMV or Rockstor setups can need less."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Create VM: Synology DSM | ProxMenux Documentation",
|
||||
"description": "Create a Synology DSM virtual machine on Proxmox VE. ProxMenux downloads the loader of your choice (Arc, RR, TinyCore M-shell or a custom one), imports it as the VM's boot disk and prepares CPU, RAM and storage through the default or advanced wizard.",
|
||||
"description": "Create a Synology DSM virtual machine on Proxmox VE. ProxMenux downloads your chosen loader (Arc, RR, Alpine RedPill M-shell or a custom image), imports it as the VM boot disk and configures CPU, RAM and storage through the default or advanced wizard.",
|
||||
"ogTitle": "Create VM: Synology DSM | ProxMenux Documentation",
|
||||
"ogDescription": "Create a Synology DSM virtual machine on Proxmox VE with ProxMenux."
|
||||
},
|
||||
"header": {
|
||||
"title": "Create VM: Synology DSM",
|
||||
"description": "Create a Synology DSM virtual machine on Proxmox VE. ProxMenux downloads the loader of your choice (Arc, RR, TinyCore M-shell or a custom one), imports it as the VM's boot disk and prepares CPU, RAM and storage through the default or advanced wizard.",
|
||||
"description": "Create a Synology DSM virtual machine on Proxmox VE. ProxMenux downloads your chosen loader (Arc, RR, Alpine RedPill M-shell or a custom image), imports it as the VM boot disk and configures CPU, RAM and storage through the default or advanced wizard.",
|
||||
"section": "Virtual Machines · NAS"
|
||||
},
|
||||
"loaderLabels": {
|
||||
@@ -32,7 +32,7 @@
|
||||
"url": "https://github.com/RROrg/rr"
|
||||
},
|
||||
{
|
||||
"name": "TinyCore RedPill M-shell",
|
||||
"name": "Alpine RedPill M-shell (TinyCore project)",
|
||||
"url": "https://github.com/PeterSuh-Q3/tinycore-redpill"
|
||||
}
|
||||
],
|
||||
@@ -127,7 +127,7 @@
|
||||
"virtualItemsRich": [
|
||||
"Lists the Proxmox storage volumes available on the host.",
|
||||
"You pick the target storage and the size in GB.",
|
||||
"The disk is attached to the VM as SATA (<code>sata0</code>, <code>sata1</code>, … up to 6)."
|
||||
"The disk is attached as SATA (<code>sata0</code>, <code>sata1</code>, …). Virtual and physical data disks share the six SATA slots numbered 0–5."
|
||||
],
|
||||
"importHeading": "b. Add import disk",
|
||||
"importItemsRich": [
|
||||
@@ -139,7 +139,7 @@
|
||||
"pciItemsRich": [
|
||||
"Detects SATA/SAS HBAs and NVMe devices on the host and lets you pass an <em>entire controller</em> into the VM. IOMMU must be enabled; the script offers to enable it and reboots if required.",
|
||||
"A confirmation step warns about controller-wide risk (the whole card, including every disk on it, leaves the host).",
|
||||
"The selected PCI devices are attached via <code>qm set hostpciN: …</code>."
|
||||
"The selected PCI devices are attached with commands such as <code>qm set VMID --hostpci0 PCI_ADDRESS,pcie=1</code>. Replace VMID and PCI_ADDRESS with the VM ID and PCI address, and use an unused hostpci index for each device."
|
||||
],
|
||||
"resetCalloutTitle": "Reset and finish",
|
||||
"resetCalloutBodyRich": "The menu also offers <strong>r</strong> (reset the current selection and start over) and <strong>d</strong> (finish and continue). You cannot finish with an empty plan — Synology needs at least one disk to install DSM on."
|
||||
@@ -150,7 +150,7 @@
|
||||
},
|
||||
"loaderInstall": {
|
||||
"heading": "Loader installation",
|
||||
"intro1Rich": "<strong>Arc</strong>, <strong>RR</strong> and <strong>TinyCore M-shell</strong> are downloaded and extracted automatically from their upstream GitHub repositories. If the download fails the script aborts with a clear message.",
|
||||
"intro1Rich": "<strong>Arc</strong>, <strong>RR</strong> and <strong>Alpine RedPill M-shell</strong> are downloaded and extracted automatically from their upstream GitHub repositories. If the download fails the script aborts with a clear message.",
|
||||
"intro2Rich": "For the <strong>Custom Loader</strong> option the script scans <code>/var/lib/vz/template/iso</code>. If more than one candidate is found you are prompted to pick the one you want.",
|
||||
"uploadIntro": "You can upload custom loaders from Proxmox local storage:",
|
||||
"imageAlt": "Add custom loader",
|
||||
@@ -161,17 +161,17 @@
|
||||
"introRich": "Once you confirm the loader, ProxMenux runs the equivalent of these <code>qm</code> commands:",
|
||||
"itemsRich": [
|
||||
"<code>qm create</code> — creates the VM with the selected CPU, RAM, BIOS and machine type.",
|
||||
"<code>qm importdisk</code> — imports the loader as an <strong>IDE</strong> disk (maximum compatibility).",
|
||||
"<code>qm set sataN: …</code> — attaches virtual disks and imported disks from the storage plan, plus the network interface.",
|
||||
"<code>qm set hostpciN: …</code> — attaches any Controller / NVMe devices selected for PCI passthrough.",
|
||||
"<code>qm set --boot</code> — sets the loader as the first boot device."
|
||||
"<code>qm importdisk</code> imports the loader image to Proxmox storage. The script then attaches it to the VM as an <strong>IDE</strong> disk on ide0 for compatibility.",
|
||||
"<code>qm set VMID --sata0 DISK_REFERENCE</code> attaches a planned data disk. Replace VMID and DISK_REFERENCE with the VM ID and disk reference; use a free SATA index from 0–5. The network adapter is configured by qm create.",
|
||||
"<code>qm set VMID --hostpci0 PCI_ADDRESS,pcie=1</code> attaches a selected PCI controller or NVMe device. Replace VMID and PCI_ADDRESS with the VM ID and PCI address, and use a free hostpci index for each device.",
|
||||
"<code>qm set VMID --boot order=ide0</code> configures the loader as the boot device. Replace VMID with the VM ID."
|
||||
]
|
||||
},
|
||||
"stepByStep": {
|
||||
"heading": "Step-by-step loader configuration",
|
||||
"intro": "All loaders follow the same high-level pattern — start the VM, pick a model, pick a DSM version, pick add-ons, build, boot — but the screens and menus differ. The guide below walks through the six shared steps with screenshots for each loader. Exact options may change with new loader releases.",
|
||||
"intro": "The six common steps are: start the VM, choose a model, choose a DSM version, choose add-ons, build and boot. Menus and options vary by release. The M-shell screenshots below show an earlier TinyCore interface; the current script downloads Alpine RedPill M-shell, so follow its current prompts.",
|
||||
"warnCalloutTitle": "Loaders are not maintained by ProxMenux",
|
||||
"warnCalloutBody": "Arc, RR and TinyCore are community projects with their own release cadence. If a step looks different from the screenshots below, the loader has probably updated — check the loader's own documentation (links at the bottom of this page)."
|
||||
"warnCalloutBody": "Arc, RR and Alpine RedPill M-shell are community projects with their own release cadence. If a step looks different from the screenshots below, the loader has probably updated — check the loader's own documentation (links at the bottom of this page)."
|
||||
},
|
||||
"stepBadge": "Step",
|
||||
"step1": {
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
},
|
||||
{
|
||||
"param": "CPU type",
|
||||
"optionsRich": "Host or KVM64"
|
||||
"optionsRich": "Host, KVM64 and other listed CPU models (ZimaOS: Host or KVM64)"
|
||||
},
|
||||
{
|
||||
"param": "Cores",
|
||||
@@ -97,7 +97,7 @@
|
||||
}
|
||||
],
|
||||
"zfsCalloutTitle": "ZFS and RAM",
|
||||
"zfsCalloutBody": "TrueNAS SCALE / CORE and XigmaNAS are ZFS-based. ZFS uses free memory as ARC cache, so the 8 GB default is a minimum — bump it to 16 GB or more if you plan to store anything meaningful. OMV (ext4/XFS), Rockstor (Btrfs) and ZimaOS are far less memory-hungry."
|
||||
"zfsCalloutBody": "TrueNAS SCALE / CORE and XigmaNAS use ZFS, whose ARC cache benefits from RAM. TrueNAS needs at least 8 GB for basic use; 16 GB or more can help with heavier services and apps. Size the VM for the chosen distribution and workload rather than treating 8 GB as a universal ZFS minimum. Lighter OMV, Rockstor or ZimaOS setups can need less."
|
||||
},
|
||||
"storagePlan": {
|
||||
"heading": "Storage plan",
|
||||
@@ -106,19 +106,19 @@
|
||||
"virtualItemsRich": [
|
||||
"Lists the Proxmox storage volumes available on the host.",
|
||||
"You pick the target storage and the size in GB.",
|
||||
"The disk is attached to the VM as SATA (<code>sata0</code>, <code>sata1</code>, … up to 6)."
|
||||
"The disk uses the selected bus: SCSI (default), SATA, VirtIO or IDE (ZimaOS: SCSI or SATA). SATA slots are <code>sata0</code>, <code>sata1</code>, …, with six slots numbered 0–5."
|
||||
],
|
||||
"importHeading": "b. Add import disk",
|
||||
"importItemsRich": [
|
||||
"Detects physical disks that are safe to import (system and protected disks are hidden).",
|
||||
"You select one or more disks via a checklist.",
|
||||
"Imported disks are attached as SATA via <code>qm set</code>."
|
||||
"Imported disks use the selected bus and are attached via <code>qm set</code>."
|
||||
],
|
||||
"pciHeading": "c. Add Controller or NVMe (PCI passthrough)",
|
||||
"pciItemsRich": [
|
||||
"Detects SATA/SAS HBAs and NVMe devices on the host and lets you pass an <em>entire controller</em> into the VM. IOMMU must be enabled; the script offers to enable it and reboots if required.",
|
||||
"A confirmation step warns about controller-wide risk (the whole card, including every disk on it, leaves the host).",
|
||||
"The selected PCI devices are attached via <code>qm set hostpciN: …</code>."
|
||||
"The selected PCI devices are attached with commands such as <code>qm set VMID --hostpci0 PCI_ADDRESS,pcie=1</code>. Replace VMID and PCI_ADDRESS with the VM ID and PCI address, and use an unused hostpci index for each device."
|
||||
],
|
||||
"resetCalloutTitle": "Reset and finish",
|
||||
"resetCalloutBodyRich": "The menu also offers <strong>r</strong> (reset the current selection and start over) and <strong>d</strong> (finish and continue). You cannot finish with an empty plan."
|
||||
@@ -163,7 +163,7 @@
|
||||
"icon": "Database",
|
||||
"officialName": "TrueNAS SCALE",
|
||||
"officialUrl": "https://www.truenas.com/truenas-scale/",
|
||||
"description": "Debian-based TrueNAS with Docker / Kubernetes apps, Linux KVM and ZFS as the primary filesystem. The modern successor to FreeNAS for users who want ZFS plus a container ecosystem.",
|
||||
"description": "Debian-based TrueNAS with Docker apps in current releases, Linux KVM and ZFS as the primary filesystem. Older SCALE releases used Kubernetes. It combines ZFS storage with a container ecosystem.",
|
||||
"specs": [
|
||||
"Recommended interface: SATA or SCSI (both support discard/trim)",
|
||||
"Minimum RAM: 8 GB (16 GB+ recommended for real workloads)",
|
||||
@@ -182,7 +182,7 @@
|
||||
"icon": "Database",
|
||||
"officialName": "TrueNAS CORE",
|
||||
"officialUrl": "https://www.truenas.com/truenas-core/",
|
||||
"description": "FreeBSD-based TrueNAS (the former FreeNAS). Mature ZFS storage with jails and plugins, but no Docker / Kubernetes. Being phased out in favour of SCALE but still widely deployed.",
|
||||
"description": "FreeBSD-based TrueNAS, formerly FreeNAS, focused on ZFS storage. CORE 13.3 jails, plugins and virtualization features are obsolete and unsupported; current development focuses on the Linux-based editions.",
|
||||
"specs": [
|
||||
"Recommended interface: SATA",
|
||||
"Minimum RAM: 8 GB (16 GB+ recommended)",
|
||||
@@ -254,7 +254,7 @@
|
||||
"icon": "MonitorIcon",
|
||||
"officialName": "zimaspace.com",
|
||||
"officialUrl": "https://www.zimaspace.com/zimaos",
|
||||
"description": "Lightweight NAS / home-server OS built on top of Debian, with a focus on media, Docker apps and home automation. ZimaOS uses a dedicated ProxMenux installer (vm/zimaos.sh) that downloads a pre-built image, but the VM profile follows the same flow as the other NAS systems.",
|
||||
"description": "Lightweight NAS / home-server OS built with Buildroot, evolved from CasaOS, with a focus on media, Docker apps and home automation. ZimaOS uses a dedicated ProxMenux installer (vm/zimaos.sh) that downloads a pre-built image, while offering CPU, RAM and storage configuration.",
|
||||
"specs": [
|
||||
"Recommended interface: SATA or VirtIO",
|
||||
"Default RAM: 4 GB (enough for media / self-hosted apps)",
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
},
|
||||
{
|
||||
"param": "CPU type",
|
||||
"options": "Host or KVM64"
|
||||
"options": "Host, KVM64 and other listed CPU models"
|
||||
},
|
||||
{
|
||||
"param": "Cores",
|
||||
@@ -105,11 +105,11 @@
|
||||
},
|
||||
{
|
||||
"param": "TPM",
|
||||
"options": "Enable or disable TPM 2.0"
|
||||
"options": "TPM 2.0 is added automatically for Windows; this wizard has no TPM toggle."
|
||||
}
|
||||
],
|
||||
"tpmWarnTitle": "Windows 11 and Windows Server 2022 need TPM",
|
||||
"tpmWarnBody": "Windows 11 and Windows Server 2022 refuse to install without a TPM 2.0 device attached to the VM. ProxMenux adds it by default; only disable it in Advanced if you know the target edition does not require it."
|
||||
"tpmWarnTitle": "TPM requirements depend on the Windows edition",
|
||||
"tpmWarnBody": "Windows 11 normally requires TPM 2.0. Windows Server 2022 requires it for certain security features, not for every installation. ProxMenux adds a virtual TPM for Windows; the advanced wizard does not offer a TPM toggle."
|
||||
},
|
||||
"storagePlan": {
|
||||
"heading": "Storage plan",
|
||||
@@ -118,19 +118,19 @@
|
||||
"virtualDiskItems": [
|
||||
"Lists the Proxmox storage volumes available on the host.",
|
||||
"You pick the target storage and the size in GB.",
|
||||
"The disk is attached to the VM as SATA (<code>sata0</code>, <code>sata1</code>, … up to 6)."
|
||||
"The disk uses the selected bus: SCSI (default), SATA, VirtIO or IDE. SATA slots are <code>sata0</code>, <code>sata1</code>, …, with six slots numbered 0–5."
|
||||
],
|
||||
"importDiskTitle": "b. Add import disk",
|
||||
"importDiskItems": [
|
||||
"Detects physical disks that are safe to import (system and protected disks are hidden).",
|
||||
"You select one or more disks via a checklist.",
|
||||
"Imported disks are attached as SATA via <code>qm set</code>."
|
||||
"Imported disks use the selected bus and are attached via <code>qm set</code>."
|
||||
],
|
||||
"pciTitle": "c. Add Controller or NVMe (PCI passthrough)",
|
||||
"pciItems": [
|
||||
"Detects SATA/SAS HBAs and NVMe devices on the host and lets you pass an <em>entire controller</em> into the VM. IOMMU must be enabled; the script offers to enable it and reboots if required.",
|
||||
"A confirmation step warns about controller-wide risk (the whole card, including every disk on it, leaves the host).",
|
||||
"The selected PCI devices are attached via <code>qm set hostpciN: …</code>."
|
||||
"The selected PCI devices are attached with commands such as <code>qm set VMID --hostpci0 PCI_ADDRESS,pcie=1</code>. Replace VMID and PCI_ADDRESS with the VM ID and PCI address, and use an unused hostpci index for each device."
|
||||
],
|
||||
"resetTitle": "Reset and finish",
|
||||
"resetBody": "The menu also offers <strong>r</strong> (reset the current selection and start over) and <strong>d</strong> (finish and continue). You cannot finish with an empty plan."
|
||||
@@ -144,7 +144,7 @@
|
||||
"efiTitle": "EFI disk",
|
||||
"efiBody": "When OVMF (UEFI) is selected, ProxMenux creates a 4 MB EFI system disk on the storage you pick and attaches it to the VM so the UEFI firmware has a place to store its variables.",
|
||||
"tpmTitle": "TPM 2.0",
|
||||
"tpmBody": "A virtual TPM 2.0 device is added automatically so Windows 11 / Server 2022 installers pass the hardware compatibility check.",
|
||||
"tpmBody": "ProxMenux adds a virtual TPM 2.0 device for Windows VMs. This meets the Windows 11 TPM requirement and supports TPM-dependent features in Windows Server.",
|
||||
"isoTitle": "ISO mounting",
|
||||
"isoBody": "The installation ISO is attached to <code>ide2</code>. The VirtIO drivers ISO is downloaded (if needed) and attached to <code>ide3</code>, ready for the <em>Load driver</em> step.",
|
||||
"guestTitle": "QEMU Guest Agent",
|
||||
@@ -187,9 +187,9 @@
|
||||
},
|
||||
"virtio": {
|
||||
"heading": "VirtIO drivers during installation",
|
||||
"body": "If you leave storage and networking at defaults (SATA + e1000), Windows will install without extra steps. However, the Proxmox storage plan always attaches virtual disks as SATA, which works out of the box. Where VirtIO becomes relevant is if, during the Advanced wizard, you pick VirtIO or SCSI for disks or VirtIO for the NIC — in that case Windows will not see those devices until the matching driver is loaded from the VirtIO ISO mounted at <code>ide3</code>.",
|
||||
"warnTitle": "Without the VirtIO network driver there is no internet during install",
|
||||
"warnBody": "If you picked VirtIO (<code>virtio</code>) as the network interface and do not load the driver during setup, Windows will not have internet access. That can block activation and Windows Update steps during first boot.",
|
||||
"body": "The VM creator defaults to SCSI disks with a VirtIO SCSI controller and a VirtIO network adapter. A standard Windows ISO may need their drivers from the VirtIO ISO mounted at <code>ide3</code>. SATA disks usually work with built-in Windows drivers; choosing SATA does not change the VirtIO network adapter.",
|
||||
"warnTitle": "Load the VirtIO network driver if Windows has no network",
|
||||
"warnBody": "The VM uses a VirtIO (<code>virtio</code>) network adapter. If Windows does not include its driver, load it during setup to obtain network access. Otherwise activation and Windows Update may be unavailable during first boot.",
|
||||
"stepLabel": "Step",
|
||||
"steps": [
|
||||
{
|
||||
@@ -206,7 +206,7 @@
|
||||
},
|
||||
{
|
||||
"title": "Browse to the correct driver folder",
|
||||
"bodyRich": "On the VirtIO ISO navigate to the folder that matches the interface and Windows version — for example <code>viostor</code> for VirtIO SCSI, with subfolders per Windows edition (10 / 11 / Server).",
|
||||
"bodyRich": "On the VirtIO ISO select <code>vioscsi</code> for the VirtIO SCSI controller or <code>viostor</code> for VirtIO block disks. Then choose the subfolder for your Windows version and architecture.",
|
||||
"img": "/vm/windows/virtio-step-3.png",
|
||||
"caption": "Browse to the appropriate driver folder"
|
||||
},
|
||||
@@ -237,7 +237,7 @@
|
||||
{
|
||||
"href": "/docs/disk-manager/import-disk-image-vm",
|
||||
"label": "Import Disk Image to VM",
|
||||
"tail": " — attach an existing Windows .vhdx / .vmdk to a fresh VM."
|
||||
"tail": " — import an existing Windows disk image (.vmdk, .qcow2, .img or .raw) into an existing VM; convert .vhdx images to a supported format first."
|
||||
},
|
||||
{
|
||||
"href": "/docs/hardware/gpu-vm-passthrough",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"iommu": {
|
||||
"heading": "IOMMU groups — why the whole card leaves at once",
|
||||
"body": "PCI passthrough is done per <strong>IOMMU group</strong>, which is the smallest unit the CPU's IOMMU can isolate. Everything inside a group moves together. If your SATA controller shares its IOMMU group with the USB controller, passing the SATA card to a VM also takes the USB ports with it — often undesirable.",
|
||||
"body": "The isolation boundary for PCI passthrough is the <strong>IOMMU group</strong>, the smallest unit the CPU’s IOMMU can isolate. Devices in the same group cannot be isolated from each other. If a SATA controller shares its group with a USB controller, passing through SATA may also require releasing USB from the host, or may prevent passthrough. It does not automatically assign every device in the group to the VM.",
|
||||
"outro": "ProxMenux shows the IOMMU group next to each device and warns you when a group carries more than just the controller you want. You can still proceed if the extra devices in the group are acceptable (all disk controllers, for example), or back out if they are not."
|
||||
},
|
||||
"prereqs": {
|
||||
@@ -97,7 +97,7 @@
|
||||
"busyBody": "Another process still holds the PCI device. Most common causes: a previous VM that crashed without releasing it, or the host kernel reclaimed it on the last boot. Run <code>lspci -nnk -s <addr></code> to see which driver is bound; it should be <code>vfio-pci</code>. A full host reboot usually clears this.",
|
||||
"noDisksTitle": "Guest sees the controller but not the disks",
|
||||
"noDisksBody": "The controller model lacks an in-guest driver. Linux almost never hits this; Windows does — install the vendor driver (e.g. LSI / Broadcom for older SAS HBAs) while the card is detached, then reboot with the card attached.",
|
||||
"sharedTitle": "Shared IOMMU group also exports an unrelated device",
|
||||
"sharedTitle": "The IOMMU group includes an unrelated device",
|
||||
"sharedBody": "Options: (a) move the card to a different PCIe slot to change its group, (b) enable <em>ACS override</em> in the kernel to split groups (security trade-off — research before applying), or (c) pick a different card in a cleaner group."
|
||||
},
|
||||
"related": {
|
||||
|
||||
@@ -46,19 +46,19 @@
|
||||
"mode": "1. Wipe all",
|
||||
"part": "Destroyed",
|
||||
"data": "Signatures wiped",
|
||||
"useCase": "Starting fresh: everything on the disk goes, ready for a new layout."
|
||||
"useCase": "Removes the partition table and the filesystem and RAID metadata, zeroes the first and last 16 MiB and, on drives that support discard, trims the whole disk. The rest of the data is not overwritten and may still be recoverable on HDDs; this is not a secure erase."
|
||||
},
|
||||
{
|
||||
"mode": "2. Remove FS labels",
|
||||
"part": "Preserved",
|
||||
"data": "Preserved",
|
||||
"useCase": "Clears stale ZFS / LVM / RAID signatures so the disk stops being auto-claimed, without touching the data."
|
||||
"useCase": "Removes stale ZFS / LVM / RAID signatures so the disk is no longer auto-claimed. Bulk user data is not overwritten, but removing signatures can make it inaccessible."
|
||||
},
|
||||
{
|
||||
"mode": "3. Zero all data",
|
||||
"part": "Preserved",
|
||||
"data": "Destroyed (zeroed)",
|
||||
"useCase": "Sanitise before handing the disk over, keeping the existing partition layout."
|
||||
"useCase": "Overwrite the existing partitions with zeros while keeping the partition table. Unallocated space and SSD spare areas are not covered; this is not a complete device sanitization guarantee."
|
||||
},
|
||||
{
|
||||
"mode": "4. Full format",
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
"intro": "For every selected image ProxMenux asks:",
|
||||
"items": [
|
||||
"<strong>Interface</strong> — <code>scsi</code> (default), <code>virtio</code>, <code>sata</code> or <code>ide</code>. Matches how the guest will see the disk.",
|
||||
"<strong>SSD emulation</strong> — only offered for non-VirtIO interfaces. Adds <code>ssd=1</code> so the guest advertises the disk as solid-state (useful for OS-level TRIM / alignment).",
|
||||
"<strong>SSD emulation</strong> — only offered for non-VirtIO interfaces. Adds <code>ssd=1</code> so the guest recognizes a solid-state disk. Discard/TRIM support must be configured separately.",
|
||||
"<strong>Bootable</strong> — if yes, ProxMenux adds the disk to the boot order so it becomes the primary boot device of the VM."
|
||||
]
|
||||
},
|
||||
@@ -73,7 +73,7 @@
|
||||
"noImagesTitle": "\"No compatible disk images found\"",
|
||||
"noImagesBody": "The script scanned the directory but found no <code>.img</code> / <code>.qcow2</code> / <code>.vmdk</code> / <code>.raw</code> file. Check the extension (case matters), that the file sits directly in the selected directory (no sub-directories are searched) and that permissions allow root to read it.",
|
||||
"slowTitle": "Import is slow",
|
||||
"slowBody": "VMDK → QCOW2 → raw conversions are CPU- and I/O-bound. Import speed depends on the source read speed, the target storage write speed and CPU for decompression. Prefer raw or qcow2 sources when possible.",
|
||||
"slowBody": "Conversions between VMDK, QCOW2 and raw can be limited by CPU and I/O. Import speed depends on source reads, target writes and any decompression work. Prefer raw or qcow2 sources when possible.",
|
||||
"uefiTitle": "Imported disk boots into UEFI shell",
|
||||
"uefiBody": "The image was built for legacy (SeaBIOS) but the VM uses OVMF (or vice versa). Either switch the VM's BIOS in Proxmox to match the image, or rebuild the image in the correct mode before importing."
|
||||
},
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"At least one physical disk not in use by the host or any other guest."
|
||||
],
|
||||
"warnTitle": "Privileged container required",
|
||||
"warnBody": "Direct device passthrough to an LXC container only works if the container is <strong>privileged</strong>. If the script detects <code>unprivileged: 1</code> in the config it offers to convert it in place (edits <code>/etc/pve/lxc/<CTID>.conf</code>). Cancel if you cannot accept the security trade-off of a privileged container."
|
||||
"warnBody": "This script requires a <strong>privileged</strong> container for its direct disk attachment. If it detects <code>unprivileged: 1</code>, it offers to edit <code>/etc/pve/lxc/<CTID>.conf</code> in place. This changes the security model and does not remap existing file ownership. Back up the container and verify ownership before accepting, or rebuild it as privileged."
|
||||
},
|
||||
"steps": {
|
||||
"heading": "Step-by-step",
|
||||
@@ -83,9 +83,9 @@
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"unprivTitle": "\"Cannot continue with an unprivileged container\"",
|
||||
"unprivBody": "You declined the conversion offer. Either re-run and accept the conversion, or convert the container manually by editing <code>/etc/pve/lxc/<CTID>.conf</code> and replacing <code>unprivileged: 1</code> with <code>unprivileged: 0</code>. You can also rebuild the container as privileged if you prefer not to convert in place.",
|
||||
"unprivBody": "You declined the conversion, so the script stopped without changing anything. To continue, run it again and accept: the script stops the container, backs up its configuration to <code>/etc/pve/lxc/<CTID>.conf.bak</code> and replaces <code>unprivileged: 1</code> with <code>unprivileged: 0</code>. That flag change alone does not convert the UID/GID ownership of existing files, so back up the container and fix the ownership first; alternatively, restore or rebuild the container as privileged.",
|
||||
"permsTitle": "Permissions inside the container are wrong",
|
||||
"permsBody": "Mounts from the host into a privileged container land as <code>root:root</code>. If the service inside the CT runs as a different user (e.g. <code>www-data</code> for Nextcloud), <code>chown</code>/<code>chmod</code> inside the container to match its UID/GID after the first mount."
|
||||
"permsBody": "Existing file ownership is retained when a partition is mounted into a privileged container; a newly formatted filesystem is often owned by <code>root:root</code>. If the service runs as another user (e.g. <code>www-data</code> for Nextcloud), inspect its UID/GID and adjust the required files with <code>chown</code>/<code>chmod</code>. Changes also affect the underlying disk."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "What this does",
|
||||
"body": "This is a raw-disk passthrough: the guest OS sees the drive as a real block device (with its SMART data and native geometry). The disk is attached via its <code>/dev/disk/by-id/…</code> path — not <code>/dev/sdX</code> — so the assignment does not break if disk controllers enumerate devices in a different order on the next boot."
|
||||
"body": "This attaches a raw physical disk as the backing device for a virtual disk interface. The guest does not automatically receive native SMART data or the physical controller’s features; use controller PCI passthrough when those are required. The disk is attached through its <code>/dev/disk/by-id/…</code> path when one exists, so a changed device enumeration order at boot does not break the assignment; otherwise <code>/dev/sdX</code> is used."
|
||||
},
|
||||
"howRuns": {
|
||||
"heading": "How the script runs",
|
||||
@@ -49,7 +49,7 @@
|
||||
"items": [
|
||||
"<strong>SCSI</strong> — modern default for Linux and Windows with VirtIO-SCSI drivers installed.",
|
||||
"<strong>SATA</strong> — broad compatibility, works out of the box on virtually every guest.",
|
||||
"<strong>VirtIO</strong> — paravirtualised block device, fastest but requires guest drivers.",
|
||||
"<strong>VirtIO</strong> — efficient paravirtualised block device; requires guest drivers.",
|
||||
"<strong>IDE</strong> — for legacy guests that lack any of the above drivers."
|
||||
]
|
||||
},
|
||||
@@ -63,7 +63,7 @@
|
||||
"heading": "Manual equivalent",
|
||||
"body": "The script is a wrapper around <code>qm set</code>. The exact command for a single disk looks like this:",
|
||||
"migrationTitle": "Live migration is not possible",
|
||||
"migrationBody": "A VM with a passthrough disk is <strong>tied to the host that exposes that disk</strong>. Live migration to another Proxmox node will fail because the target node does not see the same <code>/dev/disk/by-id/…</code> path. Use replication or backup/restore instead, or pick virtual disks on shared storage if you need mobility.",
|
||||
"migrationBody": "A VM with a physical passthrough disk is <strong>tied to the host that exposes that disk</strong>. Another node normally lacks the same <code>/dev/disk/by-id/…</code> path and disk data. Back up and transfer that data separately, or use managed virtual disks on shared or supported replicated storage for mobility; do not assume Proxmox storage replication covers this device.",
|
||||
"shareTitle": "Do not share a physical disk between VMs",
|
||||
"shareBody": "Attaching the same physical disk to two VMs at the same time will corrupt data on next write. ProxMenux detects this situation and blocks it, but if you bypass the script (direct <code>qm set</code>), make sure only one guest ever mounts the disk."
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Proxmox Disk Manager — Attach Disks to VMs / LXC, SMART Tests, Wipe | ProxMenux",
|
||||
"description": "Manage physical disks on a Proxmox VE host with ProxMenux: pass disks through to VMs or LXC containers (qm set scsi/sata/virtio, pct mp), import qcow2 / vmdk / vdi disk images, pass through whole HBAs or NVMe controllers, safely wipe disks and run SMART self-tests.",
|
||||
"description": "Manage physical disks on a Proxmox VE host with ProxMenux: attach disks to VMs or LXC containers (qm set scsi/sata/virtio, pct mp), import img / qcow2 / vmdk / raw disk images, pass through whole HBAs or NVMe controllers, wipe disks with safety checks and run SMART self-tests.",
|
||||
"ogTitle": "Proxmox Disk Manager — Attach Disks to VMs / LXC, SMART Tests, Wipe",
|
||||
"ogDescription": "Attach disks to VMs / LXC, import disk images, PCI passthrough for controllers, safe wipe and SMART tests on Proxmox VE.",
|
||||
"twitterTitle": "Proxmox Disk Manager | ProxMenux",
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "What this menu is for",
|
||||
"body": "Every option here operates on <strong>physical disks already visible to the Proxmox host</strong>. The menu is split in three groups — <strong>VM</strong> (attach disks or import images into a virtual machine), <strong>LXC</strong> (attach disks to a container), and <strong>Utilities</strong> (safe format, SMART health). Safety checks apply everywhere: system disks and disks already in use are hidden or blocked."
|
||||
"body": "These tools work with <strong>physical disks visible to the Proxmox host and image files stored on it</strong>. The menu has three groups: <strong>VM</strong> (attach disks or import images), <strong>LXC</strong> (attach disks to a container), and <strong>Utilities</strong> (formatting and SMART health). Attachment and wipe operations hide or block system disks and disks already in use; SMART checks can inspect those disks without wiping them."
|
||||
},
|
||||
"opening": {
|
||||
"heading": "Opening the menu",
|
||||
@@ -32,7 +32,7 @@
|
||||
"Add Controller or NVMe to VM"
|
||||
],
|
||||
"lxcTitle": "LXC",
|
||||
"lxcBody": "Tools that operate on existing containers. Direct device passthrough needs a privileged container; the script offers to convert it if necessary.",
|
||||
"lxcBody": "Tools for existing LXC containers. This script requires a privileged container and offers to change the flag when needed. Read the conversion and file-ownership cautions on the tool page first.",
|
||||
"lxcItems": [
|
||||
"Import Disk to LXC"
|
||||
],
|
||||
@@ -69,7 +69,7 @@
|
||||
},
|
||||
"lxc": {
|
||||
"heading": "LXC",
|
||||
"intro": "Tools that operate on existing LXC containers. Direct device passthrough requires a privileged container; the script offers to convert the container if needed.",
|
||||
"intro": "Tools for existing LXC containers. This script requires a privileged container and offers to change the flag when needed. Read the conversion and file-ownership cautions on the tool page first.",
|
||||
"options": [
|
||||
{
|
||||
"icon": "Boxes",
|
||||
@@ -98,8 +98,8 @@
|
||||
]
|
||||
},
|
||||
"safety": {
|
||||
"title": "Safety rules shared by every option",
|
||||
"intro": "ProxMenux filters out anything that could harm the host:",
|
||||
"title": "Safety rules for disk attachment and wiping",
|
||||
"intro": "Attachment and wipe operations filter out devices that could harm the host:",
|
||||
"items": [
|
||||
"The <strong>system disk</strong> (root pool, swap, active ZFS / LVM / RAID members) is always hidden.",
|
||||
"Disks <strong>mounted</strong> anywhere on the host are hidden or blocked at execution.",
|
||||
|
||||
@@ -55,11 +55,11 @@
|
||||
}
|
||||
],
|
||||
"tipTitle": "Long tests survive terminal close",
|
||||
"tipBody": "A long test is queued <em>inside the drive</em> — it does not depend on the ProxMenux process staying alive. You can close the terminal, reboot the Proxmox host (the test picks up where it left off on some drives) or just come back later and use <strong>Check test progress</strong> to see the result."
|
||||
"tipBody": "A long test runs <em>inside the drive</em> and does not depend on the ProxMenux process staying alive. You can close the terminal and return later to <strong>Check test progress</strong>. A host reboot, controller reset or power loss may interrupt the test and its result collector; do not assume it will resume automatically."
|
||||
},
|
||||
"json": {
|
||||
"heading": "JSON export for the Monitor",
|
||||
"intro": "Every run writes a timestamped JSON file to <code>/usr/local/share/proxmenux/smart/<disk>/</code>. The structure is:",
|
||||
"intro": "Status, short-test and progress actions write a timestamped JSON file to <code>/usr/local/share/proxmenux/smart/<disk>/</code>; long-test results are collected in the background. The full-report action only displays its report. The structure is:",
|
||||
"outro": "The ProxMenux Monitor picks these up to render health trends per disk; old files are rotated out automatically once the retention limit is reached."
|
||||
},
|
||||
"steps": {
|
||||
@@ -89,7 +89,7 @@
|
||||
},
|
||||
{
|
||||
"title": "Review results",
|
||||
"bodyRich": "Status and report are printed to the terminal and written to JSON. For long tests, return later and run <strong>Check test progress</strong> on the same disk to see the outcome.",
|
||||
"bodyRich": "Status, test and progress output is shown in the terminal; <strong>Full report</strong> opens in a scrollable dialog. JSON is exported for the actions described above, not for Full report. For long tests, return later and run <strong>Check test progress</strong> on the same disk to see the outcome.",
|
||||
"img": "/disk/smart/quick-status.png",
|
||||
"alt": "Quick health status output",
|
||||
"caption": "Quick health status output (SATA — smartctl -H + -A)"
|
||||
@@ -106,7 +106,7 @@
|
||||
"noSmartTitle": "\"Could not read SMART data from /dev/sdX\"",
|
||||
"noSmartBody": "The disk is probably behind a RAID / SAS controller that does not pass SMART through. With megaraid-based cards, try <code>smartctl -d megaraid,N /dev/sdX</code>. For HBAs in IT mode the direct invocation works.",
|
||||
"longTitle": "Long test never completes",
|
||||
"longBody": "The test is queued on the drive firmware and pauses if the disk is under heavy load. Running it overnight on an idle system usually works. You can also check <code>smartctl -c</code> to see percentage remaining; if it is stuck at a fixed LBA, the disk is failing at that sector."
|
||||
"longBody": "The drive runs the test in firmware, and heavy I/O can delay completion. Try an idle period such as overnight. For SATA, <code>smartctl -c</code> shows the remaining percentage, and for SAS, <code>smartctl -l selftest</code>; inspect the self-test log for completion status and any failing LBA. A reported read failure needs investigation; slow progress alone does not prove a bad sector."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
@@ -124,7 +124,7 @@
|
||||
{
|
||||
"href": "/docs/help-info/zfs-commands",
|
||||
"label": "ZFS Management commands",
|
||||
"tail": " — zpool scrub for the storage-layer equivalent of SMART tests."
|
||||
"tail": " — zpool scrub verifies ZFS data checksums and complements hardware SMART tests."
|
||||
},
|
||||
{
|
||||
"href": "/docs/monitor/dashboard/storage",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"aliasesLabel": "also:",
|
||||
"missingCallout": {
|
||||
"title": "Missing a term?",
|
||||
"leadRich": "If a term in the docs isn't defined here, open an issue or PR on <ext>GitHub</ext> — the glossary lives in <code>web/app/docs/glossary/page.tsx</code> as a simple data array."
|
||||
"leadRich": "If a term in the docs is missing, open an issue or PR on <ext>GitHub</ext>. Glossary content lives in <code>web/messages/en/docs/glossary.json</code>, with matching locale catalogs."
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
@@ -29,7 +29,7 @@
|
||||
"ACS override"
|
||||
],
|
||||
"category": "Virtualization",
|
||||
"definitionRich": "PCIe extension that prevents direct peer-to-peer traffic between devices, ensuring each device sits in its own IOMMU group. The <em>ACS override</em> kernel patch loosens this so devices in the same IOMMU group can be passed to different VMs — useful but a security trade-off.",
|
||||
"definitionRich": "PCIe access-control features that help isolate device traffic. IOMMU grouping depends on hardware and topology. The <em>ACS override</em> kernel patch can split groups reported by Linux, but does not add hardware isolation; assigning those devices to separate VMs carries a security risk.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Add Controller or NVMe to VM",
|
||||
@@ -43,7 +43,7 @@
|
||||
"Adaptive Replacement Cache"
|
||||
],
|
||||
"category": "Storage",
|
||||
"definitionRich": "ZFS's in-memory read cache. Holds recently and frequently used data blocks; size scales with available host RAM. Defaults are aggressive — Proxmox post-install lets you cap it.",
|
||||
"definitionRich": "ZFS read cache in host RAM, holding recently and frequently used data blocks. Its default limit depends on the Proxmox version and installation settings. ProxMenux Post-Install offers an option to cap it.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Post-Install: Storage",
|
||||
@@ -83,7 +83,7 @@
|
||||
"Linux bridge"
|
||||
],
|
||||
"category": "Network",
|
||||
"definitionRich": "A virtual layer-2 switch on the host. <code>vmbr0</code> is the default Proxmox bridge that connects VMs and containers to the physical network. Multiple bridges (<code>vmbr1</code>, <code>vmbr2</code>...) isolate groups of guests.",
|
||||
"definitionRich": "A virtual layer-2 switch on the host. <code>vmbr0</code> commonly connects guests to the physical network. Additional bridges (<code>vmbr1</code>, <code>vmbr2</code>...) can separate guest networks, depending on their physical links and configuration.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Bridge analysis & guided repair",
|
||||
@@ -94,7 +94,7 @@
|
||||
{
|
||||
"term": "Ceph",
|
||||
"category": "Storage",
|
||||
"definitionRich": "Distributed storage system tightly integrated with Proxmox for hyper-converged clusters. Provides object, block and file storage backed by OSDs (Object Storage Daemons). PVE 9 requires Ceph 19.x (Squid).",
|
||||
"definitionRich": "Distributed storage integrated with Proxmox for hyper-converged clusters. OSDs (Object Storage Daemons) underpin its object, block and file storage. Required Ceph versions depend on the Proxmox release and upgrade path; consult the corresponding upgrade guide.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Upgrade PVE 8 to PVE 9",
|
||||
@@ -134,7 +134,7 @@
|
||||
"Discrete GPU"
|
||||
],
|
||||
"category": "Virtualization",
|
||||
"definitionRich": "A standalone graphics card on its own PCIe slot (e.g. NVIDIA RTX, AMD Radeon). Contrasts with <strong>iGPU</strong>. Typically used for VFIO passthrough to a single VM, not for sharing across LXCs.",
|
||||
"definitionRich": "A separate graphics card, typically connected over PCIe, unlike an <strong>iGPU</strong>. It can be assigned to a VM with VFIO or accessed by multiple LXC containers through device nodes and the host driver, subject to hardware and application support.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Add GPU to VM (Passthrough)",
|
||||
@@ -153,7 +153,7 @@
|
||||
"Dynamic Kernel Module Support"
|
||||
],
|
||||
"category": "Linux",
|
||||
"definitionRich": "Framework that automatically rebuilds out-of-tree kernel modules (NVIDIA, ZFS, custom drivers) when the kernel is upgraded. Avoids modules being left behind after kernel updates.",
|
||||
"definitionRich": "Framework for rebuilding registered out-of-tree kernel modules, such as NVIDIA or ZFS, when the kernel changes. Successful builds still require compatible module sources and matching kernel headers.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Install Coral TPU (Host)",
|
||||
@@ -189,7 +189,7 @@
|
||||
"GRand Unified Bootloader"
|
||||
],
|
||||
"category": "Linux",
|
||||
"definitionRich": "Boot loader for most Linux distributions. Configuration lives in <code>/etc/default/grub</code> + <code>/boot/grub/</code>. Modified for IOMMU enablement, kernel parameters and EFI boot entries. Run <code>update-grub</code> after edits.",
|
||||
"definitionRich": "Boot loader used on GRUB-based Linux installations. Configuration is in <code>/etc/default/grub</code> and <code>/boot/grub/</code>; run <code>update-grub</code> after edits. Other Proxmox boot setups may use systemd-boot, so check the active boot loader before changing kernel parameters.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "GPU Passthrough commands",
|
||||
@@ -229,7 +229,7 @@
|
||||
"AMD-Vi"
|
||||
],
|
||||
"category": "Virtualization",
|
||||
"definitionRich": "Hardware feature (Intel VT-d / AMD-Vi) that lets PCIe devices be safely assigned directly to guest VMs. Required for GPU and disk-controller passthrough. Must be enabled both in BIOS / UEFI and in the kernel command line (<code>intel_iommu=on</code> or <code>amd_iommu=on</code>).",
|
||||
"definitionRich": "Hardware feature (Intel VT-d / AMD-Vi) needed for PCIe passthrough to VMs. Enable it in firmware and ensure kernel support is active. Kernel arguments such as <code>intel_iommu=on</code> or <code>amd_iommu=on</code> may be needed, depending on platform and kernel defaults.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Post-Install: Virtualization",
|
||||
@@ -244,7 +244,7 @@
|
||||
{
|
||||
"term": "IOMMU group",
|
||||
"category": "Virtualization",
|
||||
"definitionRich": "The smallest unit of devices that the IOMMU can isolate from each other. All devices in a group must be passed through together — usually one device, but multi-function cards or shared root-port devices land in the same group. Listed via <code>find /sys/kernel/iommu_groups/ -type l | sort -V</code>."
|
||||
"definitionRich": "A set of devices that forms the smallest IOMMU isolation boundary. Devices within a group are not necessarily isolated from one another; review every member before VFIO assignment. Listed via <code>find /sys/kernel/iommu_groups/ -type l | sort -V</code>."
|
||||
},
|
||||
{
|
||||
"term": "iSCSI",
|
||||
@@ -274,7 +274,7 @@
|
||||
"Logical Volume Manager"
|
||||
],
|
||||
"category": "Storage",
|
||||
"definitionRich": "Linux storage stack that abstracts physical disks into volume groups (VG) of logical volumes (LV). Proxmox uses LVM-thin pools for VM disks by default. Concise tools: <code>pvs</code>, <code>vgs</code>, <code>lvs</code>.",
|
||||
"definitionRich": "Linux volume-management layer that groups physical storage into volume groups (VG) containing logical volumes (LV). LVM-based Proxmox installations commonly use LVM-thin for guest disks; other backends are available. Tools include <code>pvs</code>, <code>vgs</code> and <code>lvs</code>.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Storage and Disks commands",
|
||||
@@ -288,7 +288,7 @@
|
||||
"Linux Containers"
|
||||
],
|
||||
"category": "Linux",
|
||||
"definitionRich": "OS-level virtualization technology — multiple isolated user-space instances share the host's kernel. Lighter and faster than VMs but less isolated. Proxmox manages LXC containers via the <code>pct</code> CLI.",
|
||||
"definitionRich": "OS-level virtualization in which isolated userspace instances share the host kernel. Usually has less overhead than VMs, with a different isolation boundary. Proxmox manages LXC containers with the <code>pct</code> CLI.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "VM and CT Management",
|
||||
@@ -313,7 +313,7 @@
|
||||
"Hardware address"
|
||||
],
|
||||
"category": "Network",
|
||||
"definitionRich": "48-bit identifier burnt into a NIC's firmware. Used by Proxmox <em>Persistent Network Names</em> to pin interface names (<code>eno1</code>, <code>enp3s0</code>) so they survive PCI re-enumeration.",
|
||||
"definitionRich": "Usually a 48-bit Ethernet interface identifier, assigned by hardware or software. ProxMenux <em>Persistent Network Names</em> matches MAC addresses to stable interface names (<code>eno1</code>, <code>enp3s0</code>) to keep names consistent after PCI re-enumeration.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Persistent interface names",
|
||||
@@ -327,7 +327,7 @@
|
||||
"Message of the Day"
|
||||
],
|
||||
"category": "Linux",
|
||||
"definitionRich": "Text shown after SSH login. Stored in <code>/etc/motd</code>. ProxMenux Post-Install can add a banner here; the uninstaller restores the backup if you applied it."
|
||||
"definitionRich": "Text displayed after SSH login, stored in <code>/etc/motd</code>. ProxMenux Post-Install can add a banner; the uninstaller restores the previous file when a backup exists."
|
||||
},
|
||||
{
|
||||
"term": "NFS",
|
||||
@@ -346,7 +346,7 @@
|
||||
{
|
||||
"term": "nftables / iptables",
|
||||
"category": "Network",
|
||||
"definitionRich": "Linux firewall systems. <code>nftables</code> is the modern engine; <code>iptables</code> is the legacy front-end (still works as a translation layer). Proxmox's <code>pve-firewall</code> emits nftables rules from the cluster firewall config.",
|
||||
"definitionRich": "Linux firewall tooling. <code>nftables</code> is the modern framework; <code>iptables</code> can use legacy or nft-compatible backends. Classic <code>pve-firewall</code> uses iptables, while the alternative proxmox-firewall backend uses nftables.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Network commands",
|
||||
@@ -357,7 +357,7 @@
|
||||
{
|
||||
"term": "nouveau",
|
||||
"category": "Linux",
|
||||
"definitionRich": "Open-source NVIDIA driver bundled with the Linux kernel. Must be blacklisted before installing the proprietary NVIDIA driver, otherwise both load and the install fails.",
|
||||
"definitionRich": "Open-source NVIDIA graphics driver included with the Linux kernel. When installing the proprietary NVIDIA driver, prevent nouveau from binding the same GPU, usually by blacklisting it and rebuilding initramfs.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "NVIDIA installation guide",
|
||||
@@ -368,7 +368,7 @@
|
||||
{
|
||||
"term": "no-subscription repo",
|
||||
"category": "Proxmox",
|
||||
"definitionRich": "Free Proxmox repository for users without an enterprise subscription. Less polished QA than the enterprise repo (slightly riskier for production) but free. Set up automatically by the ProxMenux Post-Install.",
|
||||
"definitionRich": "Proxmox package repository available without an enterprise subscription. Packages receive less validation than in the enterprise repository, which Proxmox recommends for production. ProxMenux Post-Install offers repository configuration.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Post-Install: Basic Settings",
|
||||
@@ -382,7 +382,7 @@
|
||||
"Open Virtualization Format"
|
||||
],
|
||||
"category": "Virtualization",
|
||||
"definitionRich": "DMTF-standard packaging formats for portable VMs. <strong>OVA</strong> is a single TAR archive; <strong>OVF</strong> is a directory with an XML descriptor + external VMDK files. Importable on VMware, VirtualBox and Proxmox.",
|
||||
"definitionRich": "DMTF formats for packaging portable VMs. <strong>OVA</strong> packages the files in a single TAR archive; <strong>OVF</strong> describes the VM in XML with accompanying disk files, commonly VMDK. Import support depends on the target hypervisor and configuration.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Export VM to OVA / OVF",
|
||||
@@ -401,7 +401,7 @@
|
||||
"Open Virtual Machine Firmware"
|
||||
],
|
||||
"category": "Virtualization",
|
||||
"definitionRich": "UEFI firmware implementation for VMs. Set with <code>qm set <vmid> -bios ovmf</code>. Required for Windows 11, Secure Boot, and most modern OS installs. Pair with an <code>efidisk0</code> to persist EFI variables.",
|
||||
"definitionRich": "UEFI firmware for VMs, selected with <code>qm set <vmid> -bios ovmf</code>. Used for UEFI guests, including Windows 11 and Secure Boot configurations. An <code>efidisk0</code> stores persistent EFI variables; many other guests can still use legacy BIOS.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Add GPU to VM (Passthrough)",
|
||||
@@ -415,7 +415,7 @@
|
||||
"Proxmox Backup Server"
|
||||
],
|
||||
"category": "Proxmox",
|
||||
"definitionRich": "Standalone product from Proxmox for incremental, deduplicated, encrypted VM / CT backups. Recommended over plain vzdump when you have a separate machine to host it on."
|
||||
"definitionRich": "Separate Proxmox backup product providing incremental transfers, deduplication and optional client-side encryption for VM and CT backups. It can be used as a vzdump destination; a separate backup server is preferable to keeping backups on the protected host."
|
||||
},
|
||||
{
|
||||
"term": "pct",
|
||||
@@ -466,7 +466,7 @@
|
||||
{
|
||||
"term": "Privileged container",
|
||||
"category": "Linux",
|
||||
"definitionRich": "LXC container where the root user inside the container <em>is</em> root on the host (UIDs not shifted). Required for hardware passthrough (USB devices, GPU sharing) and Samba / NFS server inside the CT. Less secure than unprivileged — use only when needed."
|
||||
"definitionRich": "LXC container whose root user <em>maps to host UID 0</em>, while namespaces and other restrictions still apply. Less isolated than an unprivileged container. GPU, USB and Samba access do not universally require this mode; permissions and UID mappings matter."
|
||||
},
|
||||
{
|
||||
"term": "ProxMenux Monitor",
|
||||
@@ -485,7 +485,7 @@
|
||||
"QEMU Copy-On-Write v2"
|
||||
],
|
||||
"category": "Storage",
|
||||
"definitionRich": "Default VM disk image format on Proxmox directory storage. Supports thin provisioning, snapshots, and copy-on-write. Convert with <code>qemu-img convert -O qcow2 ...</code>."
|
||||
"definitionRich": "VM disk image format commonly used on directory storage. Supports allocation on demand, snapshots and copy-on-write. Convert an image with <code>qemu-img convert -O qcow2 ...</code>."
|
||||
},
|
||||
{
|
||||
"term": "qm",
|
||||
@@ -514,7 +514,7 @@
|
||||
{
|
||||
"term": "rclone",
|
||||
"category": "Linux",
|
||||
"definitionRich": "Command-line tool that talks to ~50 cloud storage providers (Google Drive, Dropbox, OneDrive, Mega, S3, …). Used in the Proxmox cloud-backup guide to mount a personal cloud as a directory the host can write vzdump archives to.",
|
||||
"definitionRich": "Command-line tool supporting many cloud storage providers, including Google Drive, Dropbox, OneDrive, Mega and S3. The cloud-backup guide uses it to mount remote storage as a directory for vzdump archives.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Backup to Personal Cloud",
|
||||
@@ -564,7 +564,7 @@
|
||||
{
|
||||
"term": "sysctl",
|
||||
"category": "Linux",
|
||||
"definitionRich": "Kernel parameter management. Reads <code>/etc/sysctl.conf</code> + <code>/etc/sysctl.d/*.conf</code> at boot. ProxMenux Post-Install ships a curated sysctl tuning profile.",
|
||||
"definitionRich": "Tool for reading and changing kernel parameters. Persistent settings are commonly placed in <code>/etc/sysctl.d/*.conf</code>; support for <code>/etc/sysctl.conf</code> depends on the loader. ProxMenux Post-Install offers a sysctl tuning profile.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Post-Install: Network",
|
||||
@@ -594,7 +594,7 @@
|
||||
"UID shift"
|
||||
],
|
||||
"category": "Linux",
|
||||
"definitionRich": "In <strong>unprivileged</strong> LXC containers, UIDs and GIDs are shifted by <code>+100000</code> on the host. Container UID 0 = host UID 100000, container UID 1000 = host UID 101000, etc. Affects file ownership on bind mounts.",
|
||||
"definitionRich": "With the default mapping in <strong>unprivileged</strong> LXC containers, host UIDs and GIDs are shifted by <code>+100000</code>: container UID 0 maps to host UID 100000, and 1000 to 101000. Custom mappings can differ; file ownership on bind mounts must match the chosen mapping.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "LXC Mount Points",
|
||||
@@ -605,7 +605,7 @@
|
||||
{
|
||||
"term": "Unprivileged container",
|
||||
"category": "Linux",
|
||||
"definitionRich": "LXC container where root inside is mapped to an unprivileged UID on the host (UID shift +100000). Safer than privileged but can't do hardware passthrough or run kernel-level services. Default for most use cases."
|
||||
"definitionRich": "LXC container whose root maps to an unprivileged host UID, normally 100000. This reduces host privileges while sharing its kernel. Hardware access can still be configured with suitable device permissions and mappings; privileged mode is not universally required."
|
||||
},
|
||||
{
|
||||
"term": "VFIO",
|
||||
@@ -640,7 +640,7 @@
|
||||
"Virtual Machine"
|
||||
],
|
||||
"category": "Proxmox",
|
||||
"definitionRich": "A full machine emulation managed by Proxmox via QEMU/KVM. Has a numeric VMID that maps to <code>/etc/pve/qemu-server/<VMID>.conf</code>. Heavier than LXC containers but fully isolated.",
|
||||
"definitionRich": "Virtual machine managed by Proxmox with QEMU/KVM, running its own guest kernel. Its numeric VMID maps to <code>/etc/pve/qemu-server/<VMID>.conf</code>. Usually has more overhead than LXC, with a separate kernel isolation boundary.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "VM and CT Management",
|
||||
@@ -651,7 +651,7 @@
|
||||
{
|
||||
"term": "vzdump",
|
||||
"category": "Proxmox",
|
||||
"definitionRich": "Proxmox's built-in backup tool for VMs and CTs. <strong>Not incremental</strong> — every backup is a full snapshot. Configure modes (snapshot / suspend / stop), compression (zstd / pigz / lzo), retention and notification per job.",
|
||||
"definitionRich": "Proxmox backup tool for VMs and CTs. File archives are <strong>not incremental</strong>; PBS targets support incremental transfers. Jobs can configure backup mode (snapshot / suspend / stop), compression (such as zstd, gzip or lzo), retention and notifications.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "Backup and Restore commands",
|
||||
@@ -665,7 +665,7 @@
|
||||
"Zettabyte File System"
|
||||
],
|
||||
"category": "Storage",
|
||||
"definitionRich": "Combined filesystem and volume manager known for snapshots, send/receive replication, end-to-end checksums, compression and self-healing. Memory-hungry (see <strong>ARC</strong>) but extremely robust.",
|
||||
"definitionRich": "Combined filesystem and volume manager with snapshots, send/receive replication, checksums and compression. It can repair corrupted data when a valid redundant copy is available. Read caching uses RAM through <strong>ARC</strong>, whose size can be limited.",
|
||||
"seeAlso": [
|
||||
{
|
||||
"label": "ZFS Management commands",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "Three backup modes",
|
||||
"body": "<strong>snapshot</strong> uses a live snapshot — guest stays running, briefly pauses I/O. <strong>suspend</strong> freezes the VM during backup (safer than snapshot for non-snapshot-aware FS). <strong>stop</strong> shuts down the VM, backs up cold, restarts. Pick by guest tolerance and storage capability."
|
||||
"body": "For VMs, <strong>snapshot</strong> is a live backup and does not require storage snapshots. <strong>suspend</strong> pauses the VM before the live backup and does not necessarily improve consistency. <strong>stop</strong> shuts the VM down first; a previously running VM can resume once backup has started. LXC differs: snapshot mode requires snapshot-capable storage, suspend uses two rsync passes, and stop keeps the container stopped during backup."
|
||||
},
|
||||
"commandGroups": [
|
||||
{
|
||||
@@ -34,18 +34,18 @@
|
||||
},
|
||||
{
|
||||
"command": "vzdump <vmid> --mode suspend",
|
||||
"description": "Suspend VM during backup"
|
||||
"description": "Pause VM before the live backup (legacy suspend mode)"
|
||||
},
|
||||
{
|
||||
"command": "vzdump <vmid> --mode stop",
|
||||
"description": "Stop VM during backup"
|
||||
"description": "Shut down VM before starting the backup"
|
||||
},
|
||||
{
|
||||
"command": "vzdump --all",
|
||||
"description": "Backup all VMs and containers"
|
||||
},
|
||||
{
|
||||
"command": "vzdump --exclude <vmid1>,<vmid2>",
|
||||
"command": "vzdump --all --exclude <vmid1>,<vmid2>",
|
||||
"description": "Backup all except specified VMs"
|
||||
}
|
||||
]
|
||||
@@ -58,11 +58,11 @@
|
||||
"description": "Use zstd compression for backup"
|
||||
},
|
||||
{
|
||||
"command": "vzdump <vmid> --pigz <threads>",
|
||||
"command": "vzdump <vmid> --compress gzip --pigz <threads>",
|
||||
"description": "Use pigz with multiple threads"
|
||||
},
|
||||
{
|
||||
"command": "vzdump <vmid> --notes <text>",
|
||||
"command": "vzdump <vmid> --storage <storage> --notes-template <text>",
|
||||
"description": "Add notes to backup"
|
||||
},
|
||||
{
|
||||
@@ -70,7 +70,7 @@
|
||||
"description": "Send notification email"
|
||||
},
|
||||
{
|
||||
"command": "vzdump <vmid> --maxfiles <n>",
|
||||
"command": "vzdump <vmid> --prune-backups keep-last=<n>",
|
||||
"description": "Keep only n backups per VM"
|
||||
},
|
||||
{
|
||||
@@ -96,7 +96,7 @@
|
||||
},
|
||||
{
|
||||
"command": "qmrestore <backup-file> <vmid> --unique",
|
||||
"description": "Create a VM with unique ID"
|
||||
"description": "Restore VM with newly generated random MAC addresses"
|
||||
},
|
||||
{
|
||||
"command": "pct restore <vmid> <backup-file>",
|
||||
@@ -107,8 +107,8 @@
|
||||
"description": "Restore container to specific storage"
|
||||
},
|
||||
{
|
||||
"command": "pct restore <vmid> <backup-file> --rootfs <storage>",
|
||||
"description": "Restore to specific rootfs"
|
||||
"command": "pct restore <vmid> <backup-file> --rootfs <storage>:<size-GiB>",
|
||||
"description": "Restore with a root disk allocated on the chosen storage and size"
|
||||
},
|
||||
{
|
||||
"command": "pct restore <vmid> <backup-file> --unprivileged 1",
|
||||
@@ -132,7 +132,7 @@
|
||||
"description": "Find container backups"
|
||||
},
|
||||
{
|
||||
"command": "pvesm list <storage>",
|
||||
"command": "pvesm list <storage> --content backup",
|
||||
"description": "List backups in specific storage"
|
||||
},
|
||||
{
|
||||
@@ -149,7 +149,7 @@
|
||||
"title": "Scheduled Backups",
|
||||
"commands": [
|
||||
{
|
||||
"command": "cat /etc/cron.d/vzdump",
|
||||
"command": "cat /etc/pve/jobs.cfg",
|
||||
"description": "Show backup schedule"
|
||||
},
|
||||
{
|
||||
@@ -158,19 +158,19 @@
|
||||
},
|
||||
{
|
||||
"command": "systemctl list-timers",
|
||||
"description": "List all scheduled tasks"
|
||||
"description": "List systemd timers"
|
||||
},
|
||||
{
|
||||
"command": "systemctl status cron",
|
||||
"description": "Check cron service status"
|
||||
},
|
||||
{
|
||||
"command": "grep vzdump /var/log/syslog",
|
||||
"description": "Check backup logs in syslog"
|
||||
"command": "pvenode task list --typefilter vzdump",
|
||||
"description": "List completed backup tasks"
|
||||
},
|
||||
{
|
||||
"command": "tail -f /var/log/vzdump.log",
|
||||
"description": "Monitor backup log in real-time"
|
||||
"command": "pvenode task log <upid>",
|
||||
"description": "Show the log for a backup task UPID"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -202,15 +202,15 @@
|
||||
"description": "Wait for lock"
|
||||
},
|
||||
{
|
||||
"command": "qm importdisk <vmid> <backup> <storage>",
|
||||
"description": "Import disk from backup"
|
||||
"command": "qm importdisk <vmid> <disk-image> <storage>",
|
||||
"description": "Import a disk image file (for example raw, qcow2 or vmdk) as an unused disk, not a vzdump backup archive"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"testRestores": {
|
||||
"title": "Test your restores",
|
||||
"bodyRich": "A backup you've never restored isn't a backup. Periodically pick a backup, restore it to a test VMID with <code>qmrestore --unique</code>, boot the resulting VM and confirm the contents are intact. Same idea for containers via <code>pct restore</code>."
|
||||
"bodyRich": "Periodically restore a backup to an unused test VMID with <code>qmrestore --unique</code>, start the VM on an isolated test network and check its contents. The unique option generates new MAC addresses; it does not change static IPs or application settings. Test container restores with <code>pct restore</code> in the same way."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "IOMMU must be enabled in BIOS / UEFI",
|
||||
"body": "Before any of these commands matter, IOMMU has to be enabled at the firmware level (look for <em>VT-d</em>, <em>AMD-Vi</em> or <em>IOMMU</em> in BIOS / UEFI). Common GRUB parameters to enable it on the Linux side: <code>intel_iommu=on</code> (Intel) or <code>amd_iommu=on</code> (AMD), often combined with <code>iommu=pt video=efifb:off video=vesa:off</code>."
|
||||
"body": "Enable IOMMU in firmware first: look for <em>VT-d</em>, <em>AMD-Vi</em> or <em>IOMMU</em> in BIOS/UEFI. AMD enables IOMMU by default on the Linux side, as do Intel systems with Proxmox kernels 6.8 and newer. Older Intel kernels may need <code>intel_iommu=on</code>. The optional <code>iommu=pt</code> setting controls IOMMU passthrough mode; it is not a reason to disable the host framebuffer indiscriminately."
|
||||
},
|
||||
"commandGroups": [
|
||||
{
|
||||
@@ -130,14 +130,14 @@
|
||||
},
|
||||
{
|
||||
"command": "qm set <vmid> -bios ovmf",
|
||||
"description": "Set VM to use UEFI/OVMF (required for GPU passthrough)"
|
||||
"description": "Set VM to UEFI/OVMF (recommended when the GPU ROM supports UEFI)"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"afterChangesTip": {
|
||||
"title": "After changing GRUB or modprobe configs",
|
||||
"bodyRich": "Run <code>update-grub</code> + <code>update-initramfs -u</code>, then reboot. Verify with <code>cat /proc/cmdline</code> (kernel parameters), <code>dmesg | grep -i iommu</code> (IOMMU initialised) and <code>find /sys/kernel/iommu_groups/ -type l | sort -V</code> (groups present)."
|
||||
"bodyRich": "On hosts using GRUB, apply boot-option changes with <code>update-grub</code>. Refresh module changes with <code>update-initramfs -u -k all</code>, then reboot. Other bootloaders require their own configuration procedure. Verify with <code>cat /proc/cmdline</code> (kernel parameters), <code>dmesg | grep -i iommu</code> (IOMMU initialised) and <code>find /sys/kernel/iommu_groups/ -type l | sort -V</code> (groups present)."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
@@ -150,7 +150,7 @@
|
||||
{
|
||||
"href": "/docs/hardware/igpu-acceleration-lxc",
|
||||
"label": "Add GPU to LXC",
|
||||
"tail": " — passthrough to a container instead of a VM."
|
||||
"tail": " — share host GPU device access with an LXC container."
|
||||
},
|
||||
{
|
||||
"href": "/docs/help-info",
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
],
|
||||
"iptablesTip": {
|
||||
"title": "iptables vs nftables",
|
||||
"bodyRich": "Modern Debian / Proxmox uses <strong>nftables</strong> as the underlying firewall engine. The classic <code>iptables -L -n -v</code> command still works as a translation layer, but the source of truth is <code>nft list ruleset</code>. <code>pve-firewall</code> commands are Proxmox's wrapper that emits nftables rules from the cluster firewall config."
|
||||
"bodyRich": "The classic <code>pve-firewall</code> service generates iptables rules. The alternative proxmox-firewall service uses <strong>nftables</strong>. Inspect the iptables-based backend with <code>iptables -L -n -v</code> and the nftables backend with <code>nft list ruleset</code>. Use the tools for the enabled backend; do not assume these listings are interchangeable."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "Quick disk inventory",
|
||||
"body": "<code>lsblk</code> is the fastest way to see all block devices and their partitions in a tree view. For persistent identifiers (which survive between boots and hardware changes) use <code>ls -lh /dev/disk/by-id/</code>."
|
||||
"body": "<code>lsblk</code> shows block devices and partitions in a tree. Inspect persistent identifiers with <code>ls -lh /dev/disk/by-id/</code>: these normally remain stable across reboots and device reordering for the same disk. Replacing a disk or changing the way a controller exposes its identity can change its by-id path."
|
||||
},
|
||||
"commandGroups": [
|
||||
{
|
||||
@@ -104,16 +104,16 @@
|
||||
"description": "Show status of all storage pools"
|
||||
},
|
||||
{
|
||||
"command": "pvesm list",
|
||||
"description": "List all available storage"
|
||||
"command": "pvesm status --enabled 1",
|
||||
"description": "List enabled configured storage"
|
||||
},
|
||||
{
|
||||
"command": "pvesm list <storage>",
|
||||
"description": "List content of specific storage"
|
||||
},
|
||||
{
|
||||
"command": "pvesm scan <storage>",
|
||||
"description": "Scan storage for new content"
|
||||
"command": "pvesm scan nfs <server>",
|
||||
"description": "Discover NFS exports on a server"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -122,7 +122,7 @@
|
||||
"commands": [
|
||||
{
|
||||
"command": "qm importdisk <vmid> <image_path> <storage>",
|
||||
"description": "Attach disk image to VM"
|
||||
"description": "Import disk image as an unused disk for the VM; attach it separately"
|
||||
},
|
||||
{
|
||||
"command": "qm set <vmid> -<bus><index> <disk_path>",
|
||||
@@ -130,7 +130,7 @@
|
||||
},
|
||||
{
|
||||
"command": "qemu-img convert -O <format> <input> <output>",
|
||||
"description": "Convert disk image format"
|
||||
"description": "Convert an offline disk image format"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -199,15 +199,15 @@
|
||||
],
|
||||
"lvmTip": {
|
||||
"title": "LVM short vs long commands",
|
||||
"bodyRich": "Both forms exist for compatibility. <code>pvs</code> / <code>vgs</code> / <code>lvs</code> give a clean single-line-per-volume table; <code>pvdisplay</code> / <code>vgdisplay</code> / <code>lvdisplay</code> give a verbose multi-line dump per volume. For day-to-day use prefer the short versions."
|
||||
"bodyRich": "Both forms are available. <code>pvs</code> / <code>vgs</code> / <code>lvs</code> produce compact tables with one row per physical volume, volume group or logical volume respectively. <code>pvdisplay</code> / <code>vgdisplay</code> / <code>lvdisplay</code> provide more detailed multi-line output. The short forms are convenient for everyday checks."
|
||||
},
|
||||
"smartInfo": {
|
||||
"title": "SMART for spinning disks vs NVMe",
|
||||
"bodyRich": "<strong>Spinning / SATA / SAS disks</strong> use the <code>smartctl</code> family from <code>smartmontools</code> (installed by default on Proxmox). Pass the device as <code>/dev/sda</code>, <code>/dev/sdb</code>, etc. <strong>NVMe disks</strong> have their own native protocol — <code>smartctl</code> works against them (passes most data through), but the <code>nvme</code> tool from <code>nvme-cli</code> reports more NVMe-specific fields (wear levelling, media errors, namespace info). Install with <code>apt install nvme-cli</code> if not present."
|
||||
"title": "SMART for SATA/SAS vs NVMe",
|
||||
"bodyRich": "<strong>SATA / SAS disks, including SSDs,</strong> can be inspected with <code>smartctl</code> from <code>smartmontools</code> (installed by default on Proxmox). Specify the device, for example <code>/dev/sda</code> or <code>/dev/sdb</code>. <strong>NVMe disks</strong> use a different native protocol. <code>smartctl</code> also supports them, while <code>nvme</code> from <code>nvme-cli</code> provides NVMe-specific controller, namespace and health queries. Install it with <code>apt install nvme-cli</code> if absent."
|
||||
},
|
||||
"selfTestWarn": {
|
||||
"title": "Self-tests run in the background",
|
||||
"bodyRich": "<code>smartctl -t short</code> and <code>-t long</code> return immediately — the disk runs the test on its own. Check progress with <code>smartctl -a /dev/<disk></code> (look for the \"Self-test routine in progress\" line) or wait for completion and read <code>smartctl -l selftest /dev/<disk></code>. Short tests take ~2 min; long tests can take hours on large spinners. The disk stays usable during the test, but I/O performance drops."
|
||||
"bodyRich": "On supported drives, <code>smartctl -t short /dev/<disk></code> and <code>smartctl -t long /dev/<disk></code> start background tests and return immediately. Check progress with <code>smartctl -a /dev/<disk></code> (look for \"Self-test routine in progress\") or wait and read <code>smartctl -l selftest /dev/<disk></code>. Short tests commonly take about two minutes; long tests can take hours. The disk remains usable, but testing can reduce I/O performance."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Proxmox VE System Commands — pveversion, uptime, journalctl, systemctl | ProxMenux",
|
||||
"description": "Reference of essential Proxmox VE and Linux system commands: pveversion, pveperf, uptime, journalctl, systemctl, lscpu, lsblk, df, free, last, who. All read-only and safe to run on any host.",
|
||||
"description": "Proxmox VE and Linux system commands for versions, uptime, memory, services, logs and users, plus auditing and summary tools. Includes a service restart command; not every example is read-only.",
|
||||
"ogTitle": "Proxmox VE System Commands — pveversion, uptime, journalctl, systemctl",
|
||||
"ogDescription": "Reference of essential Proxmox VE and Linux system commands — version, uptime, services, logs, user info, hardware probes. All read-only.",
|
||||
"ogDescription": "Proxmox VE and Linux system commands for version, uptime, services, logs and user information, including service management and auditing tools.",
|
||||
"twitterTitle": "Proxmox VE System Commands | ProxMenux",
|
||||
"twitterDescription": "Essential system inspection commands for Proxmox VE — version, status, services, logs, user info."
|
||||
},
|
||||
"header": {
|
||||
"title": "Useful System Commands",
|
||||
"description": "Read-only commands to look at the Proxmox host: version, kernel, uptime, memory, web UI status, recent log lines, who's logged in, and a couple of audit / summary tools. None of them modifies the system.",
|
||||
"description": "Commands for inspecting the Proxmox host: version, kernel, uptime, memory, web UI status, recent logs and logged-in users, plus auditing and summary tools. Most inspect state, but systemctl restart pveproxy restarts the web UI proxy, and audit tools can write reports and logs.",
|
||||
"section": "Help and Info"
|
||||
},
|
||||
"intro": {
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
],
|
||||
"tmuxTip": {
|
||||
"title": "Use tmux / screen for long-running commands",
|
||||
"bodyRich": "Anything that takes longer than a coffee break — a backup, a long upgrade, a big rsync — should run inside <code>tmux</code> or <code>screen</code>. SSH disconnects don't kill the session, and you can re-attach from anywhere with <code>tmux attach</code>."
|
||||
"bodyRich": "Long-running work — a backup, a lengthy upgrade or a large rsync transfer — should run inside <code>tmux</code> or <code>screen</code> so an SSH disconnect does not end the terminal session. For a tmux session, reconnect to the same host as the same user and run <code>tmux attach</code>. Screen sessions use their own reattachment command."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"commands": [
|
||||
{
|
||||
"command": "apt update && apt upgrade -y",
|
||||
"description": "Update and upgrade all system packages"
|
||||
"description": "Refresh package lists and upgrade installed packages (apt upgrade)"
|
||||
},
|
||||
{
|
||||
"command": "apt dist-upgrade -y",
|
||||
@@ -51,15 +51,15 @@
|
||||
},
|
||||
{
|
||||
"command": "pveupgrade",
|
||||
"description": "Show available Proxmox upgrades"
|
||||
"description": "Start the interactive Proxmox package upgrade"
|
||||
},
|
||||
{
|
||||
"command": "pve-upgrade",
|
||||
"description": "Perform Proxmox VE upgrade"
|
||||
"command": "pve8to9 --full",
|
||||
"description": "Check readiness for the PVE 8 to 9 upgrade (does not perform it)"
|
||||
},
|
||||
{
|
||||
"command": "pveceph upgrade",
|
||||
"description": "Upgrade Ceph packages (if Ceph is installed)"
|
||||
"command": "ceph versions",
|
||||
"description": "Show Ceph daemon versions before planning a Ceph upgrade"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -134,18 +134,18 @@
|
||||
},
|
||||
{
|
||||
"command": "cat /etc/apt/sources.list.d/pve-enterprise.list",
|
||||
"description": "Show Proxmox Enterprise repo config"
|
||||
"description": "Show Proxmox Enterprise repository configuration in the PVE 8 .list file"
|
||||
},
|
||||
{
|
||||
"command": "apt-key list",
|
||||
"description": "List repository signing keys"
|
||||
"description": "List legacy repository signing keys where apt-key is available"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"backupWarn": {
|
||||
"title": "Take a backup before major upgrades",
|
||||
"bodyRich": "For point releases (8.4.1 → 8.4.5) the standard <code>apt update && apt upgrade</code> is safe. For <strong>major version upgrades</strong> (PVE 8 → 9) use the dedicated ProxMenux flow: <upgradeLink>Upgrade PVE 8 to PVE 9</upgradeLink> — it adds pre-flight checks, repository migration and post-upgrade validation."
|
||||
"bodyRich": "For routine updates, Proxmox recommends <code>apt update && apt full-upgrade</code>; review the proposed package changes before confirming. For <strong>major version upgrades</strong> (PVE 8 → 9), use the dedicated ProxMenux flow: <upgradeLink>Upgrade PVE 8 to PVE 9</upgradeLink>. It adds readiness checks, repository migration and post-upgrade validation. Back up first."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"description": "Gracefully shutdown a container"
|
||||
},
|
||||
{
|
||||
"command": "pct restart <ctid>",
|
||||
"command": "pct reboot <ctid>",
|
||||
"description": "Restart a container"
|
||||
},
|
||||
{
|
||||
@@ -153,11 +153,11 @@
|
||||
],
|
||||
"destroyWarn": {
|
||||
"title": "Destroy is irreversible",
|
||||
"bodyRich": "<code>qm destroy</code> and <code>pct destroy</code> delete the VM / CT and all its disks. There is no confirmation prompt by default. Take a backup first if there's any chance you might want the data back — see <backupLink>Backup and Restore</backupLink>."
|
||||
"bodyRich": "<code>qm destroy</code> and <code>pct destroy</code> remove the guest configuration and its managed disk volumes. Do not assume that external or bind-mounted data is deleted. The CLI has no confirmation prompt by default. Back up any data you may need before running it; see <backupLink>Backup and Restore</backupLink>."
|
||||
},
|
||||
"qmConfigTip": {
|
||||
"title": "qm config vs editing the .conf file directly",
|
||||
"bodyRich": "<code>qm config <vmid></code> and <code>pct config <ctid></code> read the file through Proxmox's own parser — output is normalised, comments stripped, pending changes shown separately. Editing <code>/etc/pve/qemu-server/<vmid>.conf</code> or <code>/etc/pve/lxc/<ctid>.conf</code> directly bypasses the parser. Useful for fixing a corrupted config or applying a setting <code>qm set</code> won't accept, but stop the guest first to avoid races. The cluster filesystem (<code>pmxcfs</code>) takes care of propagating the change to other nodes."
|
||||
"bodyRich": "<code>qm config <vmid></code> and <code>pct config <ctid></code> display configuration through Proxmox’s parsers. For normal changes, prefer <code>qm set</code> or the corresponding pct setter. Direct edits to <code>/etc/pve/qemu-server/<vmid>.conf</code> or <code>/etc/pve/lxc/<ctid>.conf</code> bypass the validation and locking in management commands; the file must still remain parseable. Stop the guest and keep a copy before manual repair. <code>pmxcfs</code> synchronises configuration across cluster nodes, not guest disk contents."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
],
|
||||
"bestPractices": {
|
||||
"title": "Operational best practices",
|
||||
"bodyRich": "Run <code>zpool scrub</code> weekly or monthly to detect silent corruption. Keep at least 10-15% of pool space free — ZFS performance degrades sharply over 80% full. Always replace failed devices with <code>zpool replace</code> (in-place) rather than detach + add (which loses redundancy temporarily)."
|
||||
"bodyRich": "Schedule <code>zpool scrub</code> regularly to verify checksums and inspect its results. Keep free capacity: the impact of a nearly full pool depends on workload and layout. Use <code>zpool replace</code> for a failed device and follow the procedure for its vdev type. Detach + add is not an equivalent replacement procedure and can alter topology or remove redundancy."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Installing ProxMenux | ProxMenux Documentation",
|
||||
"description": "One-line installer for ProxMenux on Proxmox VE 8+ hosts. Ships pre-generated translation files for six languages (English, Spanish, French, German, Italian, Portuguese) — the language is picked once during installation. Beta channel also available for early access to new features.",
|
||||
"description": "One-command installer for ProxMenux on Proxmox VE 8+ hosts. Includes pre-generated JSON catalogs for eight languages: English, Spanish, French, German, Italian, Portuguese, Slovak and Swedish. Choose a language during installation or change it later in Settings. A beta channel provides early access to new features.",
|
||||
"ogTitle": "Installing ProxMenux | ProxMenux Documentation",
|
||||
"ogDescription": "Install ProxMenux on Proxmox VE 8+ in one command. Stable and beta channels available."
|
||||
},
|
||||
@@ -61,12 +61,12 @@
|
||||
},
|
||||
"uninstall": {
|
||||
"heading": "Uninstalling",
|
||||
"body": "From inside ProxMenux: <strong>Settings → Uninstall ProxMenux</strong>. Removes the script tree, launcher and Monitor service, optionally removes selected dependencies, restores <code>/root/.bashrc</code> and <code>/etc/motd</code> backups taken at install time. Full step-by-step: <uninstalllink>Uninstall ProxMenux</uninstalllink>."
|
||||
"body": "From inside ProxMenux: <strong>Settings → Uninstall ProxMenux</strong>. Removes the script tree, launcher and Monitor service, optionally removes selected dependencies, and restores <code>/root/.bashrc</code> and <code>/etc/motd</code> from the backups created by Post-Install, if they exist (otherwise it removes the ProxMenux MOTD line). Full step-by-step: <uninstalllink>Uninstall ProxMenux</uninstalllink>."
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"virustotalTitle": "VirusTotal flags the install URL",
|
||||
"virustotalBody": "A 1/95 detection by heuristic engines (e.g. <em>Chong Lua Dao</em>) is a known false positive. The installer uses the standard <code>curl | bash</code> pattern and downloads legitimate binaries (like <code>jq</code> from its official GitHub release), which aggressive scanners flag based on <em>behaviour</em> rather than actual malicious code. The installer is 100% open source and reviewable. More context in <issuelink>Issue #162</issuelink>.",
|
||||
"virustotalBody": "The 1/95 result from <em>Chong Lua Dao</em> reported in Issue #162 was identified by the maintainer as a false positive. The installer is run with a command that downloads and executes the script (<code>bash -c \"$(wget -qLO - …)\"</code>) and can download <code>jq</code> from its official GitHub release. This <em>behaviour</em> can trigger heuristic scanners. That historical report does not assess every future download. The installer is open source and reviewable. More context in <issuelink>Issue #162</issuelink>.",
|
||||
"aptTitle": "Install fails with apt errors",
|
||||
"aptBody": "Usually a missing or misconfigured Proxmox repo. The installer pulls dependencies via apt; if the repo config is broken (often the case on bare-bones Proxmox 8 installs that haven't been updated yet), apt fails. Run <code>apt-get update</code> manually first and resolve any errors, then re-run the installer.",
|
||||
"menuTitle": "`menu: command not found` after install",
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
},
|
||||
"twoProducts": {
|
||||
"heading": "Two products, one project",
|
||||
"intro": "ProxMenux ships as two independent pieces sharing the same source tree. The installer deploys both — they live side by side on the host and don't depend on each other:",
|
||||
"intro": "ProxMenux has two components in the same source tree. The installer deploys both on the host: Scripts provides the terminal interface, and Monitor provides the web dashboard:",
|
||||
"scripts": {
|
||||
"title": "ProxMenux Scripts",
|
||||
"body": "The original CLI/TUI you launch with <code>menu</code>. Nine functional areas covering post-install optimizations, VM and LXC creation, GPU and Coral TPU passthrough, disks, storage, network, security, utilities, plus a curated commands reference. Runs in any terminal — local, SSH or web."
|
||||
@@ -113,7 +113,7 @@
|
||||
},
|
||||
{
|
||||
"title": "AI Assistant",
|
||||
"description": "Optional rewrite of notifications in plain language. Six providers: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter, local Ollama. Twelve languages.",
|
||||
"description": "Optional rewrite of notifications in plain language. Six providers: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter, local Ollama. Thirteen languages in the AI language selector.",
|
||||
"icon": "Sparkles",
|
||||
"href": "/docs/monitor/ai-assistant"
|
||||
},
|
||||
@@ -139,24 +139,24 @@
|
||||
},
|
||||
"installPaths": {
|
||||
"heading": "Install paths",
|
||||
"intro": "The installer deploys Scripts and Monitor in one go. Scripts has two flavours — translation or lightweight — and the Monitor is installed as a standalone AppImage you enable from the menu later:",
|
||||
"intro": "Both installers deploy Scripts and Monitor. Scripts uses pre-generated JSON catalogs in eight languages, without online translation. Choose the stable or beta channel; Monitor is packaged as an AppImage and runs from its extracted runtime:",
|
||||
"headerPath": "Install path",
|
||||
"headerBundles": "What it bundles",
|
||||
"headerWhen": "When you'd pick it",
|
||||
"rows": [
|
||||
{
|
||||
"pathRich": "<strong>Scripts: Translation</strong>",
|
||||
"bundles": "CLI/TUI + Python venv + googletrans (English, Spanish, French, German, Italian, Portuguese)",
|
||||
"when": "Multi-language menus, non-English speakers"
|
||||
"pathRich": "<strong>Scripts: stable</strong>",
|
||||
"bundles": "CLI/TUI with pre-generated JSON translations in eight languages; no translation venv or online translation service.",
|
||||
"when": "Normal use with the stable release channel."
|
||||
},
|
||||
{
|
||||
"pathRich": "<strong>Scripts: Normal (lightweight)</strong>",
|
||||
"bundles": "CLI/TUI English-only, smaller footprint, no Python venv",
|
||||
"when": "Most users — Proxmox docs are English anyway"
|
||||
"pathRich": "<strong>Scripts: beta</strong>",
|
||||
"bundles": "The same multilingual interface, installed from the develop branch for testing upcoming changes.",
|
||||
"when": "Early testing of new features, with a greater risk of bugs."
|
||||
},
|
||||
{
|
||||
"pathRich": "<strong>Monitor</strong>",
|
||||
"bundles": "Self-contained AppImage on TCP 8008. Independent install — can be enabled from the Scripts menu, or run the AppImage directly.",
|
||||
"bundles": "Self-contained AppImage with a web dashboard on TCP 8008. The installer extracts its runtime and manages the service; Monitor can be controlled from Settings.",
|
||||
"when": "When a web dashboard for the host is useful — phone, tablet, browser tab"
|
||||
}
|
||||
],
|
||||
@@ -187,7 +187,7 @@
|
||||
"lead": "<strong>Want a web dashboard?</strong> ",
|
||||
"linkHref": "/docs/monitor",
|
||||
"linkLabel": "ProxMenux Monitor",
|
||||
"tail": " covers what it shows, how it's built and how to secure it."
|
||||
"tail": " documentation explains what it shows, how it is built and how to secure it."
|
||||
},
|
||||
{
|
||||
"lead": "<strong>Looking for a specific command?</strong> ",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
},
|
||||
"header": {
|
||||
"title": "Live monitoring tools",
|
||||
"description": "Three interactive launchers for real-time network observation and bandwidth measurement: iftop, iptraf-ng and iperf3. Each tool is auto-installed from apt on first use, runs in the foreground, and is exited with the documented keystroke. Read-only against the host configuration — they only observe traffic.",
|
||||
"description": "Three interactive launchers for real-time network observation and bandwidth measurement: iftop, iptraf-ng and iperf3. Each tool is auto-installed from apt on first use, runs in the foreground, and is exited with the documented keystroke. They do not change the host network configuration; iperf3 generates test traffic.",
|
||||
"section": "Network"
|
||||
},
|
||||
"intro": {
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
"list": {
|
||||
"items": [
|
||||
"A Dockerfile without a published image: the image has to be built and published in an OCI registry first.",
|
||||
"A Compose file with several services: it is blocked because it describes more than one image. This option installs a single container.",
|
||||
"A Compose file with several services is blocked: this option installs one service in one container at a time, even when several services use the same image.",
|
||||
"<code>configs</code>, external secrets or device formats that cannot be translated unambiguously.",
|
||||
"Shell substitutions such as <code>$(command)</code>: the resulting value has to be written instead.",
|
||||
"<code>docker run</code> options that are not recognised, and <code>--env-file</code>: an explicit Compose file is read instead."
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
{
|
||||
"id": "restore",
|
||||
"title": "Backup, restore and another host",
|
||||
"intro": "A backup made with vzdump or Proxmox Backup Server includes the container, its disks and the copy of its contract. What the installation keeps on the host is not part of it. <strong>Manage installed OCI applications</strong> detects the containers restored on a host that has no contract for them, a new Proxmox installation or another host, and offers to register them again.",
|
||||
"intro": "A backup made with vzdump or Proxmox Backup Server includes the container, the container disks selected for backup and the copy of its contract. What the installation keeps on the host is not part of it. <strong>Manage installed OCI applications</strong> detects the containers restored on a host that has no contract for them, a new Proxmox installation or another host, and offers to register them again.",
|
||||
"blocks": [
|
||||
{
|
||||
"steps": {
|
||||
@@ -462,7 +462,7 @@
|
||||
],
|
||||
[
|
||||
"Container disks",
|
||||
"Proxmox moves them with the container. HA needs them on shared storage."
|
||||
"Proxmox moves them with the container. HA needs their data available on the target node, through shared storage or a supported replication setup."
|
||||
],
|
||||
[
|
||||
"Host directories and devices",
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
["OCI rootfs", "Yes", "The CT backup; it can also be rebuilt from the image and the contract"],
|
||||
["Container disk with <code>backup=1</code>", "Yes", "The CT backup"],
|
||||
["Host directory", "No", "The backup of the host storage"],
|
||||
["Instance contract", "No", "<code>/usr/local/share/proxmenux/oci/instances/VMID/</code> on the host"],
|
||||
["Instance contract", "Yes, the copy carried inside the CT", "<code>/.proxmenux/oci-record.json</code> inside the CT; additional host and cluster copies are kept separately"],
|
||||
["Multi-container application", "Each member in its own backup", "The backups of every member, plus the stack contract and its bridge on the host"]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Automated Post-Install Script | ProxMenux Documentation",
|
||||
"description": "The ProxMenux Automated post-install script applies a curated set of 14 safe, hardware-aware optimizations to a fresh Proxmox VE host with zero prompts. Reversible configuration changes are registered for later restoration.",
|
||||
"description": "The ProxMenux Automated post-install script runs a fixed set of 14 hardware-aware optimizations on a fresh Proxmox VE host. It has no feature-selection checklist, but the system update, banner removal, some Log2RAM installations and rebooting can ask for confirmation. Reversible configuration changes are registered for later restoration.",
|
||||
"ogTitle": "Automated Post-Install Script | ProxMenux Documentation",
|
||||
"ogDescription": "14 curated optimizations applied to a fresh Proxmox VE host with zero prompts. Hardware-aware, with reversible configuration changes tracked."
|
||||
"ogDescription": "14 fixed, hardware-aware optimizations for a fresh Proxmox VE host, with confirmations for some actions and reversible configuration changes tracked."
|
||||
},
|
||||
"header": {
|
||||
"title": "Automated Post-Install Script",
|
||||
"description": "One click, zero prompts — ProxMenux applies a curated set of 14 safe optimizations that almost every Proxmox host benefits from. Reversible configuration changes are registered for Uninstall Optimizations; package upgrades are not described as reversible.",
|
||||
"description": "ProxMenux runs a fixed set of 14 baseline optimizations without a feature-selection checklist. Some actions still ask for confirmation. Reversible configuration changes are registered for Uninstall Optimizations; package upgrades are not described as reversible.",
|
||||
"section": "Post-Install · Automated"
|
||||
},
|
||||
"intro": {
|
||||
@@ -43,7 +43,7 @@
|
||||
},
|
||||
{
|
||||
"tool": "Skip language packages",
|
||||
"what": "Writes /etc/apt/apt.conf.d/99-disable-translations to stop downloading locale-specific packages. Faster, lighter apt updates.",
|
||||
"what": "Writes /etc/apt/apt.conf.d/99-disable-translations to stop downloading translated package-description indexes, reducing the data fetched by apt updates.",
|
||||
"category": "Basic Settings",
|
||||
"categorySlug": "basic-settings"
|
||||
},
|
||||
@@ -97,7 +97,7 @@
|
||||
},
|
||||
{
|
||||
"tool": "Logrotate tuning",
|
||||
"what": "Daily rotation with size cap 10M, 7 rotations, compression and copytruncate — Log2RAM-friendly.",
|
||||
"what": "Sets daily and then size 10M globally, keeps 7 rotations, enables compression and copytruncate. The later size criterion takes precedence; per-log rules may override it. Suitable for Log2RAM, but rotation frequency depends on the rules and timer.",
|
||||
"category": "System",
|
||||
"categorySlug": "system"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
],
|
||||
"officialTitle": "The official Proxmox recommendation",
|
||||
"officialBody": "Proxmox's own upgrade guidance is to run, in this exact order:",
|
||||
"officialOutro": "That single line is all you need on any current Proxmox release. The challenge isn't the command itself — it's making sure the repositories on the host are sane <em>before</em> running it.",
|
||||
"officialOutro": "For routine updates within the installed Proxmox VE major version, this is the usual command. Check the host’s repositories and review the proposed package changes <em>before</em> proceeding. Upgrading to another major version requires the official migration procedure.",
|
||||
"doesTitle": "What the ProxMenux option does — verified against the script",
|
||||
"doesIntro": "The ProxMenux update wraps the exact apt commands above and adds a number of pre/post steps you would otherwise have to remember by hand. Every item below is what the dispatcher script actually does (see <link>Proxmox System Update</link> for the full breakdown):",
|
||||
"doesItems": [
|
||||
@@ -59,7 +59,7 @@
|
||||
},
|
||||
"languages": {
|
||||
"heading": "Skip downloading additional languages",
|
||||
"intro": "On every <code>apt update</code>, Debian by default pulls translation files for every locale it ships — a lot of traffic and disk space for something you'll rarely see. This option tells APT to only fetch the main metadata. Before disabling, ProxMenux <strong>makes sure the host's own locale is actually generated</strong> (reads <code>/etc/default/locale</code> or <code>/etc/environment</code>, appends to <code>/etc/locale.gen</code> if missing, and runs <code>locale-gen</code>). So you don't lose your shell locale as a side effect.",
|
||||
"intro": "During <code>apt update</code>, APT can download translated package descriptions as well as the main metadata. This option disables those translation downloads to save bandwidth and disk space. Before disabling them, ProxMenux <strong>makes sure the host’s own locale is actually generated</strong> (reads <code>/etc/default/locale</code> or <code>/etc/environment</code>, appends to <code>/etc/locale.gen</code> if missing, and runs <code>locale-gen</code>). So you do not lose your shell locale as a side effect.",
|
||||
"writtenTitle": "What gets written",
|
||||
"revertTitle": "Reversible from the Uninstall menu",
|
||||
"revertBody": "Deleting <code>/etc/apt/apt.conf.d/99-disable-translations</code> (either manually or from the Uninstall menu) restores the default behaviour and APT downloads language files again."
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
},
|
||||
"header": {
|
||||
"title": "Customizable Post-Install Script",
|
||||
"description": "Cherry-pick exactly which optimizations to apply to a Proxmox VE host. ProxMenux groups ~35 individual tools into 10 categories, each with its own checklist dialog. Same engine as Automated, but with full control over what gets applied.",
|
||||
"description": "Cherry-pick exactly which optimizations to apply to a Proxmox VE host. ProxMenux groups ~35 individual tools into 10 categories in one checklist dialog. Same engine as Automated, but with full control over what gets applied.",
|
||||
"section": "Post-Install · Customizable"
|
||||
},
|
||||
"intro": {
|
||||
"title": "When to pick Customizable",
|
||||
"body": "Choose this path when you already know which tweaks you want on the host — or which you definitely do not want. The script presents a checklist per category so you can pre-select, deselect or mix-and-match optimizations. Items can be applied again later, and reversible configuration changes are tracked for <link>Uninstall Optimizations</link>. Package upgrades are not presented as reversible."
|
||||
"body": "Choose this path when you already know which tweaks you want on the host — or which you definitely do not want. The script presents a checklist grouped by category so you can pre-select, deselect or mix-and-match optimizations. Items can be applied again later, and reversible configuration changes are tracked for <link>Uninstall Optimizations</link>. Package upgrades are not presented as reversible."
|
||||
},
|
||||
"compare": {
|
||||
"heading": "How it compares to Automated",
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"categoriesSection": {
|
||||
"heading": "The 10 categories",
|
||||
"body": "The Customizable script groups optimizations into 10 categories. Each category has its own checklist dialog and its own documentation page — open one of the cards below for the per-option rationale, defaults and verification steps."
|
||||
"body": "The Customizable script groups optimizations into 10 categories in one checklist dialog. Each category has its own documentation page — open one of the cards below for the per-option rationale, defaults and verification steps."
|
||||
},
|
||||
"categories": [
|
||||
{
|
||||
@@ -33,7 +33,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Virtualization",
|
||||
"description": "Prepare the host for advanced virtualization. Auto-installs the guest agent on templates and enables IOMMU/VFIO for PCI passthrough of GPUs, controllers and TPUs."
|
||||
"description": "Prepare the host for advanced virtualization. Installs a matching guest agent when Proxmox itself runs inside a supported VM, and enables IOMMU/VFIO for PCI passthrough of GPUs, controllers and TPUs."
|
||||
},
|
||||
{
|
||||
"name": "Network",
|
||||
@@ -53,7 +53,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Monitoring",
|
||||
"description": "Integrate the host with OVH Real-Time Monitoring. Only appears when ProxMenux detects an OVH server."
|
||||
"description": "Integrate the host with OVH Real-Time Monitoring. Installs RTM only when ProxMenux detects an OVH server; on other hosts the option makes no changes."
|
||||
},
|
||||
{
|
||||
"name": "Performance",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"breakTitle": "Can break after Proxmox updates",
|
||||
"breakBody": "Proxmox regularly ships UI updates that overwrite <code>proxmoxlib.js</code>. When that happens, the banner comes back. You can re-apply this option after every Proxmox update to re-patch the file, or just accept the nag until you reapply. ProxMenux also installs an APT hook that auto-re-patches on package upgrades — see <link>Uninstall Optimizations</link> for how that hook is reversed.",
|
||||
"legalTitle": "Legal note (always worth repeating)",
|
||||
"legalBody": "This option only hides the UI nag. It does <strong>not</strong> grant you enterprise support, access to the enterprise repository, or any rights to ship Proxmox commercially without a subscription. If you run Proxmox in a revenue-generating environment, buy a subscription — it supports the project and gets you the stable enterprise channel."
|
||||
"legalBody": "This option only hides the UI notice. It does <strong>not</strong> grant enterprise support or access to the enterprise repository, and it does not change the software license. Proxmox VE is released under the GNU AGPLv3. A subscription supports the project and provides access to the enterprise update channel; choose the appropriate support level for your environment."
|
||||
},
|
||||
"verify": {
|
||||
"heading": "Verification",
|
||||
|
||||
@@ -78,6 +78,17 @@
|
||||
"heading": "Community scripts",
|
||||
"body": "The menu also exposes two third-party scripts from the <a>community-scripts</a> project: <em>Proxmox VE Post Install</em> and <em>Proxmox VE Microcode</em>. These are wrappers that <code>wget | bash</code> the original authors' scripts. They are not maintained by ProxMenux. See <link>External Repositories</link> for details and trust considerations before running them."
|
||||
},
|
||||
"pbs": {
|
||||
"heading": "On Proxmox Backup Server",
|
||||
"body": "On a Proxmox Backup Server host, the same menu opens from <strong>Settings post-install Proxmox</strong> in the PBS menu. Automated, Customizable, Apply Available Updates and Uninstall Optimizations work as on Proxmox VE, with these differences:",
|
||||
"items": [
|
||||
"<strong>Repositories and upgrade:</strong> when the server has no subscription and only the Enterprise PBS repository is active, ProxMenux asks before switching to the PBS no-subscription repository. The switch goes through the server's own repository API, the same one behind <em>Administration > Repositories</em>. With an active subscription, or with a no-subscription or test repository already configured, the sources stay as they are.",
|
||||
"<strong>Customizable list:</strong> the options that only apply to Proxmox VE are not listed: guest agent, VFIO IOMMU, Open vSwitch, vzdump backup speed, pigz, Appliance Manager, Ceph, High Availability and OVH Real Time Monitoring.",
|
||||
"<strong>Subscription banner:</strong> the patch applies to the Proxmox Backup Server web interface, and Uninstall Optimizations restores it.",
|
||||
"<strong>Figurine:</strong> installs without the Proxmox VE aliases.",
|
||||
"<strong>Community scripts:</strong> the section offers <em>Proxmox Backup Server Post Install</em> and <em>Proxmox Backup Server Microcode</em> in place of the Proxmox VE scripts."
|
||||
]
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
"items": [
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
"verifyTitle": "Verification",
|
||||
"verifyBody": "On a real OVH host, after a reboot you should see the <a>RTM dashboard</a> in your OVH Manager populated with live data for the host. On the Proxmox side, the RTM collector is a systemd service — check it directly:",
|
||||
"troubleTitle": "Troubleshooting",
|
||||
"revertTitle": "Not reversible from the Uninstall menu",
|
||||
"revertBody": "There is no dedicated uninstall entry for RTM. On a real OVH host, remove the packages manually with <code>apt purge ovh-*</code> and delete any puppet manifests under <code>/etc/puppet/</code> that RTM installed. On a non-OVH host, nothing was ever installed, so there's nothing to revert."
|
||||
"revertTitle": "Remove RTM from the Uninstall menu",
|
||||
"revertBody": "When RTM is registered as installed, Uninstall Optimizations offers an OVH Real-Time Monitoring entry. It runs <code>apt-get purge -y ''ovh-rtm*'' ''rtm'' ''rtm-*''</code>, removes /etc/rtm, and marks RTM as uninstalled. Puppet artefacts may still need manual cleanup; review any RTM-specific manifests under <code>/etc/puppet/</code>. On a non-OVH host, no RTM packages were installed, so there is nothing to remove."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"impactTitle": "Impact is workload-dependent",
|
||||
"impactBody": "BBR shines on high-latency or lossy links (cross-continent replication, VPN tunnels, mobile clients). On a LAN between two machines on the same switch, the difference is often within noise. TFO helps short, repeated HTTP connections the most.",
|
||||
"revertTitle": "Reversible from the Uninstall menu",
|
||||
"revertBody": "BBR/TFO are tracked. <link>Uninstall Optimizations</link> removes the two sysctl files (<code>/etc/sysctl.d/99-tcp-bbr.conf</code> and <code>99-tcp-fastopen.conf</code>) and reloads sysctl so the kernel returns to <code>cubic</code> and <code>tcp_fastopen=1</code>. Manual equivalent:"
|
||||
"revertBody": "BBR/TFO are tracked. <link>Uninstall Optimizations</link> removes the two sysctl files (<code>/etc/sysctl.d/99-kernel-bbr.conf</code> and <code>99-tcp-fastopen.conf</code>) and reloads the remaining sysctl configuration. Removing a file does not itself reset its live kernel values. Defaults such as <code>cubic</code> and <code>tcp_fastopen=1</code> return after a reboot unless another configuration overrides them. Manual equivalent:"
|
||||
},
|
||||
"names": {
|
||||
"heading": "Interface Names (persistent)",
|
||||
@@ -83,13 +83,13 @@
|
||||
"whyItems": [
|
||||
"Adding or removing PCIe devices can shift the bus numbering, turning <code>enp3s0</code> into <code>enp4s0</code>. If your <code>/etc/network/interfaces</code> references the old name, the bridge vanishes on reboot.",
|
||||
"BIOS / firmware updates sometimes change how devices enumerate, with the same effect.",
|
||||
"LXC containers with <code>hotplug</code> NICs and bonded links can race on boot and end up named inconsistently. Pinning fixes that."
|
||||
"The helper writes <code>.link</code> files for physical NICs, including bond member ports, using the MAC currently reported in sysfs; for bond members this may be the bond’s shared MAC, so check their names after a reboot. It skips virtual interfaces such as LXC veth devices and the bond devices themselves; it does not fix naming races for virtual <code>hotplug</code> NICs."
|
||||
],
|
||||
"writtenTitle": "What gets written",
|
||||
"writtenIntro": "One file per physical NIC, at <code>/etc/systemd/network/10-proxmenux-<iface>.link</code>. Each file starts with the header <code># Managed by ProxMenux — do not edit</code> so ProxMenux can distinguish its own files from user- or package-provided <code>.link</code> files.",
|
||||
"writtenOutro": "<code>.link</code> files from other packages or hand-written by the user are left in place — only files carrying the ProxMenux header are managed. On re-run, the function reconciles its own set: it re-reads <code>MACAddress=</code> from every <code>10-proxmenux-*.link</code> and drops any whose MAC no longer appears under <code>/sys/class/net/</code>. Files written by an earlier ProxMenux release in the old <code>10-<iface>.link</code> format are migrated automatically the first time.",
|
||||
"pveTitle": "PVE 9 vs PVE 8",
|
||||
"pveBody": "On Proxmox VE 9 (<code>systemd-networkd</code> native), the script reloads udev rules after writing the <code>.link</code> files so new hotplug NICs pick up the correct name without a reboot. On PVE 8 (<code>ifupdown2</code>), interface naming is resolved at boot anyway — a reboot is required for the changes to take effect. The script sets the reboot flag either way so Customizable prompts you.",
|
||||
"pveBody": "The script uses systemd <code>.link</code> files for persistent names. On Proxmox VE 9 it also reloads udev rules after writing them, so a pinned NIC that is re-added or re-probed can pick up its rule without rebooting. Existing interfaces should be checked after a reboot on both PVE 8 and PVE 9. This does not switch the host away from <code>ifupdown2</code>. The script sets the reboot flag in either case so Customizable prompts you.",
|
||||
"reviewTitle": "Review existing /etc/network/interfaces first",
|
||||
"reviewBody": "If your host has legacy configuration in <code>/etc/network/interfaces</code> that references NIC names generated by the kernel's default scheme, pinning <em>today's</em> names is exactly what you want. But if you've already manually customised the config around specific names, double-check the pinning matches what the interfaces file expects before rebooting.",
|
||||
"revertTitle": "Reversible from the Uninstall menu",
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
},
|
||||
"log2ram": {
|
||||
"title": "Install Log2RAM (SSD/NVMe wear reduction)",
|
||||
"intro": "Log2RAM mounts <code>/var/log</code> on a tmpfs ramdisk and periodically syncs the contents back to the underlying disk. On a hypervisor journald churn hits the root SSD every few seconds; moving the writes to RAM reduces wear and disk I/O without losing logs — the periodic sync flushes them to disk and a clean shutdown flushes them too.",
|
||||
"intro": "Log2RAM mounts <code>/var/log</code> on a tmpfs ramdisk and periodically syncs it to the underlying disk. Buffering frequent journald writes in RAM can reduce root SSD wear and disk I/O. Periodic sync and a clean shutdown save logs to disk, but an abrupt power loss can lose entries written since the last sync.",
|
||||
"upstreamLabel": "Upstream project:",
|
||||
"upstreamUrl": "https://github.com/azlux/log2ram",
|
||||
"upstreamLinkLabel": "azlux/log2ram on GitHub",
|
||||
@@ -149,7 +149,7 @@
|
||||
"Registers itself in <code>installed_tools.json</code> so it can be reverted from Uninstall Optimizations."
|
||||
],
|
||||
"howUseLabel": "How to use:",
|
||||
"howUseBody": "On the Automated flow Log2RAM applies unattended when an SSD/NVMe root is detected. On the Customizable flow the script prompts for size, sync interval and whether to enable the 90% auto-sync guard.",
|
||||
"howUseBody": "On the Automated flow Log2RAM installs unattended when an SSD/NVMe root is detected. The Customizable flow asks for size, sync interval and whether to enable the auto-sync guard. Its prompt currently says 90%, but the generated guard uses the 80% cleanup and 92% aggressive thresholds described above.",
|
||||
"verifyLabel": "Verify and manage from the shell:",
|
||||
"verifyCode": "# Service state and configured timers\nsystemctl status log2ram\nsystemctl list-timers log2ram*\n\n# Current ramdisk usage — /var/log IS the tmpfs itself\ndf -h /var/log\n\n# Force a sync now (tmpfs → disk); does NOT shrink the tmpfs\nlog2ram write\n\n# Trigger the auto-sync guard on demand (vacuum + sync when usage is high)\n/usr/local/bin/log2ram-check.sh\n\n# Current config: SIZE, mail settings, path\ncat /etc/log2ram.conf\n\n# ProxMenux-specific cron jobs\ncat /etc/cron.d/log2ram /etc/cron.d/log2ram-auto-sync\n\n# Recent Log2RAM activity\njournalctl -u log2ram -n 50 --no-pager"
|
||||
},
|
||||
@@ -172,6 +172,6 @@
|
||||
},
|
||||
"autoApplication": {
|
||||
"title": "Automatic Application",
|
||||
"body": "These optional features are applied only when specifically selected during the post-install process. Each feature can be individually chosen based on your specific needs and preferences."
|
||||
"body": "In the Customizable flow, select each optional feature according to your needs. Log2RAM is also part of the Automated flow with hardware detection; ZRAM remains Customizable-only. Review the individual sections for prompts and prerequisites."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"heading": "Use pigz for faster gzip compression",
|
||||
"intro": "Standard <code>gzip</code> compresses data using a <strong>single CPU core</strong>. On modern Proxmox hosts with 8, 16 or 32 cores, that is a huge bottleneck during <code>vzdump</code> VM/CT backups, log rotation, and anything else that pipes through <code>gzip</code>. <a>pigz</a> is a drop-in parallel replacement: same gzip-compatible output, but it spreads the work across every core.",
|
||||
"doesTitle": "What ProxMenux does",
|
||||
"doesIntro": "Four steps, all idempotent:",
|
||||
"doesIntro": "Five steps, all idempotent:",
|
||||
"doesItems": [
|
||||
"Sets <code>pigz: 1</code> in <code>/etc/vzdump.conf</code> so Proxmox's backup tool uses pigz natively.",
|
||||
"Installs the <code>pigz</code> apt package if not already present.",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"trackedBody": "Each of these options registers a tool in <code>installed_tools.json</code>, so they appear in <link>Uninstall Optimizations</link>. Reverting <code>zfs_arc</code> removes <code>/etc/modprobe.d/99-zfsarc.conf</code> and rebuilds initramfs; <code>zfs_auto_snapshot</code> reverses the cron schedule and offers to purge the package; <code>zfs_autotrim</code> sets <code>autotrim=off</code> on the pools it enabled; <code>vzdump_speed</code> restores <code>/etc/vzdump.conf</code> from the <code>.bak</code> the install created.",
|
||||
"arc": {
|
||||
"heading": "Optimize ZFS ARC size",
|
||||
"intro": "The <strong>Adaptive Replacement Cache (ARC)</strong> is ZFS's in-memory read cache. Without explicit tuning, ZFS happily grabs up to half the host RAM for itself, which is excessive on a Proxmox host that also needs memory for VMs and LXCs. This option caps ARC to a sane fraction of total RAM based on the size of the machine.",
|
||||
"intro": "The <strong>Adaptive Replacement Cache (ARC)</strong> is ZFS’s in-memory read cache. Proxmox VE installations since 8.1 set a limit of 10% of RAM, capped at 16 GiB; older or upgraded hosts may differ. This option writes that same policy explicitly (RAM/10, capped at 16 GiB, with a 64 MiB floor) to its own file, which also covers older or upgraded hosts. Check existing settings and workload needs before changing it; a smaller cache is not always faster.",
|
||||
"sizingTitle": "Sizing rules",
|
||||
"headerRam": "Host RAM",
|
||||
"headerMax": "ARC cap",
|
||||
@@ -41,7 +41,7 @@
|
||||
"max": "16 GiB (cap)"
|
||||
}
|
||||
],
|
||||
"after": "The file <code>/etc/modprobe.d/99-zfsarc.conf</code> contains a single directive — <code>options zfs zfs_arc_max=…</code>. Every other ZFS module parameter (<code>zfs_arc_min</code>, L2ARC prefetch/write throttle, TXG timeout) is left at its OpenZFS default. Before writing, a reconcile step scans any other <code>*.conf</code> in <code>/etc/modprobe.d/</code> that sets <code>zfs_arc_min</code> / <code>zfs_arc_max</code>, backs them up to <code>/usr/local/share/proxmenux/backups/zfs_arc/</code> with a manifest, and strips the conflicting lines so only ProxMenux's file is active. After writing the file, ProxMenux runs <code>update-initramfs -u -k all</code> and, when applicable, <code>proxmox-boot-tool refresh</code>, so the cap also lands in the initramfs used by ZFS-on-root setups.",
|
||||
"after": "The file <code>/etc/modprobe.d/99-zfsarc.conf</code> contains a single directive — <code>options zfs zfs_arc_max=…</code>. This option does not tune other ZFS module parameters (<code>zfs_arc_min</code>, L2ARC prefetch/write throttle, TXG timeout). Before writing, a reconcile step scans other <code>*.conf</code> in <code>/etc/modprobe.d/</code> that set <code>zfs_arc_min</code> / <code>zfs_arc_max</code>, backs them up to <code>/usr/local/share/proxmenux/backups/zfs_arc/</code> with a manifest, and removes the conflicting <code>zfs_arc_min</code> / <code>zfs_arc_max</code> values (other options on those lines are kept), so only ProxMenux’s ARC file sets the limit. After writing, it runs <code>update-initramfs -u -k all</code> and, when applicable, <code>proxmox-boot-tool refresh</code>, so the limit also reaches the initramfs used by ZFS-on-root setups.",
|
||||
"rebootTitle": "Requires a reboot to take effect",
|
||||
"rebootBody": "ARC settings are read when the <code>zfs</code> kernel module loads. To make the cap take effect on ZFS-on-root hosts, ProxMenux regenerates the initramfs with <code>update-initramfs -u -k all</code> and, when applicable, refreshes the boot loader with <code>proxmox-boot-tool refresh</code>. A reboot is still required to pick up the new module parameter; the \"reboot required\" flag is set automatically.",
|
||||
"safeTitle": "Safe on non-ZFS hosts",
|
||||
@@ -90,22 +90,22 @@
|
||||
},
|
||||
"autotrim": {
|
||||
"heading": "Enable ZFS autotrim (SSD/NVMe pools)",
|
||||
"intro": "Enables the <code>autotrim</code> property on every ZFS pool that is backed exclusively by SSDs or NVMe drives with TRIM support. Pools that include a single HDD vdev are skipped automatically — TRIM on rotational drives is meaningless and ZFS will refuse it. Pools that were already set to <code>autotrim=on</code> are left as they are.",
|
||||
"intro": "Enables the <code>autotrim</code> property on ZFS pools backed exclusively by SSDs or NVMe drives with TRIM support. The script conservatively skips pools containing a rotational device. Pools already set to <code>autotrim=on</code> are left unchanged.",
|
||||
"trimTitle": "What TRIM does, and why it matters on ZFS",
|
||||
"trimBody1": "SSDs / NVMe drives manage internal storage in fixed-size erase blocks that are much larger than the logical sectors the filesystem talks to. When a filesystem deletes a file, the drive doesn't know — it still thinks those sectors are in use, so its internal garbage collector keeps shuffling stale data around to free new erase blocks. <strong>TRIM</strong> is the standard command the OS uses to tell the drive \"these sectors are now free, you can erase them ahead of time\".",
|
||||
"trimBody2": "Without TRIM, SSD performance degrades over time as the drive runs out of pre-erased blocks and has to do erase-on-write, and write amplification increases — both shortening the drive's useful life. With TRIM enabled, the drive can keep a healthy pool of empty blocks ready to write into.",
|
||||
"trimBody3": "On ZFS, <code>autotrim=on</code> is the modern equivalent of the periodic <code>zpool trim <pool></code> command — instead of having to remember to run a trim manually (or schedule one), the pool issues TRIM commands automatically and continuously as blocks become free. It's low-overhead and the recommended setting for SSD-backed pools.",
|
||||
"trimBody3": "With <code>autotrim=on</code>, ZFS trims recently freed space in the background, grouping ranges before issuing commands. A periodic <code>zpool trim <pool></code> is another option. Autotrim avoids a separate schedule, but its performance impact depends on the devices; periodic manual trim may suit some lower-end drives better.",
|
||||
"practicalTitle": "Why is this practical to enable?",
|
||||
"practicalItems": [
|
||||
"<strong>Sustained write performance.</strong> SSDs that never see TRIM commands slow down measurably over months. Autotrim keeps the controller's job easier.",
|
||||
"<strong>Drive longevity.</strong> Lower write amplification means fewer total NAND writes for the same amount of data — measurable in years of useful life for the disk.",
|
||||
"<strong>Sustained write performance.</strong> TRIM can help a drive reclaim unused blocks efficiently. The benefit and any latency impact depend on the device and workload.",
|
||||
"<strong>Drive longevity.</strong> Avoiding unnecessary internal copying can reduce write amplification and NAND wear. It does not guarantee a specific increase in drive lifespan.",
|
||||
"<strong>No scheduled cron job to remember.</strong> Unlike a periodic <code>zpool trim</code>, autotrim is fire-and-forget — the pool handles it on its own."
|
||||
],
|
||||
"whenTitle": "When is this necessary?",
|
||||
"whenIntro1": "<strong>You should enable it</strong> on any ZFS pool whose vdevs are all SSD or NVMe with TRIM support — the typical Proxmox install on consumer or enterprise SSDs.",
|
||||
"whenIntro1": "<strong>Consider enabling it</strong> on ZFS pools made entirely of TRIM-capable SSD or NVMe devices. Check device behaviour and workload latency; a scheduled manual trim can be preferable on some hardware.",
|
||||
"whenIntro2": "<strong>The script skips it automatically</strong> on:",
|
||||
"whenSkipItems": [
|
||||
"Pools containing any HDD (rotational) vdev — TRIM is meaningless there.",
|
||||
"Pools containing any HDD (rotational) vdev — a conservative hardware filter used by this script.",
|
||||
"Drives without <code>discard_granularity</code> exposed in sysfs — usually old SSDs without TRIM, or pass-through paths where the OS can't see the underlying device.",
|
||||
"Pools where ZFS itself reports the property unsupported (rare; very old pools).",
|
||||
"Pools already set to <code>autotrim=on</code> (no-op)."
|
||||
@@ -121,7 +121,7 @@
|
||||
},
|
||||
"vzdump": {
|
||||
"heading": "Increase vzdump backup speed",
|
||||
"intro": "By default, Proxmox vzdump throttles backups to protect running VMs/CTs from IO starvation. On many setups that throttle is more conservative than needed. This option removes the bandwidth cap and lowers the I/O priority so vzdump can saturate the storage path during backup windows.",
|
||||
"intro": "Writes bwlimit: 0 and ionice: 5 in the global vzdump configuration. Proxmox already defaults to no bandwidth limit, so this removes a cap only if one was configured. Compared with the default ionice: 7, the value 5 gives a higher best-effort I/O priority where the scheduler honours it. This can affect running guests and does not guarantee faster backups.",
|
||||
"changedTitle": "What gets changed in /etc/vzdump.conf",
|
||||
"backupTitle": "First run creates a .bak of vzdump.conf",
|
||||
"backupBody": "The first time this option runs, ProxMenux copies <code>/etc/vzdump.conf</code> to <code>/etc/vzdump.conf.bak</code> before touching it. Subsequent runs re-use that backup and won't overwrite it, so a hand-edited config from before the first apply stays recoverable. The changes to <code>bwlimit</code> and <code>ionice</code> are then made with <code>sed</code>, and any other options in the file (compress, pigz, tmpdir, exclude-path, etc.) are preserved.",
|
||||
@@ -145,7 +145,7 @@
|
||||
{
|
||||
"label": "Backup and Restore commands",
|
||||
"href": "/docs/help-info/backup-commands",
|
||||
"tail": " — vzdump CLI reference (now without the legacy bwlimit / ionice caps)."
|
||||
"tail": " — vzdump CLI reference for bandwidth and I/O-priority settings."
|
||||
},
|
||||
{
|
||||
"label": "Uninstall Optimizations",
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
},
|
||||
"logrotate": {
|
||||
"heading": "Optimize logrotate",
|
||||
"intro": "Rewrites <code>/etc/logrotate.conf</code> with a tighter policy suitable for a host that's also part of an SSD-protecting Log2RAM setup: daily rotation, 7-day retention, 10 MB size trigger, compression, and <code>copytruncate</code> so active services keep writing without reopening their log files. Original <code>logrotate.conf</code> is backed up to <code>.bak</code> on first apply.",
|
||||
"intro": "Rewrites <code>/etc/logrotate.conf</code> with global daily and size settings, 7 retained rotations, compression and <code>copytruncate</code>, so active services can keep writing without reopening their log files. The size setting follows daily and takes precedence unless a per-log rule overrides it. Original <code>logrotate.conf</code> is backed up to <code>.bak</code> on first apply.",
|
||||
"tipTitle": "Log2RAM-friendly",
|
||||
"tipBody": "The <code>size 10M</code> trigger means logs rotate on size <em>or</em> daily, whichever comes first. Combined with Log2RAM's RAM-backed <code>/var/log</code>, this keeps the working set small so flushes to disk stay cheap."
|
||||
"tipBody": "The <code>size 10M</code> directive takes precedence over the earlier daily setting; it does <em>not</em> mean whichever comes first. Logrotate checks the threshold when it runs, and per-log rules may override the global settings. With Log2RAM’s RAM-backed <code>/var/log</code>, review both the rules and the timer frequency to control disk usage."
|
||||
},
|
||||
"limits": {
|
||||
"heading": "Increase various system limits",
|
||||
@@ -72,7 +72,7 @@
|
||||
}
|
||||
],
|
||||
"tipTitle": "Why inotify matters",
|
||||
"tipBody": "Applications like Docker, Syncthing, Node.js watchers, Plex's library scanner and many more hit <code>max_user_watches</code> quickly. Default on Debian is 8192 — a single running Plex can exhaust it. 1M is generous and costs ~1 KB of RAM per watch, which is negligible."
|
||||
"tipBody": "Docker, Syncthing, Node.js file watchers and Plex library scans can exhaust <code>max_user_watches</code>. The default depends on the kernel and host memory; it is not always 8192. Raising the limit to 1M allows more watches, but does not preallocate them. Active watches consume kernel memory, so monitor actual usage on memory-constrained hosts."
|
||||
},
|
||||
"memory": {
|
||||
"heading": "Optimize memory settings",
|
||||
@@ -102,8 +102,8 @@
|
||||
"verify": {
|
||||
"heading": "Verification",
|
||||
"intro": "After applying the System optimizations:",
|
||||
"tipTitle": "Fully reversible",
|
||||
"tipBody": "All six options are tracked in <code>installed_tools.json</code>, so they appear in <link>Uninstall Optimizations</link> if you want to back any of them out. Reverts restore the sysctl files' defaults, drop the systemd unit and alias for kexec, and reset journald/logrotate to stock Debian configs."
|
||||
"tipTitle": "Restoration and limitations",
|
||||
"tipBody": "All six options are tracked in <code>installed_tools.json</code> and offered in <link>Uninstall Optimizations</link>. Restoration removes the configuration files and the kexec unit and alias, rewrites journald.conf with the stock systemd defaults and restores logrotate.conf from its backup. Some live limits need a new session or reboot."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
},
|
||||
{
|
||||
"tool": "APT Language Skip",
|
||||
"restores": "Removes /etc/apt/apt.conf.d/99-disable-translations. APT will download language packages again."
|
||||
"restores": "Removes /etc/apt/apt.conf.d/99-disable-translations, allowing APT to download translated package-description indexes according to its remaining language settings."
|
||||
},
|
||||
{
|
||||
"tool": "APT IPv4 Force",
|
||||
@@ -83,7 +83,7 @@
|
||||
},
|
||||
{
|
||||
"tool": "System Limits Increase",
|
||||
"restores": "Removes /etc/sysctl.d/99-maxwatches.conf, 99-maxkeys.conf, 99-swap.conf, 99-fs.conf and /etc/security/limits.d/99-limits.conf. Reverts PAM limits and systemd DefaultLimitNOFILE, and strips the ulimit -n 256000 line from /root/.profile."
|
||||
"restores": "Removes /etc/sysctl.d/99-maxwatches.conf, 99-maxkeys.conf, 99-swap.conf, 99-fs.conf and /etc/security/limits.d/99-limits.conf. Reverts PAM limits and systemd DefaultLimitNOFILE. Its /root/.profile cleanup targets the legacy ulimit -n 256000 line; a ulimit -n 1048576 line from the current installer can remain and may need manual removal."
|
||||
},
|
||||
{
|
||||
"tool": "ZRAM swap profile",
|
||||
@@ -104,7 +104,7 @@
|
||||
},
|
||||
{
|
||||
"tool": "TCP BBR + TCP Fast Open",
|
||||
"restores": "Removes /etc/sysctl.d/99-tcp-bbr.conf and 99-tcp-fastopen.conf and reloads sysctl so the kernel returns to the cubic congestion control and to tcp_fastopen=1."
|
||||
"restores": "Removes /etc/sysctl.d/99-kernel-bbr.conf and 99-tcp-fastopen.conf and reloads remaining sysctl configuration. File removal does not itself reset live values; defaults such as cubic and tcp_fastopen=1 return after reboot unless another configuration overrides them."
|
||||
},
|
||||
{
|
||||
"tool": "Persistent Interface Names",
|
||||
@@ -166,8 +166,8 @@
|
||||
"restores": "Removes idle=nomwait from kernel cmdline (ZFS) or GRUB, and the ignore_msrs / report_ignored_msrs options from /etc/modprobe.d/kvm.conf."
|
||||
},
|
||||
{
|
||||
"tool": "QEMU Guest Agent (templates)",
|
||||
"restores": "Reads /usr/local/share/proxmenux/guest_agent.pkg (recorded at install time) and apt purges whichever package was installed (qemu-guest-agent for standard hosts, spice-vdagent when Spice mode is used)."
|
||||
"tool": "Guest agent for a virtualized Proxmox host",
|
||||
"restores": "Reads /usr/local/share/proxmenux/guest_agent.pkg and purges the recorded host package. The installer selects qemu-guest-agent, open-vm-tools or virtualbox-guest-utils according to the detected hypervisor. If the record is missing, the uninstaller tries those three packages. This acts on the nested Proxmox host, not guest templates."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -221,7 +221,7 @@
|
||||
},
|
||||
{
|
||||
"tool": "OVH RTM (monitoring)",
|
||||
"restores": "apt purges any ovh-* packages the RTM installer added and deletes the puppet manifests it dropped under /etc/puppet/. On non-OVH hosts nothing was ever installed, so nothing is removed."
|
||||
"restores": "Purges packages matching ovh-rtm*, rtm and rtm-*, removes /etc/rtm and clears the RTM registry entry. Puppet artefacts under /etc/puppet/ may need manual inspection and cleanup; the uninstaller does not delete that directory. On non-OVH hosts the installer normally makes no changes."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -230,7 +230,7 @@
|
||||
"edge": {
|
||||
"heading": "Edge cases and caveats",
|
||||
"packageTitle": "Package reinstall touches live Proxmox packages",
|
||||
"packageBody": "Reverting <strong>Subscription Banner Removal</strong> reinstalls <code>pve-manager</code>, <code>proxmox-widget-toolkit</code>, <code>libjs-extjs</code> and <code>libpve-http-server-perl</code> with <code>--force-confnew</code>. This is generally safe but does touch the running web UI — refresh your browser afterwards, and expect a few seconds of reconnection. Don't run this in the middle of a migration or clone operation.",
|
||||
"packageBody": "If ProxMenux’s own backups cannot restore <strong>Subscription Banner Removal</strong>, the fallback reinstalls <code>pve-manager</code>, <code>proxmox-widget-toolkit</code>, <code>libjs-extjs</code> and <code>libpve-http-server-perl</code> with <code>--force-confnew</code>. This touches the running web UI: refresh the browser afterwards and allow a few seconds to reconnect. Avoid doing it during a migration or clone operation.",
|
||||
"rebootTitle": "Persistent names and VFIO need a reboot",
|
||||
"rebootBody": "Removing ProxMenux's <code>10-proxmenux-*.link</code> files (<em>Persistent Interface Names</em>) and reverting <em>IOMMU/VFIO</em> do not affect the running system — they only matter after a reboot. ProxMenux sets the reboot flag automatically for these.",
|
||||
"perItemTitle": "You can revert one thing and keep the rest",
|
||||
|
||||
@@ -48,9 +48,9 @@
|
||||
},
|
||||
"pathB": {
|
||||
"heading": "Path B — From the Monitor dashboard",
|
||||
"intro": "The same updates appear in the Monitor under <link>Settings → ProxMenux Optimizations</link>. When pending updates are detected the card shows an \"Updates available\" banner with the count and an <strong>Apply</strong> action that opens the same per-optimization picker.",
|
||||
"imageAlt": "ProxMenux Optimizations card on the Monitor dashboard with an Updates available banner at the top showing the count of pending updates and an Apply button that opens the per-optimization picker",
|
||||
"imageCaption": "The Optimizations card in the Monitor — when at least one optimization has a newer version on disk, the banner surfaces it without requiring shell access."
|
||||
"intro": "The same updates appear in the Monitor under <link>Settings → ProxMenux Optimizations</link>. When pending updates are detected, the card shows an <strong>updates count badge</strong> that opens the per-optimization picker. Individual tools also provide their own update action.",
|
||||
"imageAlt": "ProxMenux Optimizations card in Monitor settings, with a pending-updates count badge that opens the per-optimization picker and update actions on individual tools",
|
||||
"imageCaption": "The Optimizations card in the Monitor — when at least one optimization has a newer version on disk, its count badge makes the updates accessible without shell access."
|
||||
},
|
||||
"applying": {
|
||||
"heading": "What happens when you apply",
|
||||
@@ -69,7 +69,7 @@
|
||||
},
|
||||
{
|
||||
"title": "Registry refresh sent to the Monitor",
|
||||
"body": "Once the batch finishes, the menu POSTs to <code>http://127.0.0.1:8008/api/updates/post-install/scan</code> to rebuild <code>/usr/local/share/proxmenux/updates_available.json</code>. That is what makes the Monitor's Optimizations card and the shell menu entry disappear immediately after the update, without waiting for the next scheduled scan."
|
||||
"body": "Once the batch finishes, the menu POSTs to <code>http://127.0.0.1:8008/api/updates/post-install/scan</code> to rebuild <code>/usr/local/share/proxmenux/updates_available.json</code>. After all pending updates are applied, the update badge in the Monitor’s Optimizations card and the conditional shell menu entry disappear without waiting for the next scheduled scan. The Optimizations card itself remains available."
|
||||
}
|
||||
],
|
||||
"jqTitle": "jq is required",
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
},
|
||||
"hardening": {
|
||||
"heading": "SSH hardening: MaxAuthTries",
|
||||
"intro": "Lynis control <strong>SSH-7408</strong> recommends <code>MaxAuthTries 3</code> in <code>sshd_config</code>. With Fail2Ban's <code>maxretry = 2</code> on the SSH jail, a malicious client never reaches three attempts anyway — but the explicit setting satisfies the audit and adds defence in depth (e.g. if Fail2Ban is stopped for maintenance).",
|
||||
"intro": "Lynis control <strong>SSH-7408</strong> recommends <code>MaxAuthTries 3</code> in <code>sshd_config</code>. The SSH jail uses <code>maxretry = 2</code> to trigger a ban after repeated failures, while MaxAuthTries limits attempts within a connection. The explicit SSH setting adds defence in depth, including when Fail2Ban is stopped for maintenance.",
|
||||
"installerIntro": "The installer:",
|
||||
"items": [
|
||||
"Reads the current <code>MaxAuthTries</code> value (or defaults to 6 if absent).",
|
||||
@@ -125,7 +125,7 @@
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"neverBansTitle": "Fail2Ban runs but never bans anything",
|
||||
"neverBansBody": "Check the auth log files actually receive entries: <code>tail -f /var/log/ssh-auth.log</code> and try a wrong-password SSH attempt from a different machine. If the log stays empty, the logger service is not running: <code>systemctl status ssh-auth-logger.service</code>. If it's active but the log is empty, check that the journald drop-in took effect: <code>journalctl --dump-catalog | head</code> — events at <em>info</em> level should be visible.",
|
||||
"neverBansBody": "Check that <code>tail -f /var/log/ssh-auth.log</code> receives an entry after a wrong-password SSH attempt from another machine. If it stays empty, inspect <code>systemctl status ssh-auth-logger.service</code>. If the logger is active, inspect recent SSH events with <code>journalctl -u ssh.service -n 50 --no-pager -p info</code> and check whether the journald drop-in permits the <em>info</em> level.",
|
||||
"monitorEmptyTitle": "ProxMenux Monitor jail has no entries even after failed logins",
|
||||
"monitorEmptyBody": "The <code>[proxmenux]</code> jail reads <code>/var/log/proxmenux-auth.log</code>, which is written by the ProxMenux Monitor Flask app — not by a journald logger. If you don't run the Monitor, the file stays empty and the jail never fires. That's expected; the jail config is harmless. If you do run the Monitor and the log is empty, check the Flask logging config.",
|
||||
"selfBanTitle": "I banned myself",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"items": [
|
||||
"Auto-detected — no path to type",
|
||||
"Picks the ACME-uploaded cert if present, falls back to the self-signed default",
|
||||
"Renewal happens through Proxmox; the Monitor follows automatically on next start"
|
||||
"Proxmox handles renewal; the Monitor validates and loads it on the next new TLS connection"
|
||||
]
|
||||
},
|
||||
"custom": {
|
||||
@@ -143,7 +143,7 @@
|
||||
},
|
||||
"trustCa": {
|
||||
"heading": "Trust the Proxmox self-signed CA",
|
||||
"intro1Rich": "If you prefer to keep the default Proxmox-generated certificate (no ACME), you can stop the browser warning by importing the cluster's root CA into the OS or browser trust store. The Monitor will keep auto-detecting the same <code>/etc/pve/local/pveproxy-ssl.pem</code>; the only thing that changes is that the device viewing the dashboard now recognises the issuer.",
|
||||
"intro1Rich": "To keep the default Proxmox-generated certificate without ACME, import the cluster root CA into the OS or browser trust store. The Monitor detects <code>/etc/pve/local/pve-ssl.pem</code> as the fallback certificate. This makes the client trust its issuer; the URL must still match a name in the certificate.",
|
||||
"intro2Rich": "The CA file lives at <code>/etc/pve/pve-root-ca.pem</code> on every node. In a cluster the path is on the shared <code>pmxcfs</code> filesystem so all nodes share the same root, and a single import covers the whole datacenter. Copy it to your machine:",
|
||||
"code": "scp root@<your-host>:/etc/pve/pve-root-ca.pem ./pve-root-ca.pem",
|
||||
"thenImport": "Then import it on the client side:",
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
"downloadCmd": "curl -fsSL -o /tmp/test https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh && head -1 /tmp/test",
|
||||
"downloadOutro": "If this fails outside ProxMenux, it's a network / proxy issue on the host.",
|
||||
"errorsTitle": "“Installer finished with errors”",
|
||||
"errorsBody": "The installer surfaced a non-zero exit code. The previous channel and any already-installed components are left as they were before the switch. Re-run the action; if it keeps failing, run the installer manually from a shell (see the manual equivalent above) — that gives you the full output instead of the dialog summary.",
|
||||
"errorsBody": "The installer returned a non-zero exit code. There is no automatic rollback: some files or components may already have changed. Read the installer output shown above the error before pressing Enter and check the current state, then retry from the menu or run the installer manually from SSH or the host console.",
|
||||
"configTitle": "“Could not update config file” after switching to Stable",
|
||||
"configBody": "The post-install cleanup of beta metadata failed — usually because <code>config.json</code> has a syntax error from a manual edit. Validate it:",
|
||||
"configCmd": "jq . /usr/local/share/proxmenux/config.json",
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Change Language | ProxMenux Documentation",
|
||||
"description": "Switch ProxMenux UI between English, Spanish, French, German, Italian or Portuguese. Translation install only — uses googletrans + a pre-cached translation table. The menu reloads automatically with the new language.",
|
||||
"description": "Choose from eight ProxMenux interface languages. Every installation includes pre-generated JSON translation catalogs; no translation service or Python environment is needed on the host. The menu reloads automatically.",
|
||||
"ogTitle": "Change Language | ProxMenux Documentation",
|
||||
"ogDescription": "Pick the ProxMenux interface language from the Settings menu. Six languages supported."
|
||||
"ogDescription": "Pick one of eight ProxMenux interface languages from Settings. Available on every installation."
|
||||
},
|
||||
"header": {
|
||||
"title": "Change Language",
|
||||
"description": "Switch the ProxMenux UI between six supported languages. Saves the choice to config.json and re-execs the menu with the new language. Only available on the Translation install type — the Normal (lightweight) install is English-only by design.",
|
||||
"description": "Switch the ProxMenux interface between eight supported languages. The choice is saved to config.json and the menu is restarted in the new language. Every installation includes the translation catalogs.",
|
||||
"section": "Settings"
|
||||
},
|
||||
"intro": {
|
||||
"title": "What this is",
|
||||
"body": "A dialog menu that lists the six supported languages. Pick one, ProxMenux saves it to <code>config.json</code> as <code>.language</code>, then re-execs <code>config_menu.sh</code> so the new language takes effect immediately."
|
||||
"body": "A dialog lists the eight supported languages. ProxMenux saves your choice to <code>config.json</code> as <code>.language</code>, then restarts <code>config_menu.sh</code> so it takes effect immediately."
|
||||
},
|
||||
"warn": {
|
||||
"title": "Translation install only",
|
||||
"body": "This option only appears in Settings if both checks pass: <code>/opt/googletrans-env/bin/activate</code> exists (Python venv with googletrans), <em>and</em> <code>config.json</code> has a non-empty <code>.language</code>. On the Normal (English-only) install neither is present and the language picker is not shown."
|
||||
"title": "Available on every installation",
|
||||
"body": "Settings always shows Change Language. Translation catalogs are installed in <code>/usr/local/share/proxmenux/lang/</code>, <em>and</em> the selected language is stored in <code>config.json</code>. No legacy Python translation environment is required."
|
||||
},
|
||||
"supported": {
|
||||
"heading": "Supported languages",
|
||||
@@ -32,38 +32,48 @@
|
||||
{
|
||||
"code": "es",
|
||||
"lang": "Spanish",
|
||||
"notes": "Cached + auto-translated"
|
||||
"notes": "Pre-generated JSON catalog"
|
||||
},
|
||||
{
|
||||
"code": "fr",
|
||||
"lang": "French",
|
||||
"notes": "Cached + auto-translated"
|
||||
"notes": "Pre-generated JSON catalog"
|
||||
},
|
||||
{
|
||||
"code": "de",
|
||||
"lang": "German",
|
||||
"notes": "Cached + auto-translated"
|
||||
"notes": "Pre-generated JSON catalog"
|
||||
},
|
||||
{
|
||||
"code": "it",
|
||||
"lang": "Italian",
|
||||
"notes": "Cached + auto-translated"
|
||||
"notes": "Pre-generated JSON catalog"
|
||||
},
|
||||
{
|
||||
"code": "pt",
|
||||
"lang": "Portuguese",
|
||||
"notes": "Cached + auto-translated"
|
||||
"notes": "Pre-generated JSON catalog"
|
||||
},
|
||||
{
|
||||
"code": "sk",
|
||||
"lang": "Slovak",
|
||||
"notes": "Pre-generated JSON catalog"
|
||||
},
|
||||
{
|
||||
"code": "sv",
|
||||
"lang": "Swedish",
|
||||
"notes": "Pre-generated JSON catalog"
|
||||
}
|
||||
]
|
||||
},
|
||||
"englishTip": {
|
||||
"title": "English is the most accurate",
|
||||
"body": "Non-English strings are produced by a pre-cached table seeded from googletrans. Edge-case strings (rarely triggered options, recent additions) may fall through to a live googletrans call or to the English original. If a translation feels off, English is always the source of truth."
|
||||
"body": "Non-English text comes from pre-generated JSON catalogs included with ProxMenux. Missing translations fall back to English; there is no live translation call on the host. English remains the reference when a translation seems incorrect."
|
||||
},
|
||||
"underHood": {
|
||||
"heading": "How it works under the hood",
|
||||
"items": [
|
||||
"Dialog menu lists the 6 codes; you pick one.",
|
||||
"The dialog lists eight language codes; choose one.",
|
||||
"If <code>config.json</code> exists: <code>jq --arg lang \"$new_language\" '.language = $lang''</code> updates the field in place.",
|
||||
"If <code>config.json</code> doesn't exist: a fresh one is created with the language code in a single-field object.",
|
||||
"Confirmation dialog: <em>\"Language changed to [code]\"</em>.",
|
||||
@@ -76,7 +86,7 @@
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"noOptionTitle": "Option doesn't appear in Settings",
|
||||
"noOptionBody": "You're on the Normal (English-only) install. To get language support, reinstall ProxMenux choosing the Translation install option (it pulls Python venv + googletrans).",
|
||||
"noOptionBody": "Change Language is always available in current releases. If it is missing, update ProxMenux using the official installer and open Settings again.",
|
||||
"stillEnglishTitle": "Language changed but UI still shows English",
|
||||
"stillEnglishBody": "The menu re-execs itself after the change. If you opened a fresh shell and started a different ProxMenux entrypoint, run <code>menu</code> again to pick up the new language. Confirm: <code>jq -r '.language' /usr/local/share/proxmenux/config.json</code>."
|
||||
},
|
||||
@@ -86,7 +96,7 @@
|
||||
{
|
||||
"href": "/docs/settings/show-version-information",
|
||||
"label": "Show Version Information",
|
||||
"tail": " — confirms install type and current language."
|
||||
"tail": " — confirms the release channel, translation files and current language."
|
||||
},
|
||||
{
|
||||
"href": "/docs/settings",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "ProxMenux Settings — Monitor Activation, Release Channel, Languages | ProxMenux",
|
||||
"description": "ProxMenux configuration menu: ProxMenux Monitor activation and service toggle, Reset Monitor Password, Change Release Channel between Stable and Beta, language selection (translation install), version information and uninstall. Options appear conditionally based on what is installed and active.",
|
||||
"description": "ProxMenux settings: Monitor service and password reset, Stable/Beta release channel, eight interface languages, version diagnostics and uninstall. Monitor options appear when its service is installed.",
|
||||
"ogTitle": "ProxMenux Settings — Monitor Activation, Release Channel, Languages",
|
||||
"ogDescription": "Configure ProxMenux — Monitor service, Release Channel, language, version info and uninstall.",
|
||||
"twitterTitle": "ProxMenux Settings",
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"header": {
|
||||
"title": "Settings",
|
||||
"description": "ProxMenux configuration menu. Lists what's installed, lets you toggle the Monitor service, reset the Monitor login password, switch between Stable and Beta release channels in either direction, change the UI language (Translation install only), and provides a clean uninstaller. Options appear conditionally — what you see depends on your install type and current state.",
|
||||
"description": "Configure ProxMenux: toggle the Monitor service, reset its login credentials, switch between Stable and Beta in either direction, choose one of eight interface languages, inspect version diagnostics and uninstall. Monitor actions require its service to be installed; language selection is always available.",
|
||||
"section": "Settings"
|
||||
},
|
||||
"intro": {
|
||||
@@ -18,33 +18,33 @@
|
||||
},
|
||||
"opening": {
|
||||
"heading": "Opening the menu",
|
||||
"body": "From ProxMenux's main menu, press <kbd>s</kbd>. The options shown depend on your install type and on what is currently active:",
|
||||
"imageAlt": "Settings ProxMenux menu with conditional options based on install type and component state"
|
||||
"body": "From ProxMenux's main menu, press <kbd>s</kbd>. Monitor actions appear when its service is installed; the remaining settings are always available:",
|
||||
"imageAlt": "ProxMenux Settings menu with conditional Monitor actions"
|
||||
},
|
||||
"installTypes": {
|
||||
"heading": "Two install types, different menus",
|
||||
"intro": "ProxMenux ships in two flavours. The Settings menu adapts to which one you have:",
|
||||
"heading": "One installation, all languages",
|
||||
"intro": "Current releases include static JSON translation catalogs in every installation. Older releases offered separate Translation and Normal modes:",
|
||||
"headerType": "Install type",
|
||||
"headerBundles": "What it bundles",
|
||||
"headerMenu": "Menu shows",
|
||||
"rows": [
|
||||
{
|
||||
"type": "Translation",
|
||||
"bundles": "Python venv + googletrans + multi-language config",
|
||||
"type": "Current installation",
|
||||
"bundles": "Static JSON catalogs for seven languages plus built-in English; no translation Python environment",
|
||||
"menuRich": "<strong>Change Language</strong> + Show Version + Uninstall"
|
||||
},
|
||||
{
|
||||
"type": "Normal (lightweight)",
|
||||
"bundles": "English-only, no venv, smaller footprint",
|
||||
"menu": "Show Version + Uninstall (no language picker)"
|
||||
"type": "Legacy Translation / Normal modes",
|
||||
"bundles": "Obsolete split between a translation environment and an English-only installation",
|
||||
"menu": "Update with the official installer to use the current unified menu"
|
||||
}
|
||||
],
|
||||
"detectionTitle": "Detection happens automatically",
|
||||
"detectionBody": "The script checks for <code>/opt/googletrans-env/bin/activate</code> and a non-empty <code>language</code> key in <code>config.json</code>. Both present → Translation install. Either missing → Normal install. You don't choose; the menu adapts."
|
||||
"detectionTitle": "Language selection is always available",
|
||||
"detectionBody": "The menu no longer checks for a translation environment. Every installation includes <code>/usr/local/share/proxmenux/lang/</code> and saves the selected <code>language</code> in <code>config.json</code>."
|
||||
},
|
||||
"options": {
|
||||
"heading": "Menu options",
|
||||
"intro": "Five tools. The <em>Conditional</em> badges mean the option only appears when the prerequisite is met (Monitor installed; Beta program active; Translation install).",
|
||||
"intro": "The tools below manage ProxMenux itself. <em>Conditional</em> means the Monitor actions appear only when its systemd service is installed. Release channel, language, version diagnostics and uninstall are always available.",
|
||||
"list": [
|
||||
{
|
||||
"icon": "Activity",
|
||||
@@ -64,7 +64,7 @@
|
||||
"icon": "Info",
|
||||
"href": "/docs/settings/show-version-information",
|
||||
"title": "Show Version Information",
|
||||
"description": "ProxMenux version, install type, installed components, file paths, virtual environment state and current language."
|
||||
"description": "ProxMenux version, release channel, installed components, file paths, translation files and current language."
|
||||
},
|
||||
{
|
||||
"icon": "Trash2",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Show Version Information | ProxMenux Documentation",
|
||||
"description": "Read-only ProxMenux self-diagnostic: version number, install type (Translation / Normal), installed components from config.json, file paths, virtual environment state and current language.",
|
||||
"description": "Read-only ProxMenux diagnostics: version, release channel, components recorded in config.json, file paths, translation catalogs and current language.",
|
||||
"ogTitle": "Show Version Information | ProxMenux Documentation",
|
||||
"ogDescription": "Diagnostic dump of ProxMenux version, install type, components, files and language."
|
||||
"ogDescription": "Diagnostic output of ProxMenux version, release channel, components, files and language."
|
||||
},
|
||||
"header": {
|
||||
"title": "Show Version Information",
|
||||
"description": "Read-only diagnostic. Reads version.txt, config.json and a few well-known file paths, then renders a scrollable text box with version, install type, installed components, file presence, virtual environment state and current language.",
|
||||
"description": "Read-only diagnostics. Reads version.txt, config.json and known file paths, then shows a scrollable text box with the version, release channel, installed components, file presence, translation files and current language.",
|
||||
"section": "Settings"
|
||||
},
|
||||
"intro": {
|
||||
@@ -26,9 +26,9 @@
|
||||
"contentRich": "Single-line version number; <code>Unknown</code> if file missing"
|
||||
},
|
||||
{
|
||||
"section": "Install type",
|
||||
"source": "venv + config.json checks",
|
||||
"content": "Translation (multi-language) or Normal (English-only)"
|
||||
"section": "Release channel",
|
||||
"source": "config.json beta-program status",
|
||||
"content": "Stable (main) or Beta (develop); beta version when available"
|
||||
},
|
||||
{
|
||||
"section": "Installed components",
|
||||
@@ -41,14 +41,14 @@
|
||||
"contentRich": "<code>menu</code>, <code>utils.sh</code>, <code>config.json</code>, <code>version.txt</code> presence + paths"
|
||||
},
|
||||
{
|
||||
"section": "Virtual environment",
|
||||
"source": "/opt/googletrans-env",
|
||||
"content": "Translation install only — venv + pip presence"
|
||||
"section": "Translation files",
|
||||
"source": "/usr/local/share/proxmenux/lang/",
|
||||
"content": "Presence of the lang/ directory included with every installation"
|
||||
},
|
||||
{
|
||||
"section": "Current language",
|
||||
"source": "config.json",
|
||||
"contentRich": "Translation: language code from <code>.language</code>; Normal: <code>English (Fixed)</code>"
|
||||
"contentRich": "Language code from <code>.language</code>; defaults to <code>en</code> when unset"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Uninstall ProxMenux | ProxMenux Documentation",
|
||||
"description": "Clean ProxMenux uninstaller with optional dependency removal (jq, dialog, python3-*) and automatic restoration of /root/.bashrc and /etc/motd backups created at install time. Also removes the proxmenux-monitor service if present.",
|
||||
"description": "Clean ProxMenux uninstaller with optional removal of jq and dialog, cleanup of legacy translation files and the Monitor service, and restoration of system-file backups.",
|
||||
"ogTitle": "Uninstall ProxMenux | ProxMenux Documentation",
|
||||
"ogDescription": "Cleanly remove ProxMenux from a Proxmox host with optional dependency cleanup."
|
||||
},
|
||||
@@ -18,32 +18,32 @@
|
||||
"heading": "The uninstall flow",
|
||||
"items": [
|
||||
"<strong>Confirmation dialog.</strong> Yes/no — “Are you sure you want to uninstall ProxMenux?”",
|
||||
"<strong>Dependency removal checklist.</strong> Pre-selected list depends on install type (see table below). All boxes default to OFF — you opt in to removing each dependency.",
|
||||
"<strong>Removal runs with a progress bar.</strong> Removes the venv (Translation install only), the <code>menu</code> launcher, the <code>/usr/local/share/proxmenux/</code> tree, the ProxMenux Monitor service if present together with the notification target it registered in Proxmox VE (<code>proxmenux-webhook</code> and its matcher), the dependencies you ticked, and finally restores the system file backups (see below).",
|
||||
"<strong>Dependency removal checklist.</strong> Offers jq and dialog. Both boxes are OFF by default; select only dependencies that no other application needs.",
|
||||
"<strong>Removal runs with a progress bar.</strong> Removes any leftover legacy translation environment, the <code>menu</code> launcher, the <code>/usr/local/share/proxmenux/</code> tree, the ProxMenux Monitor service if present together with the notification target it registered in Proxmox VE (<code>proxmenux-webhook</code> and its matcher), the dependencies you ticked, and finally restores the system file backups (see below).",
|
||||
"<strong>Completion dialog.</strong> Lists removed dependencies and exits."
|
||||
]
|
||||
},
|
||||
"deps": {
|
||||
"heading": "Dependency removal: what's offered",
|
||||
"intro": "The checklist depends on install type. <strong>None of the boxes is checked by default</strong> — these are system-wide packages that other applications might use, so the safer default is to leave them.",
|
||||
"headerType": "Install type",
|
||||
"intro": "The checklist offers jq and dialog. <strong>Neither box is checked by default</strong>: other applications may use these system-wide packages, so keeping them is safer.",
|
||||
"headerType": "Installation",
|
||||
"headerOffered": "Offered for removal",
|
||||
"rows": [
|
||||
{
|
||||
"type": "Translation",
|
||||
"offeredRich": "<code>python3-venv</code>, <code>python3-pip</code>, <code>python3</code>, <code>jq</code>"
|
||||
"type": "Current releases",
|
||||
"offeredRich": "<code>dialog</code>, <code>jq</code>"
|
||||
},
|
||||
{
|
||||
"type": "Normal",
|
||||
"type": "Legacy installations after updating",
|
||||
"offeredRich": "<code>dialog</code>, <code>jq</code>"
|
||||
}
|
||||
],
|
||||
"warnTitle": "System-wide packages — think twice",
|
||||
"warnBody": "<code>python3</code>, <code>jq</code> and <code>dialog</code> are commonly used by other tools (including Proxmox itself in some workflows). Removing <code>python3</code> in particular can break Proxmox helpers, Ceph utilities and many third-party scripts. Leave them unless you're positive nothing else needs them."
|
||||
"warnBody": "The current checklist offers <code>jq</code> and <code>dialog</code>, not <code>python3</code>. These are system packages that other tools may need. Removal can also remove dependent packages or unused dependencies. Keep required packages and review any proposed removal before running apt manually."
|
||||
},
|
||||
"removed": {
|
||||
"heading": "What gets removed",
|
||||
"code": "/usr/local/bin/menu # the launcher\n/usr/local/share/proxmenux/ # everything: scripts, config, cache, version\n/opt/googletrans-env/ # virtual env (Translation install only)\n/etc/systemd/system/proxmenux-monitor.service # Monitor service unit\n/root/.config/proxmenux-monitor/ # Monitor config dir\n # + dependencies you ticked in the checklist"
|
||||
"code": "/usr/local/bin/menu # the launcher\n/usr/local/share/proxmenux/ # everything: scripts, config, cache, version\n/opt/googletrans-env/ # leftover legacy translation environment\n/etc/systemd/system/proxmenux-monitor.service # Monitor service unit\n/root/.config/proxmenux-monitor/ # Monitor config dir\n # + dependencies you ticked in the checklist"
|
||||
},
|
||||
"restored": {
|
||||
"heading": "What gets restored",
|
||||
@@ -59,18 +59,18 @@
|
||||
"manual": {
|
||||
"heading": "Manual uninstall",
|
||||
"intro": "If for some reason the menu uninstaller can't run (e.g. <code>dialog</code> already missing), the equivalent manual sequence:",
|
||||
"code": "# 1. Stop and remove the Monitor service (if installed)\nsystemctl stop proxmenux-monitor.service 2>/dev/null\nsystemctl disable proxmenux-monitor.service 2>/dev/null\nrm -f /etc/systemd/system/proxmenux-monitor.service\nrm -rf /root/.config/proxmenux-monitor\nsystemctl daemon-reload\nsystemctl reset-failed 2>/dev/null\n\n# 2. Remove the venv (Translation install only)\nrm -rf /opt/googletrans-env\n\n# 3. Remove ProxMenux files\nrm -f /usr/local/bin/menu\nrm -rf /usr/local/share/proxmenux\n\n# 4. Restore backups\n[ -f /root/.bashrc.bak ] && mv /root/.bashrc.bak /root/.bashrc\n[ -f /etc/motd.bak ] && mv /etc/motd.bak /etc/motd \\\n || sed -i '/This system is optimised by: ProxMenux/d' /etc/motd"
|
||||
"code": "# 1. Stop and remove the Monitor service (if installed)\nsystemctl stop proxmenux-monitor.service 2>/dev/null\nsystemctl disable proxmenux-monitor.service 2>/dev/null\nrm -f /etc/systemd/system/proxmenux-monitor.service\nrm -rf /root/.config/proxmenux-monitor\nsystemctl daemon-reload\nsystemctl reset-failed 2>/dev/null\n\n# 2. Remove a leftover legacy translation environment\nrm -rf /opt/googletrans-env\n\n# 3. Remove ProxMenux files\nrm -f /usr/local/bin/menu\nrm -rf /usr/local/share/proxmenux\n\n# 4. Restore backups\n[ -f /root/.bashrc.bak ] && mv /root/.bashrc.bak /root/.bashrc\n[ -f /etc/motd.bak ] && mv /etc/motd.bak /etc/motd \\\n || sed -i '/This system is optimised by: ProxMenux/d' /etc/motd"
|
||||
},
|
||||
"reinstall": {
|
||||
"heading": "Reinstalling later",
|
||||
"body": "Run the official ProxMenux installer again. Pick Translation or Normal as you prefer — the choice is independent of what you had before."
|
||||
"body": "Run the official ProxMenux installer again. Current releases use one installation path with all eight interface languages included."
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"hangTitle": "Uninstall hangs at “Removing googletrans and virtual environment”",
|
||||
"hangBody": "<code>pip uninstall</code> can stall if pip is unresponsive. From another shell: <code>rm -rf /opt/googletrans-env</code> directly (the script does the same as a fallback after pip).",
|
||||
"hangTitle": "Uninstall stalls while removing a legacy translation environment",
|
||||
"hangBody": "Current releases remove a leftover environment with <code>rm -rf /opt/googletrans-env</code>; they do not run <code>pip uninstall</code>. If this step stalls, inspect it from another shell and check the host filesystem before retrying.",
|
||||
"aptTitle": "apt warns about packages still in use during dependency removal",
|
||||
"aptBody": "Expected if you ticked <code>python3</code> or <code>jq</code> while other things on the host depend on them. apt's <code>autoremove</code> will refuse to remove them in that case (which is the safe behaviour). Untick that dependency and re-run.",
|
||||
"aptBody": "Selected packages are marked automatic and passed to <code>apt-get -y --purge autoremove</code>. This does not guarantee that dependent services are protected. Leave dependencies unchecked if other tools need them; review apt’s proposed removals before any manual cleanup.",
|
||||
"motdTitle": "MOTD still shows the ProxMenux line after uninstall",
|
||||
"motdBody": "Either no <code>/etc/motd.bak</code> existed and the sed strip didn't match (e.g. the line was modified). Edit <code>/etc/motd</code> by hand and remove any leftover ProxMenux line."
|
||||
},
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
"noLunTitle": "LUNs do not appear in /dev/disk/by-path after registering",
|
||||
"noLunBody": "<code>pvesm add iscsi</code> succeeded but the kernel is not seeing block devices. Check <code>iscsiadm --mode session</code> — if no session is active, start one manually with <code>iscsiadm --mode node --login</code>. If a session exists but no LUNs appear, force a rescan: <code>iscsiadm --mode session --rescan</code>. If still nothing, the target probably has no LUNs assigned to this IQN yet (configure LUN mapping on the target).",
|
||||
"chapTitle": "CHAP authentication",
|
||||
"chapBody": "ProxMenux does not expose the CHAP username / password fields in the interactive flow. If your target requires CHAP, register with ProxMenux first (discovery with CHAP may fail, but <code>pvesm add</code> will still write the entry), then add credentials manually: <code>pvesm set <id> --username <chap-user></code> and edit <code>/etc/iscsi/iscsid.conf</code> with the password, then <code>systemctl restart iscsid</code>. This is a gap in the current script — documented here so you know what to do."
|
||||
"chapBody": "ProxMenux does not expose CHAP username/password fields in the interactive flow. If discovery fails, the script stops before <code>pvesm add</code>; it does not register the storage anyway. Configure the target’s CHAP requirements separately in <code>open-iscsi</code>, including discovery authentication when required, then retry. Use <code>iscsiadm</code> to check the configuration and verify active sessions with <code>iscsiadm --mode session</code>."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Related",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
},
|
||||
"destructive": {
|
||||
"title": "Destructive tool for the 'format' path",
|
||||
"body": "The <em>Format</em> path <strong>erases every partition and byte on the selected disk</strong>. ProxMenux shows the disk list with a warning banner, filters out disks already in use, and requires an explicit confirmation before any <code>wipefs</code> / <code>sgdisk</code> / <code>mkfs</code> runs. Still — read the device path aloud twice before typing \"yes\"."
|
||||
"body": "The <em>Format</em> path <strong>destroys the existing partitions and data on the selected disk</strong>. ProxMenux shows the disk list with a warning banner, filters out disks already in use, and requires confirmation before any <code>wipefs</code> / <code>sgdisk</code> / <code>mkfs</code> runs. This is not a secure overwrite of every byte. Double-check the device path before confirming."
|
||||
},
|
||||
"compare": {
|
||||
"heading": "Directory vs ZFS pool — which to pick",
|
||||
@@ -78,7 +78,7 @@
|
||||
"Pick the filesystem — see the table above for trade-offs.",
|
||||
"Storage ID (default <code>disk-<device></code>), mount path, content-type preset.",
|
||||
"Confirm at the <strong>FINAL CONFIRMATION — DATA WILL BE ERASED</strong> dialog.",
|
||||
"ProxMenux wipes the partition table, creates one partition spanning the whole disk, runs <code>mkfs.<fs></code> (or <code>zpool create</code>), mounts it, adds it to <code>/etc/fstab</code> by UUID with <code>defaults,nofail</code>, and registers it in Proxmox via <code>pvesm add dir</code> or <code>pvesm add zfspool</code>."
|
||||
"ProxMenux clears the partition table and creates one partition spanning the disk. It runs <code>mkfs.<fs></code> or <code>zpool create</code> and mounts the result. Regular filesystems get an entry in <code>/etc/fstab</code> by UUID with <code>defaults,nofail</code>; ZFS uses its pool mount configuration instead. If <em>As Proxmox storage</em> is marked (always the case for ZFS), it is then registered with <code>pvesm add dir</code> or <code>pvesm add zfspool</code>; otherwise it stays a host mount only."
|
||||
],
|
||||
"tipTitle": "Why UUID + nofail in /etc/fstab",
|
||||
"tipBody": "The script writes <code>UUID=… /mnt/<id> <fs> defaults,nofail 0 2</code>. UUID survives device reordering across reboots (so <code>/dev/sdc</code> becoming <code>/dev/sdd</code> does not break boot). <code>nofail</code> means that if the disk ever disappears (hardware failure, unplugged), Proxmox still boots — storage will just show as inactive until the disk comes back."
|
||||
@@ -97,7 +97,7 @@
|
||||
},
|
||||
"presets": {
|
||||
"heading": "Content-type presets",
|
||||
"intro": "Instead of a long checklist, ProxMenux offers 4 presets plus a custom option. The preset string is passed to <code>pvesm add … --content <csv></code>:",
|
||||
"intro": "ProxMenux offers three presets plus a custom option. The selected content string is passed to <code>pvesm add … --content <csv></code>:",
|
||||
"headerPreset": "Preset",
|
||||
"headerContent": "Content string",
|
||||
"headerUse": "Use case",
|
||||
@@ -115,7 +115,7 @@
|
||||
{
|
||||
"preset": "All types",
|
||||
"content": "images,backup,iso,vztmpl,snippets",
|
||||
"use": "\"Let the host decide\" — allows every content type Proxmox supports on this storage."
|
||||
"use": "The broad preset shown here enables images, backups, ISOs, LXC templates and snippets. Add other supported types, such as rootdir, through Custom if needed."
|
||||
},
|
||||
{
|
||||
"preset": "Custom",
|
||||
@@ -124,7 +124,7 @@
|
||||
}
|
||||
],
|
||||
"zfsTitle": "ZFS pool content is narrower",
|
||||
"zfsBody": "If you picked <strong>zfs</strong> as the filesystem, Proxmox only accepts <code>images</code> and <code>rootdir</code> as content types on a <code>zfspool</code> (it is block storage, not a filesystem for ISOs). The presets above will still work but Proxmox silently drops the content types it cannot use — check <code>pvesm status</code> afterwards."
|
||||
"zfsBody": "If you picked <strong>zfs</strong>, a <code>zfspool</code> supports only <code>images</code> and <code>rootdir</code>, not ISO or backup files. Use Custom to enter a supported content list. The script forwards your selection unchanged; unsupported types may make registration fail. Check <code>pvesm status</code> afterwards."
|
||||
},
|
||||
"manual": {
|
||||
"heading": "Manual equivalent",
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
"rows": [
|
||||
{
|
||||
"bit": "1 (sticky)",
|
||||
"effect": "Only the file owner can delete / rename a file.",
|
||||
"why": "Prevents CT-A from deleting files created by CT-B in the same directory."
|
||||
"effect": "Deleting or renaming a file is restricted to its owner, the directory owner or a suitably privileged process.",
|
||||
"why": "Helps prevent users with different mapped UIDs from deleting each other’s files. It does not isolate CTs that share a mapped UID or privileged root access."
|
||||
},
|
||||
{
|
||||
"bit": "777 (rwx-rwx-rwx)",
|
||||
@@ -48,7 +48,7 @@
|
||||
{
|
||||
"bit": "ACLs (default)",
|
||||
"effect": "Inherited on every newly created file / subdir.",
|
||||
"why": "The permissions apply forever — new content keeps the open profile without re-running the script."
|
||||
"why": "New content inherits the default ACLs without re-running the script. Applications can still request restrictive modes or change permissions later."
|
||||
}
|
||||
],
|
||||
"privTitle": "Privileged CTs see the same thing, just without the shift",
|
||||
|
||||
@@ -46,13 +46,13 @@
|
||||
},
|
||||
{
|
||||
"method": "<strong>Both</strong>",
|
||||
"mount": "Both paths above (two independent NFS connections to the server)",
|
||||
"mount": "Both paths above (two mount points for the same NFS export)",
|
||||
"ui": "Yes",
|
||||
"useCase": "You want UI integration AND a stable host-side path with open permissions for LXC bind-mounts. Server sees two connections from the host."
|
||||
"useCase": "UI integration plus a separate stable host path with open permissions for LXC bind mounts."
|
||||
}
|
||||
],
|
||||
"bothTitle": "\"Both\" creates two independent NFS mounts",
|
||||
"bothBody": "Marking both options runs each method independently — pvesm mounts at <code>/mnt/pve/<id></code>, fstab mounts at <code>/mnt/<path></code>. The server sees two TCP connections from the Proxmox host. This is intentional: it lets you keep the pvesm storage clean (default Proxmox options) while having a separate host-side mount with open permissions for LXC bind-mounts."
|
||||
"bothBody": "Both methods run separately: pvesm mounts at <code>/mnt/pve/<id></code> and fstab at <code>/mnt/<path></code>. This provides a Proxmox-managed mount with default options and a separate host mount for LXC bind mounts. Two mount points do not guarantee two separate TCP connections; the NFS client may reuse transport connections."
|
||||
},
|
||||
"pvesmBranch": {
|
||||
"heading": "Method A — As Proxmox storage (pvesm)",
|
||||
@@ -94,7 +94,7 @@
|
||||
}
|
||||
],
|
||||
"warnTitle": "images and rootdir on NFS",
|
||||
"warnBody": "Marking <code>images</code> on an NFS storage lets Proxmox place live VM disks there. It works, but NFS latency + its lock semantics make this noticeably slower than local storage (and a network outage pauses every VM backed by that store). Marking <code>rootdir</code> means you will host LXC root filesystems over NFS, which historically has trouble with unprivileged containers (overlay / chown interactions). Prefer keeping <code>images</code> / <code>rootdir</code> on local or iSCSI storage and using NFS for <code>backup</code> / <code>iso</code> / <code>vztmpl</code>.",
|
||||
"warnBody": "Selecting <code>images</code> lets Proxmox store VM disks on NFS. Performance depends on the network, server and workload; an outage can block I/O that depends on the mount. Selecting <code>rootdir</code> stores LXC root filesystems on NFS, where unprivileged containers can encounter UID mapping, overlay and ownership limitations. Assess these requirements before placing <code>images</code> / <code>rootdir</code> there; NFS is also useful for <code>backup</code> / <code>iso</code> / <code>vztmpl</code>.",
|
||||
"result": "The result is <code>pvesm add nfs <id> --server <srv> --export <path> --content <csv></code> and Proxmox auto-mounts at <code>/mnt/pve/<id></code>."
|
||||
},
|
||||
"fstabBranch": {
|
||||
@@ -113,7 +113,7 @@
|
||||
"Attempts <code>chmod 1777</code> + <code>setfacl o::rwx</code> on the mount point (silent best-effort — only succeeds if the NFS server allows it; many NAS exports already serve world-writable paths)."
|
||||
],
|
||||
"lxcTitle": "Using the fstab mount from an LXC",
|
||||
"lxcBody": "The script prints the exact <code>pct set</code> command at the end to bind-mount the path into a container, e.g. <code>pct set <ctid> -mp0 /mnt/<path>,mp=/mnt/<ct-path>,shared=1,backup=0</code>. Or use the <mountLink>LXC Mount Manager</mountLink>, which detects the fstab mount automatically. <strong>No changes are made inside the container</strong> — for unprivileged LXCs to read/write the NFS data, the script relies on server-side world-writable export semantics (typical for Synology, TrueNAS, OMV defaults). If your NFS server squashes root or restricts perms, see Troubleshooting.",
|
||||
"lxcBody": "The script prints a <code>pct set</code> command for a bind mount, e.g. <code>pct set <ctid> -mp0 /mnt/<path>,mp=/mnt/<ct-path>,shared=1,backup=0</code>. Or use the <mountLink>LXC Mount Manager</mountLink>, which detects fstab mounts. <strong>No changes are made inside the container</strong>. Access from an unprivileged CT depends on server-side permissions for its mapped UIDs/GIDs. The script only attempts host-side permission changes; it cannot guarantee writable exports or manufacturer defaults. See Troubleshooting if access fails.",
|
||||
"noUiTitle": "The fstab mount is NOT a Proxmox storage",
|
||||
"noUiBody": "The host fstab mount is invisible to the Proxmox web UI — by design. It does not appear in <em>Datacenter > Storage</em>, you cannot select it in the VM / CT creator, and Proxmox backup jobs cannot target it. It is purely a host filesystem path. If you also want UI integration, mark <em>both</em> methods in the picker."
|
||||
},
|
||||
@@ -145,9 +145,9 @@
|
||||
"showmountTitle": "\"Failed to connect\" from showmount",
|
||||
"showmountBody": "The server refused the export-list query. Common causes: the server enforces strict client ACLs (your Proxmox IP is not on the allowed list), <code>rpcbind</code> is not running on the server, or the server exposes only NFSv4 with <code>showmount</code> disabled. The export path can still be added manually if you know it.",
|
||||
"inactiveTitle": "Storage shows as inactive in the Proxmox UI",
|
||||
"inactiveBody": "Run <em>Test NFS Connectivity</em> first — 99 % of the time this flags the exact hop that breaks (DNS, port, mount permissions). If connectivity is fine but Proxmox still flags inactive, check <code>journalctl -u pvestatd</code> on the Proxmox node; intermittent DNS or slow NFS mounts on boot can leave storages in an inactive state until <code>pvesm set <id> --disable 0</code> is re-applied.",
|
||||
"inactiveBody": "Run <em>Test NFS Connectivity</em> first: it checks that the server answers ping, that port 2049 is open and that the export list (<code>showmount -e</code>) is available. If connectivity works but storage remains inactive, inspect <code>journalctl -u pvestatd</code> and the server/export configuration. Restore the underlying connectivity or permissions first. <code>pvesm set <id> --disable 0</code> enables a disabled storage; it is not a general repair for NFS failures.",
|
||||
"lxcNoWriteTitle": "fstab mount works but unprivileged LXC can't write through a bind-mount",
|
||||
"lxcNoWriteBody": "NFS permissions are enforced server-side, not by the host. The fstab options (<code>uid=</code>, <code>file_mode=</code>) that work for CIFS do <strong>not</strong> apply to NFS. If your unprivileged LXC (root inside CT = UID 100000 on host, mapped to NFS as \"others\") cannot write, the NFS server is either squashing root or has restrictive perms. Fix on the server: change the export to <code>no_root_squash</code> if you trust the host, or set the export world-writable (Synology, TrueNAS, OMV all expose this in the UI). The script tries <code>chmod 1777</code> on the mount but that only succeeds when the server permits it.",
|
||||
"lxcNoWriteBody": "NFS access depends on server-side ownership, ACLs and squash settings. CIFS-style options such as <code>uid=</code> and <code>file_mode=</code> do <strong>not</strong> apply to NFS. With default LXC mapping, CT root becomes host UID 100000, not remote UID 0. Configure access for the actual mapped UID/GID or the server’s anonymous identity. <code>no_root_squash</code> only affects remote UID 0, so it is not a universal fix for UID 100000. The script attempts <code>chmod 1777</code> but cannot override the server’s permissions.",
|
||||
"fstabBootTitle": "fstab mount does not come up after reboot",
|
||||
"fstabBootBody": "The script adds <code>nofail,_netdev</code> so a missing share at boot does not block startup. If the mount never comes up: confirm the network is reachable (<code>ping <server></code>), check <code>journalctl -u remote-fs.target</code>, and verify the entry is valid with <code>mount -fav | grep nfs</code>. <code>mount -a</code> after boot mounts everything that is currently missing."
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"title": "What this does",
|
||||
"body": "ProxMenux offers two mount methods for any Samba share: <strong>(1) Proxmox storage</strong> via <code>pvesm add cifs</code> — visible in Datacenter > Storage, mounted at <code>/mnt/pve/<id></code>, credentials stored encrypted in <code>/etc/pve/priv/storage/<id>.pw</code>; <strong>(2) Host fstab mount</strong> at a path you pick — persistent via <code>/etc/fstab</code>, mounted with <code>uid=0,gid=0,file_mode=0777,dir_mode=0777</code> so unprivileged LXC bind-mounts can write, credentials stored in a root-only <code>/etc/samba/credentials/</code> file (password never in <code>fstab</code>). You can run one method, the other, or both."
|
||||
"body": "ProxMenux offers two mount methods for a Samba share: <strong>(1) Proxmox storage</strong> via <code>pvesm add cifs</code>, visible in Datacenter > Storage and mounted at <code>/mnt/pve/<id></code>. The password is stored as plaintext in <code>/etc/pve/priv/storage/<id>.pw</code>, protected by the root-only private directory; this is access control, not encryption. <strong>(2) Host fstab mount</strong> at a chosen path, persistent through <code>/etc/fstab</code> and mounted with <code>uid=0,gid=0,file_mode=0777,dir_mode=0777</code> so unprivileged LXC bind mounts can write. Its credentials are in a root-only file under <code>/etc/samba/credentials/</code>, never directly in <code>fstab</code>. Either or both methods can be used."
|
||||
},
|
||||
"opening": {
|
||||
"heading": "Opening the tool",
|
||||
@@ -41,24 +41,24 @@
|
||||
"method": "<strong>Host fstab only</strong>",
|
||||
"mountRich": "<code>/mnt/<path></code> with open uid/gid/file_mode",
|
||||
"ui": "No",
|
||||
"useCaseRich": "Bind-mounting the share into one or more LXCs <em>without</em> exposing it as a Proxmox storage. Open perms guarantee unprivileged CTs can write through the bind-mount."
|
||||
"useCaseRich": "Bind-mount the share into one or more LXCs <em>without</em> registering Proxmox storage. Open local permissions help unprivileged CTs access it, but writing still requires permission from the SMB server for the authenticated user."
|
||||
},
|
||||
{
|
||||
"method": "<strong>Both</strong>",
|
||||
"mount": "Both paths above (two independent CIFS connections to the server)",
|
||||
"mount": "Both paths above (two mount points for the same CIFS export)",
|
||||
"ui": "Yes",
|
||||
"useCase": "You want UI integration AND a stable host-side path with open permissions for LXC bind-mounts. The pvesm mount uses Proxmox defaults; the fstab mount applies the open uid/gid/file_mode separately."
|
||||
}
|
||||
],
|
||||
"bothTitle": "\"Both\" creates two independent CIFS connections",
|
||||
"bothBody": "pvesm and fstab mount the same share twice with different options. The pvesm mount at <code>/mnt/pve/<id></code> uses Proxmox defaults (no open uid/gid) — Proxmox UI is happy. The fstab mount at <code>/mnt/<path></code> uses <code>uid=0,gid=0,file_mode=0777,dir_mode=0777</code> — unprivileged LXC bind-mounts to it can write. Two TCP connections to the SMB server from the same Proxmox host."
|
||||
"bothTitle": "“Both” creates two CIFS mount points",
|
||||
"bothBody": "pvesm mounts at <code>/mnt/pve/<id></code> with Proxmox defaults. fstab mounts at <code>/mnt/<path></code> with <code>uid=0,gid=0,file_mode=0777,dir_mode=0777</code> to permit local access through LXC bind mounts. The SMB server still enforces the mounted user’s permissions. These are two mount points; they do not guarantee two separate TCP connections."
|
||||
},
|
||||
"pvesmBranch": {
|
||||
"heading": "Method A — As Proxmox storage (pvesm)",
|
||||
"intro": "If <em>As Proxmox storage</em> is marked, ProxMenux runs the original pvesm flow:",
|
||||
"items": [
|
||||
"<strong>Storage ID</strong> — default <code>cifs-<server-ip-with-dashes></code>. Only letters, digits, <code>-</code> and <code>_</code>.",
|
||||
"<strong>Content types</strong> — CIFS exposes <strong>6</strong> options (same as NFS minus <code>rootdir</code>, which Proxmox does not allow on CIFS because the locking semantics cannot hold a live LXC rootfs):"
|
||||
"<strong>Content types</strong> — this ProxMenux checklist offers <strong>6</strong> choices. It omits <code>rootdir</code> compared with the NFS checklist; this is a script-level choice, not a claim that every Proxmox CIFS backend version forbids LXC root filesystems:"
|
||||
],
|
||||
"headerType": "Content type",
|
||||
"headerAllows": "What it allows",
|
||||
@@ -89,16 +89,16 @@
|
||||
}
|
||||
],
|
||||
"warnTitle": "Live VM disks on CIFS",
|
||||
"warnBody": "If you tick <code>images</code>, ProxMenux pops up a warning before continuing. CIFS uses an advisory locking model that interacts badly with KVM disk operations (snapshots, live migration, I/O under contention). A backup or ISO store on CIFS is perfectly fine; a live-disk store is asking for trouble. Use NFS (or local storage) for <code>images</code> when you can.",
|
||||
"warnBody": "Selecting <code>images</code> triggers a ProxMenux warning that CIFS/SMB can cause locking issues with VM disk operations. The script recommends NFS for VM disk images but lets you continue. Backups and ISOs are common CIFS uses. Assess locking, snapshots, migration and workload requirements before using CIFS for <code>images</code>.",
|
||||
"credsTitle": "Where pvesm stores credentials",
|
||||
"credsBody": "When you use User authentication, the password is NOT written in <code>/etc/pve/storage.cfg</code>. Proxmox keeps it in <code>/etc/pve/priv/storage/<storage-id>.pw</code> — mode <code>0600</code>, owner <code>root</code>, member of the cluster sync. If you later change the password on the Samba server, use <code>pvesm set <id> --password <new></code> or remove and re-add through ProxMenux."
|
||||
"credsBody": "The password is not written in <code>/etc/pve/storage.cfg</code>. Proxmox writes plaintext credentials in <code>/etc/pve/priv/storage/<storage-id>.pw</code>, inside the private area of the cluster filesystem, readable only by <code>root</code> (mode <code>0600</code>); it is protected by access control, not by encryption. After a server password change, use <code>pvesm set <id> --password <new></code> or remove and re-add through ProxMenux."
|
||||
},
|
||||
"fstabBranch": {
|
||||
"heading": "Method B — Host fstab mount only",
|
||||
"intro": "If <em>As host fstab mount only</em> is marked, ProxMenux asks for a host mount path and persistent options, writes a root-only credentials file (User mode), then mounts and writes the entry to <code>/etc/fstab</code>:",
|
||||
"items": [
|
||||
"<strong>Host mount path</strong> — default <code>/mnt/<share-name></code>. Must be an absolute path. If something is already mounted there, or a fstab entry exists, ProxMenux offers to replace it.",
|
||||
"<strong>Mount options</strong> — pick <em>Read/Write</em> (default with <code>rw,uid=0,gid=0,file_mode=0777,dir_mode=0777,iocharset=utf8,nofail,_netdev</code>), <em>Read-only</em> (read-only variant with <code>file_mode=0555,dir_mode=0555</code>), or <em>Custom</em> (type your own option string). Open uid/gid/file_mode are always recommended for LXC bind-mount writes."
|
||||
"<strong>Mount options</strong> — choose <em>Read/Write</em> (default: <code>rw,uid=0,gid=0,file_mode=0777,dir_mode=0777,iocharset=utf8,nofail,_netdev</code>), <em>Read-only</em> (<code>file_mode=0555,dir_mode=0555</code>), or <em>Custom</em> (enter your own options). The script recommends open uid/gid/file_mode for writes through LXC bind mounts."
|
||||
],
|
||||
"credsTitle": "Credentials file (User mode)",
|
||||
"credsBody": "If you authenticated with a username + password, ProxMenux writes a root-only credentials file at <code>/etc/samba/credentials/<server>_<share>.cred</code> (mode <code>0600</code>) with <code>username=</code> and <code>password=</code> lines, and references it in the fstab entry via the <code>credentials=</code> mount option. Plain text never lands in <code>/etc/fstab</code>. For Guest mode, the option <code>guest</code> is appended instead and no credentials file is created.",
|
||||
@@ -110,7 +110,7 @@
|
||||
"Runs <code>systemctl daemon-reload</code> so systemd picks up the new fstab entry."
|
||||
],
|
||||
"lxcTitle": "Using the fstab mount from an unprivileged LXC",
|
||||
"lxcBody": "Because the CIFS client applies <code>uid=0,gid=0,file_mode=0777,dir_mode=0777</code>, every file in the mount is owned by host UID 0 with mode 0777. An unprivileged LXC bind-mounting the path sees \"others\" perms on every entry (CT root = host UID 100000 = others on the host filesystem), so reads and writes succeed. <strong>No changes are made inside the container</strong> — no <code>chown</code> in the CT, no group setup, nothing modified in <code>/etc/lxc</code> beyond the single <code>mp</code> bind-mount line. The script prints the exact <code>pct set</code> command at the end, or use the <mountLink>LXC Mount Manager</mountLink> to attach the path.",
|
||||
"lxcBody": "The CIFS options <code>uid=0,gid=0,file_mode=0777,dir_mode=0777</code> open local permission checks for LXC bind mounts. Server ACLs and negotiated Unix/POSIX semantics can still affect access. <strong>No changes are made inside the container</strong>: no CT <code>chown</code>, groups or edits to <code>/etc/lxc</code>. The <code>mp</code> line is managed in Proxmox CT configuration. Use the printed <code>pct set</code> command or the <mountLink>LXC Mount Manager</mountLink>.",
|
||||
"noUiTitle": "The fstab mount is NOT a Proxmox storage",
|
||||
"noUiBody": "The host fstab mount is invisible to the Proxmox web UI — by design. It does not appear in <em>Datacenter > Storage</em>, you cannot select it in the VM / CT creator, and Proxmox backup jobs cannot target it. It is purely a host filesystem path. If you also want UI integration, mark <em>both</em> methods in the picker."
|
||||
},
|
||||
@@ -121,12 +121,12 @@
|
||||
"fstabGuestIntro": "Method B (fstab, guest auth) — no credentials file:"
|
||||
},
|
||||
"view": {
|
||||
"heading": "View configured CIFS storages",
|
||||
"body": "Lists every CIFS entry in Proxmox (<code>pvesm status | awk ''$2 == \"cifs\"''</code>) with server, share, content types, username (or <em>Guest</em>), mount path and live status. Password is <strong>never printed</strong>. <strong>Note:</strong> this view only shows pvesm-registered storages — fstab-only mounts are not listed. Check those with <code>findmnt -t cifs</code> or <code>grep cifs /etc/fstab</code>."
|
||||
"heading": "View configured CIFS storages and host mounts",
|
||||
"body": "Shows registered CIFS storages (<code>pvesm status | awk ''$2 == \"cifs\"''</code>) with server, share, content, username or <em>Guest</em>, path and status. Passwords are <strong>never printed</strong>. <strong>Note:</strong> a second section lists host fstab mounts, their options, authentication-file path and active/inactive state. For manual checks use <code>findmnt -t cifs</code> or <code>grep cifs /etc/fstab</code>."
|
||||
},
|
||||
"remove": {
|
||||
"heading": "Remove CIFS storage",
|
||||
"body": "Runs <code>pvesm remove <storage-id></code> after a confirmation that shows the server / share / content. Only the Proxmox-side registration is removed — <strong>the remote Samba server is not touched</strong>. Proxmox also deletes the paired credentials file. To remove a fstab-only mount, edit <code>/etc/fstab</code> by hand, run <code>umount <path></code>, and remove the file from <code>/etc/samba/credentials/</code>.",
|
||||
"heading": "Remove CIFS storage or a host mount",
|
||||
"body": "The removal picker offers pvesm storages and host fstab mounts. For pvesm, it runs <code>pvesm remove <storage-id></code> and Proxmox removes the paired credentials. For fstab, it attempts <code>umount <path></code>, removes the matching <code>/etc/fstab</code> entry and credentials under <code>/etc/samba/credentials/</code>, and removes an empty mount directory if possible. A failed unmount requires a manual unmount or reboot. <strong>The remote Samba server and its files are not modified</strong>.",
|
||||
"warnTitle": "Back up dependencies first",
|
||||
"warnBody": "VMs, CTs or backup jobs that reference this storage by ID will fail after removal. Move / drop those references before removing the storage."
|
||||
},
|
||||
@@ -145,7 +145,7 @@
|
||||
"sleepTitle": "\"host is down\" or storage status goes inactive at night",
|
||||
"sleepBody": "Some NAS appliances put SMB to sleep aggressively. <code>pvestatd</code> then sees the storage as inactive until the first access wakes the NAS. If this is cosmetic, nothing is broken. If it causes backup failures, disable SMB idle disconnect on the NAS or schedule backups outside the sleep window.",
|
||||
"lxcNoWriteTitle": "Unprivileged LXC bind-mount can't write to the fstab path",
|
||||
"lxcNoWriteBody": "Confirm the mount uses the open options: <code>findmnt /mnt/<path></code> should show <code>uid=0,gid=0,file_mode=0777,dir_mode=0777</code>. If a Custom option string omits those, an unprivileged LXC will get permission denied (CT UIDs map to host \"others\", which without open file_mode have no write bit). Re-mount with the default RW preset or add the four options back to your custom string.",
|
||||
"lxcNoWriteBody": "Check <code>findmnt /mnt/<path></code> for the intended options, such as <code>uid=0,gid=0,file_mode=0777,dir_mode=0777</code>. Missing local write permissions can block mapped LXC UIDs. Reapply the default RW preset or adjust Custom options as needed. Also verify the mounted SMB user can write on the server and whether Unix/POSIX extensions supply server modes; open local modes cannot override server ACLs.",
|
||||
"fstabBootTitle": "fstab mount does not come up after reboot",
|
||||
"fstabBootBody": "The script adds <code>nofail,_netdev</code> so a missing share at boot does not block startup. If the mount never comes up: confirm the network is reachable (<code>ping <server></code>), check <code>journalctl -u remote-fs.target</code>, verify the credentials file still exists (<code>ls -l /etc/samba/credentials/</code>) and is readable, and try <code>mount -a</code> manually."
|
||||
},
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
},
|
||||
"privReq": {
|
||||
"title": "Privileged container requirement",
|
||||
"body": "The four <strong>LXC network sharing</strong> flows above require a <strong>privileged</strong> container — the kernel modules (<code>nfs-kernel-server</code>, <code>smbd</code>, <code>mount.nfs</code>, <code>mount.cifs</code>) need capabilities that unprivileged CTs do not expose. If you only need to share files between the host and an unprivileged CT, use the <mountLink>LXC Mount Manager</mountLink> instead — it bind-mounts from the host and adjusts permissions on the host side so the container can read and write without any kernel-module magic."
|
||||
"body": "The four <strong>LXC network sharing</strong> flows above require a <strong>privileged</strong> container. The scripts enforce this supported mode before configuring the services and mount tools (<code>nfs-kernel-server</code>, <code>smbd</code>, <code>mount.nfs</code>, <code>mount.cifs</code>). If you only need to share files between the host and an unprivileged CT, use the <mountLink>LXC Mount Manager</mountLink> instead — it bind-mounts from the host and adjusts permissions on the host side so the container can read and write without configuring these services or mount tools inside it."
|
||||
},
|
||||
"unprivExplain": {
|
||||
"title": "How ProxMenux handles unprivileged CT permissions",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"arrowLabel": "bind mount",
|
||||
"outro": "The host path on the left and the container path on the right can be different — for example, <code>/mnt/nas-films</code> on the host can become <code>/media/films</code> inside the container. The script adds the entry to the container config (<code>/etc/pve/lxc/<ctid>.conf</code>) using the next free <code>mpN</code> index, with two safe-defaults baked in:",
|
||||
"items": [
|
||||
"<code>shared=1</code> — tells Proxmox the data is shared storage, so it does not try to migrate the disk when you migrate the container.",
|
||||
"<code>shared=1</code> — tells Proxmox the mount uses shared data, so it does not migrate the data with the CT. This flag does not replicate data: the same path and data must already be available on the destination node.",
|
||||
"<code>backup=0</code> — excludes the bind mount from <code>vzdump</code> backups (the data lives on the host, you back it up separately)."
|
||||
]
|
||||
},
|
||||
@@ -64,7 +64,7 @@
|
||||
"idmapChangesRich": "Custom UID/GID mapping in <code>/etc/pve/lxc/<CTID>.conf</code> plus matching <code>/etc/subuid</code> + <code>/etc/subgid</code> entries on the host. CT must be restarted on every change.",
|
||||
"idmapWhenRich": "You need a <em>specific</em> UID inside the CT to map to a <em>specific</em> UID on the host (e.g. <code>media:1000</code> in the CT must own files as <code>media:1000</code> on the host so NFS doesn't squash). A more rigid setup, normally only worth it for that exact scenario.",
|
||||
"idmapTipTitle": "When you actually need lxc.idmap",
|
||||
"idmapTipBody": "If the LXC Mount Manager doesn't cover your case — typically because you need files written from inside the CT to land on the host as a specific UID/GID (NFS exports with <code>all_squash</code>, Samba shares with strict ownership, sharing a directory with a host user that has the same name as someone inside the CT) — that is the moment to add <code>lxc.idmap</code> entries by hand. The Mount Manager won't fight you: the bind-mount line it wrote is independent of any idmap configuration you add later."
|
||||
"idmapTipBody": "Use manual ID mapping when files written in the CT must appear on the host under a specific numeric UID/GID, for example to share ownership with a host user. It cannot override NFS <code>all_squash</code>; the server still decides the anonymous identity and permissions. Add <code>lxc.idmap</code> entries by hand if needed. The Mount Manager’s bind-mount line is independent of those entries."
|
||||
},
|
||||
"opening": {
|
||||
"heading": "Opening the tool",
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
}
|
||||
],
|
||||
"netEffectTitle": "Net effect",
|
||||
"netEffectBody": "Your container always boots, even if the NFS server is offline. The first time something touches the mount path, systemd quietly mounts it. If the server is still down, that one access fails with <em>resource temporarily unavailable</em> — but nothing else in the CT is affected."
|
||||
"netEffectBody": "The NFS filesystem is mounted on <em>first access</em> rather than eagerly during boot. If the server is offline, that access may wait or fail, and services that depend on the path can be affected. Automount reduces the boot-time dependency; it does not guarantee that every CT service is unaffected by an unavailable NFS server."
|
||||
},
|
||||
"manual": {
|
||||
"heading": "Manual equivalent",
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
"heading": "The \"sharedfiles\" group convention",
|
||||
"body": "Before exporting the folder, ProxMenux creates a group called <code>sharedfiles</code> with <strong>GID 101000</strong> inside the container, adds every regular user to it, then sets the export directory to <code>root:sharedfiles</code> with mode <code>2775</code>. The <code>2</code> at the front is the SGID bit — every file or folder created inside automatically inherits the <code>sharedfiles</code> group.",
|
||||
"gidTitle": "Why GID 101000 specifically",
|
||||
"gidBody": "It maps to host GID <strong>1000</strong> when an unprivileged container reads the same file (LXC default idmap shifts everything by +100000). In the current ProxMenux flow the NFS server itself runs in a <strong>privileged</strong> CT (no shift on its side), but the convention keeps the group ID numerically consistent with unprivileged client CTs that may mount this share later. Two privileged CTs both using <code>sharedfiles</code> at GID 101000 can read / write each other's files cleanly because the GID numbers match end-to-end.",
|
||||
"remapTitle": "The script also creates 'remap_*' users — they are vestigial here",
|
||||
"remapBody": "For every regular user in the CT (and for common UIDs like 33 = www-data, 1000, 1001, 1002), the script creates a parallel <code>remap_<uid></code> user with UID = <code><uid> + 100000</code>, all members of <code>sharedfiles</code>. The <code>+100000</code> shift mimics the LXC unprivileged idmap, but since this script enforces a <strong>privileged</strong> CT (no shift), those <code>remap_*</code> users are shadow accounts with no real-world counterpart on the host. They are harmless leftovers from a more ambitious design intent. If you don't see them in <code>getent passwd</code>, nothing breaks."
|
||||
"gidBody": "With the default LXC ID map (+100000), host GID 101000 appears as GID <strong>1000</strong> inside an unprivileged CT. This server flow uses a <strong>privileged</strong> CT, where there is no shift. Two privileged CTs using <code>sharedfiles</code> at GID 101000 therefore share the same numeric group ID.",
|
||||
"remapTitle": "Legacy 'remap_*' user creation is skipped for privileged CTs",
|
||||
"remapBody": "The legacy unprivileged branch would create <code>remap_<uid></code> users with UID <code><uid> + 100000</code>, all in <code>sharedfiles</code>, for regular users and common UIDs (33, 1000, 1001, 1002). This <code>+100000</code> shift is irrelevant in the <strong>privileged</strong> CTs required by this flow, so the script skips that branch. Missing <code>remap_*</code> accounts in <code>getent passwd</code> are expected and do not indicate a failure."
|
||||
},
|
||||
"defaults": {
|
||||
"heading": "Default export options — read this first",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"creds": {
|
||||
"heading": "Where the password lives",
|
||||
"body": "ProxMenux <strong>never stores the password in plain text</strong> in the mount command or in <code>/etc/fstab</code>. Instead it writes a credentials file inside the CT:",
|
||||
"body": "ProxMenux <strong>does not put the password in the mount command</strong> or in <code>/etc/fstab</code>. It writes a credentials file inside the CT instead. That file contains plaintext credentials protected by root-only permissions; it is not encrypted:",
|
||||
"whyTitle": "Why a separate file rather than fstab",
|
||||
"whyBody": "The CIFS module accepts <code>username=</code> / <code>password=</code> options inline in fstab, but anyone who can read <code>/etc/fstab</code> sees the password in clear. Putting credentials in a root-only file and pointing fstab at it (<code>credentials=</code>) keeps the password out of world-readable config."
|
||||
},
|
||||
@@ -85,7 +85,7 @@
|
||||
}
|
||||
],
|
||||
"netEffectTitle": "Net effect of the fstab flags",
|
||||
"netEffectBody": "Your container always boots, even if the Samba server is offline. The first time something touches the mount path, systemd quietly mounts it. If the server is still down, that one access fails with <em>resource temporarily unavailable</em> — but nothing else in the CT is affected."
|
||||
"netEffectBody": "The CIFS filesystem is mounted on <em>first access</em> rather than eagerly during boot. If the server is offline, that access may wait or fail, and services that depend on the path can be affected. Automount reduces the boot-time dependency; it does not guarantee that every CT service is unaffected by an unavailable CIFS server."
|
||||
},
|
||||
"manual": {
|
||||
"heading": "Manual equivalent",
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
"noShareTitle": "Client connects but cannot see the share",
|
||||
"noShareBody": "Check that <code>browseable = yes</code> is set in the share block (default for rw / ro modes; may be missing in custom). Also check the CT firewall and the Proxmox host firewall allow TCP 445 (SMB) and 139 (NetBIOS). Some Windows clients also require name resolution — try the IP directly first.",
|
||||
"authTitle": "Authentication fails (NT_STATUS_LOGON_FAILURE)",
|
||||
"authBody": "Either the wrong password (Samba passwords are <em>separate</em> from system passwords — see them with <code>pdbedit -L</code>) or the user is not in <code>valid users</code> for that share. Reset the password with <code>smbpasswd <user></code> inside the CT.",
|
||||
"authBody": "Either the password is wrong (Samba passwords are <em>separate</em> from system passwords; list Samba users with <code>pdbedit -L</code>) or the user is not in <code>valid users</code> for that share. Reset the password with <code>smbpasswd <user></code> inside the CT.",
|
||||
"groupTitle": "Files written by the client appear with wrong group on the server",
|
||||
"groupBody": "The script sets <code>force group = sharedfiles</code> in the share block, so new files should be group <code>sharedfiles</code>. If they aren't, the SGID bit on the parent directory may have been lost (someone ran <code>chmod</code> by hand). Reapply: <code>chmod 2775 /mnt/<share></code>.",
|
||||
"bothTitle": "Sharing the same folder over both NFS and Samba",
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
{
|
||||
"format": "OVF",
|
||||
"output": "name-vmid-ts-ovf/",
|
||||
"pros": "~120% disk overhead. Easier to inspect (descriptor is plain XML). Can edit before importing.",
|
||||
"pros": "~120% of virtual disk size. Easier to inspect (descriptor is plain XML). Can edit before importing.",
|
||||
"cons": "Multiple files — must transfer all of them together."
|
||||
}
|
||||
]
|
||||
@@ -55,7 +55,7 @@
|
||||
"heading": "Destination directory",
|
||||
"body": "Pick from presets (<code>/var/lib/vz/dump</code>, <code>/var/lib/vz/template/iso</code>) or enter a manual path. The script validates the directory is writeable and warns if free space looks tight before starting.",
|
||||
"calloutTitle": "Free space rule of thumb",
|
||||
"calloutBody": "For an OVF export of a VM with disks totalling 100 GB virtual: budget ~120 GB free. For an OVA: budget ~220 GB. Sparse / mostly-empty disks may use less, but the conversion writes them out fully before the OVA TAR step compresses anything. If you run out of space mid-export, the temp directory is cleaned up by the EXIT trap and you start over."
|
||||
"calloutBody": "For an OVF export of a VM with disks totalling 100 GB virtual: budget ~120 GB free. For an OVA: budget ~220 GB. Actual usage may be lower for mostly-empty disks. The OVA archive is created with uncompressed TAR while the temporary VMDK files still exist, so allow space for both. If you run out of space mid-export, the temp directory is cleaned up by the EXIT trap and you start over."
|
||||
},
|
||||
"package": {
|
||||
"heading": "What ends up in the package",
|
||||
@@ -120,8 +120,8 @@
|
||||
"noSpaceBody": "Destination ran out of space. The temp directory is auto-cleaned by the EXIT trap. Pick a destination with more headroom (rule of thumb above) and re-run.",
|
||||
"unsupportedHwTitle": "Export completes but VMware refuses to import: \"Unsupported hardware family\"",
|
||||
"unsupportedHwBody": "Some ESXi versions reject OVF descriptors that declare a hardware family they don't recognise. Open the .ovf in a text editor (or extract the .ova first), find <code><vssd:VirtualSystemType></code> and edit it to a value ESXi accepts (e.g. <code>vmx-13</code> for ESXi 6.5+). For a quick workaround, try VirtualBox — it's more permissive.",
|
||||
"nicTitle": "Imported VM in VMware has e1000 NIC but I want VirtIO",
|
||||
"nicBody": "Expected — the OVF only stores the NIC count, not the model. Edit the imported VM's NIC settings in VMware after import. Same applies for SCSI controller (export uses lsilogic for VMware compatibility; change to <code>VirtIO SCSI</code> if your guest supports it).",
|
||||
"nicTitle": "Imported VM uses a different NIC or SCSI controller",
|
||||
"nicBody": "The OVF preserves the NIC count, not the original model. Review the imported VM’s network settings in the destination hypervisor. The export declares an lsilogic SCSI controller for VMware compatibility. When importing back into Proxmox with ProxMenux, the VM is created with an LSI controller and e1000 NICs; switch to <code>VirtIO SCSI</code> and VirtIO afterwards if the guest has suitable drivers.",
|
||||
"runningTitle": "VM was running and I declined to stop it — export aborted",
|
||||
"runningBody": "The script can't produce a consistent image while disks are being written. Either accept the shutdown prompt next time, or stop the VM manually first (<code>qm shutdown $VMID</code>) and re-run.",
|
||||
"slowTitle": "Disk conversion is slow",
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
},
|
||||
{
|
||||
"label": "qm create + importdisk",
|
||||
"detail": "qm create $VMID\nqm importdisk\n(VMDK → qcow2)\nqm set --scsiN",
|
||||
"detail": "qm create $VMID\nqm importdisk\n(VMDK → storage format)\nqm set --scsiN",
|
||||
"variant": "target"
|
||||
}
|
||||
]
|
||||
@@ -86,7 +86,7 @@
|
||||
},
|
||||
"memWarn": {
|
||||
"title": "Memory unit ambiguity",
|
||||
"body": "The parser <strong>assumes MiB</strong>. If the OVF declares memory in <em>GB</em> (e.g. some VMware exports do), the imported VM will have 1/1024th of the intended RAM. After import, double-check <code>qm config $VMID | grep memory</code> against the source VM's documented RAM and adjust with <code>qm set $VMID --memory <MiB></code> if it's off by a factor of 1024 or 1024²."
|
||||
"body": "The parser normalizes recognized memory units to <strong>MiB</strong>, including bytes, KiB, MiB, GiB and supported textual labels. Missing or unrecognized units are <em>treated as MiB</em>. After import, compare <code>qm config $VMID | grep memory</code> with the source VM’s documented RAM and, if needed, correct it using <code>qm set $VMID --memory <MiB></code>."
|
||||
},
|
||||
"dialog": {
|
||||
"heading": "Import dialog flow",
|
||||
@@ -108,7 +108,7 @@
|
||||
"heading": "Disk import loop",
|
||||
"intro": "For each disk reference in the OVF:",
|
||||
"items": [
|
||||
"<code>qm importdisk $VMID $disk_path $STORAGE</code> — converts the VMDK to the storage-native format (e.g. qcow2 on local-lvm, raw on ZFS) and creates an <code>unusedN:</code> entry in the VM config.",
|
||||
"<code>qm importdisk $VMID $disk_path $STORAGE</code> — imports the disk in a format supported by the target storage and creates an <code>unusedN:</code> entry in the VM configuration.",
|
||||
"The script greps the config for the just-created <code>unusedN</code> reference.",
|
||||
"<code>qm set $VMID --scsiN $unused_disk</code> — attaches the disk as <code>scsi0</code>, <code>scsi1</code>, …",
|
||||
"<code>qm set $VMID --delete unusedN</code> — clears the now-redundant unused marker."
|
||||
@@ -175,11 +175,11 @@
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"orphanTitle": "VM was created but disk import failed — orphan VM left behind",
|
||||
"orphanIntro": "Known limitation. The script doesn't auto-clean a partial import. Destroy the orphan with:",
|
||||
"orphanIntro": "When an import fails, the script offers to remove the partial VM and its imported disks. If you declined, or automatic deletion failed, inspect the VM and remove it manually with:",
|
||||
"orphanCode": "qm destroy $VMID --destroy-unreferenced-disks 1",
|
||||
"orphanOutro": "Then fix the underlying cause (likely disk space on the target storage) and re-import.",
|
||||
"memTitle": "Imported VM has 8 MB of RAM (or 8 TB)",
|
||||
"memIntro": "Memory unit ambiguity in the OVF parser. Off by a factor of 1024 → OVF used GB instead of MiB. Fix:",
|
||||
"memIntro": "The parser converts recognized AllocationUnits to MiB. Missing or unsupported units are treated as MiB, so inspect the OVF and compare the imported setting with the source VM. Correct the memory if necessary:",
|
||||
"memCode": "qm set $VMID --memory 8192 # 8 GiB",
|
||||
"bootTitle": "Imported VM doesn't boot — \"No bootable device\"",
|
||||
"bootIntro": "Most common cause: BIOS / UEFI mismatch. The VM was UEFI but Proxmox created it as BIOS. Set the matching firmware:",
|
||||
@@ -188,7 +188,7 @@
|
||||
"bsodTitle": "VMware-exported Windows VM imports but BSODs on first boot",
|
||||
"bsodBody": "Windows is sensitive to disk controller changes. Either: (a) install VirtIO drivers <em>before</em> exporting from VMware, or (b) keep the SCSI controller as <code>lsi</code> (the default) and only switch to VirtIO SCSI after the guest boots and you can install the VirtIO drivers in Windows.",
|
||||
"zeroTitle": "OVF parser reports 0 disks",
|
||||
"zeroBody": "The OVF descriptor uses an unusual disk reference style. Open the .ovf in a text editor and confirm each disk has a <code><File ovf:href=\"...vmdk\" ...></code> entry. If the file extension is unusual (e.g. just <code>.dat</code>), rename it to <code>.vmdk</code> and update the OVF reference, then re-run.",
|
||||
"zeroBody": "The OVF descriptor may use a disk reference style the parser does not recognize. Open the .ovf and look for each disk’s <code><File ovf:href=\"...vmdk\" ...></code> entry. If a disk really is VMDK but has an unusual extension such as <code>.dat</code>, rename it to <code>.vmdk</code> and update the OVF reference. Renaming does not convert a disk’s format.",
|
||||
"awkTitle": "awk: syntax error at or near , — parser fails on every OVA / OVF",
|
||||
"awkIntro": "The OVF parser uses gawk-specific syntax (3-argument <code>match()</code>) which mawk — the default <code>awk</code> on Debian / Proxmox — does not support. Recent versions of the script auto-install gawk on first use via the canonical <code>ensure_repositories</code> + <code>install_single_package</code> pair; if you're running an older copy, install it manually:",
|
||||
"awkCode": "apt-get install -y gawk",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"title": "System maintenance",
|
||||
"body": "Keep the host healthy: CLI tooling, regular updates, and the major-version upgrade when it's time.",
|
||||
"bullets": [
|
||||
"System Utilities Installer (26 CLI tools)",
|
||||
"System Utilities Installer (25 CLI tools)",
|
||||
"Proxmox System Update (apt + dist-upgrade)",
|
||||
"PVE 8 → PVE 9 major upgrade"
|
||||
]
|
||||
@@ -73,7 +73,7 @@
|
||||
"options": [
|
||||
{
|
||||
"title": "System Utilities Installer",
|
||||
"description": "Curated picker for 26 CLI tools (htop, btop, iperf3, jq, tmux, ncdu, ...) with custom selection or predefined groups (basic, dev, compression, multiplexers, analysis, network). Uses the canonical repo + verify-command flow.",
|
||||
"description": "Curated picker for 25 CLI tools (htop, btop, iperf3, tmux, ...) with custom selection or predefined groups (basic, dev, compression, multiplexers, analysis, network). Uses the canonical repo + verify-command flow.",
|
||||
"href": "/docs/utils/system-utils"
|
||||
},
|
||||
{
|
||||
@@ -106,10 +106,10 @@
|
||||
},
|
||||
"diskSpaceCallout": {
|
||||
"title": "A note on disk space for export / import",
|
||||
"body": "Both tools convert disk formats: export uses <code>qemu-img convert -O vmdk -o subformat=streamOptimized</code>; import uses <code>qm importdisk</code> to convert back to the storage-native format (qcow2 / raw). Plan for <strong>~120% of virtual disk size</strong> for OVF and <strong>~220%</strong> for OVA — the conversion writes the full disk before any compression. Check the destination directory has the headroom before you start."
|
||||
"body": "Both tools convert disk formats: export uses <code>qemu-img convert -O vmdk -o subformat=streamOptimized</code>; import uses <code>qm importdisk</code> to convert back to the storage-native format (qcow2 / raw). For export, plan for <strong>~120% of virtual disk size</strong> for OVF and <strong>~220%</strong> for OVA. The OVA archive uses uncompressed TAR and is created while the temporary VMDK files still exist. Check the destination directory has the headroom before you start."
|
||||
},
|
||||
"fitsTogether": {
|
||||
"heading": "How the menu fits together",
|
||||
"body": "Each tool has a dedicated script under <code>scripts/utilities/</code>. The Proxmox System Update is a wrapper that delegates to one of two worker scripts in <code>scripts/global/</code> depending on the detected major version (PVE 8 or PVE 9). The PVE 8 → 9 upgrade exposes two extra menu actions inside its own flow — a stand-alone <em>Pre-upgrade check</em> (runs <code>pve8to9 --full</code>) and a read-only <em>Manual upgrade guide</em> (17-step runbook) — for users who want to inspect or operate by hand instead of the automated path."
|
||||
"body": "Each tool has a dedicated script under <code>scripts/utilities/</code>. Proxmox System Update calls one safe worker in <code>scripts/global/</code>, update-pve-safe.sh, which detects the major version and handles both PVE 8 and PVE 9. The PVE 8 → 9 upgrade offers two extra actions in its own menu: a stand-alone <em>Pre-upgrade check</em> (runs <code>pve8to9 --full</code>) and a read-only <em>Manual upgrade guide</em> (17-step runbook), for users who want to inspect the process or carry it out by hand."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Proxmox System Update | ProxMenux Documentation",
|
||||
"description": "Runs the official Proxmox upgrade sequence (apt update + apt full-upgrade -y) and adds the repo hygiene, essential-package check, LVM sanity scan, autoremove/autoclean and reboot prompt that the upgrade guide also recommends. Detects the running major version automatically.",
|
||||
"description": "Updates packages within the current Proxmox major version with apt-get update and apt full-upgrade -y. Checks disk space and configured repositories, attempts GPG key recovery, checks and repairs old LVM PV headers, rebuilds managed DKMS drivers when needed, runs autoremove/autoclean and offers a reboot when required.",
|
||||
"ogTitle": "Proxmox System Update | ProxMenux Documentation",
|
||||
"ogDescription": "Official apt full-upgrade / dist-upgrade wrapped with repo hygiene, autoremove and a smart reboot prompt."
|
||||
"ogDescription": "apt full-upgrade with repository checks, autoremove/autoclean and a reboot prompt when required."
|
||||
},
|
||||
"header": {
|
||||
"title": "Proxmox System Update",
|
||||
"description": "Wrapper that delegates to a single safe worker (<code>update-pve-safe.sh</code>) which detects the running Proxmox major version by itself. The configured repositories are read through the Proxmox API and kept as they are; a host with no active subscription whose only Proxmox repository is Enterprise is asked before switching to no-subscription. All packages are upgraded, ProxMenux-managed DKMS drivers are rebuilt if a new kernel landed, and the reboot prompt fires only when the kernel actually changed. Also launchable from the <em>Update Now</em> button in the ProxMenux Monitor dashboard header when pending updates are detected.",
|
||||
"description": "Delegates to a single worker (<code>update-pve-safe.sh</code>) that detects the running Proxmox major version. Configured repositories are read through the Proxmox API and preserved; an unsubscribed host with only Enterprise is asked before switching to no-subscription. The worker upgrades packages and rebuilds ProxMenux-managed DKMS drivers for a staged kernel. The wrapper offers a reboot when the system reboot marker exists or the newest installed kernel differs from the running kernel. Also available from <em>Update Now</em> in the ProxMenux Monitor header when pending updates are detected.",
|
||||
"section": "Utilities"
|
||||
},
|
||||
"calloutWhat": {
|
||||
@@ -22,25 +22,25 @@
|
||||
},
|
||||
"onTop": {
|
||||
"heading": "What ProxMenux runs on top — verified against the script",
|
||||
"intro": "This option runs <strong>exactly</strong> the apt command above, wrapped with the repo hygiene, DKMS rebuild for ProxMenux-managed drivers and post-upgrade cleanup the official upgrade guide also recommends. Everything below maps 1:1 to <code>scripts/utilities/proxmox_update.sh</code> and the single safe worker <code>scripts/global/update-pve-safe.sh</code> — nothing implied, every step is in the code:",
|
||||
"intro": "Uses <strong>the same apt full-upgrade operation</strong>, with repository checks, DKMS rebuilding and post-update cleanup. The steps below correspond to <code>scripts/utilities/proxmox_update.sh</code> and its single worker <code>scripts/global/update-pve-safe.sh</code>:",
|
||||
"items": [
|
||||
"<strong>Detects the PVE major version</strong> from inside the worker (<code>pveversion | grep -oP ''pve-manager/\\K[0-9]+''</code>) and adapts the base Proxmox / Debian repo URLs (bookworm on PVE 8, trixie on PVE 9). There is no fan-out to per-version worker scripts — a single safe worker handles both.",
|
||||
"<strong>Detects the PVE major version</strong> inside the worker (<code>pveversion | grep -oP ''pve-manager/\\K[0-9]+''</code>). A single worker handles PVE 8 and PVE 9; configured repositories are preserved unless an unsubscribed host accepts the offered switch.",
|
||||
"<strong>Keeps the configured repositories.</strong> <code>ensure_repositories</code> reads the repositories through the Proxmox repository API, together with the subscription status. A host with an active subscription, or one that already uses the no-subscription or test repository, is left unchanged. A host with no active subscription whose only Proxmox repository is Enterprise is asked whether to switch to no-subscription; declining stops the update with no source changed.",
|
||||
"<strong>Runs the upgrade non-interactively</strong> with <code>DEBIAN_FRONTEND=noninteractive</code> and <code>--force-confdef --force-confold</code> — if a configuration file you already modified also changed upstream, your version stays in place. No silent overwrites of custom configs.",
|
||||
"<strong>Runs the upgrade non-interactively</strong> with <code>DEBIAN_FRONTEND=noninteractive</code> and <code>--force-confdef --force-confold</code>. For dpkg conffile decisions, it accepts the default action when one exists; otherwise it keeps the existing configuration file.",
|
||||
"<strong>Skips forcing optional utilities.</strong> The safe worker does not push <code>zfsutils-linux</code>, <code>chrony</code>, <code>ifupdown2</code> or similar packages onto the host — a Proxmox install that opted out of any of them keeps its choice. Missing packages are surfaced by the higher-level installer flows, not by the update path.",
|
||||
"<strong>LVM metadata sanity check</strong> against stray PV headers from passthrough disks (warn-only, no automatic fix).",
|
||||
"<strong>LVM metadata check and repair.</strong> Detects old PV headers and runs vgck --updatemetadata and vgchange -ay for the affected volume groups. This can change LVM metadata; it is not a warning-only scan.",
|
||||
"<strong>Cleans up afterwards:</strong> <code>apt-get autoremove -y</code> + <code>apt-get autoclean -y</code>.",
|
||||
"<strong>DKMS rebuild before the reboot prompt.</strong> When the upgrade staged a new kernel, the wrapper calls <code>pmx_rebuild_dkms_after_kernel</code> to rebuild every driver that ProxMenux installed via DKMS against the incoming kernel version — so the modules are ready before the box comes back up. Reboot detection uses <code>/var/run/reboot-required</code> when <code>needrestart</code> is present, and falls back to a <code>dpkg-query</code> comparison between the running kernel and the newest installed <code>proxmox-kernel-*-pve-signed</code> / <code>pve-kernel-*-pve</code> package when it isn't — a signal that survives the many Proxmox hosts that ship without <code>needrestart</code>."
|
||||
"<strong>DKMS rebuild before the reboot prompt.</strong> The worker calls <code>pmx_rebuild_dkms_after_kernel</code> when a newer installed kernel is staged. The wrapper checks <code>/var/run/reboot-required</code> and also uses <code>dpkg-query</code> to compare the kernel reported by <code>uname -r</code> with the newest installed <code>proxmox-kernel-*-pve-signed</code> / <code>pve-kernel-*-pve</code> package. The marker may be absent on hosts without <code>needrestart</code>; the kernel comparison still works in that case."
|
||||
]
|
||||
},
|
||||
"calloutOneSentence": {
|
||||
"title": "In one sentence",
|
||||
"body": "Same upgrade Proxmox tells you to run, plus the repo cleanup, the essential-package check, the LVM sanity scan, the autoremove/autoclean afterwards, and a reboot prompt only when it matters."
|
||||
"body": "Updates host packages, preserves configured repositories unless you accept a switch, checks LVM metadata, rebuilds managed DKMS drivers, cleans up with autoremove/autoclean and offers a reboot when needed."
|
||||
},
|
||||
"confirm": {
|
||||
"heading": "Confirmation dialog",
|
||||
"intro": "Selecting the option opens a summary of what the worker will do, requiring an explicit confirmation:",
|
||||
"imageAlt": "Proxmox System Update confirmation dialog listing repo hygiene, package updates, cleanup"
|
||||
"imageAlt": "Proxmox System Update confirmation dialog with repository checks, package updates and cleanup"
|
||||
},
|
||||
"routes": {
|
||||
"heading": "How the wrapper routes",
|
||||
@@ -61,14 +61,14 @@
|
||||
},
|
||||
"worker": {
|
||||
"heading": "What the worker does",
|
||||
"intro": "A single worker (<code>scripts/global/update-pve-safe.sh</code>) handles both PVE 8 and PVE 9. It detects the major version internally and uses the version-appropriate codename (<code>bookworm</code> or <code>trixie</code>) for its base sources. The stages are:",
|
||||
"intro": "One worker (<code>scripts/global/update-pve-safe.sh</code>) handles PVE 8 (<code>bookworm</code>) and PVE 9 (<code>trixie</code>). It detects the major version internally and checks the existing repository configuration without rewriting the Debian base sources. The stages are:",
|
||||
"items": [
|
||||
"<strong>Sanity checks.</strong> Verifies at least ~1 GB free in <code>/var/cache/apt/archives</code>. Aborts early with a clear message when it fails, so the run doesn't die in the middle of an apt transaction.",
|
||||
"<strong>Repository check.</strong> <code>ensure_repositories</code> reads the repositories and the subscription status. On a host with a usable Proxmox repository it changes nothing; on a host with no active subscription and only the Enterprise repository it asks before switching to no-subscription, and stops the update when the answer is no.",
|
||||
"<strong>Apt update with GPG auto-recovery.</strong> On <code>NO_PUBKEY</code> for any repo (yours or a third-party one) the worker imports the missing key and retries automatically before failing.",
|
||||
"<strong>Pending upgrades + security count.</strong> Reports how many packages will change and how many of those come from the security suite, so the confirmation dialog has real numbers to show.",
|
||||
"<strong>Confirmation dialog.</strong> The wrapper asks for an explicit yes before touching apt.",
|
||||
"<strong>apt full-upgrade.</strong> Runs with <code>DEBIAN_FRONTEND=noninteractive</code> and <code>--force-confdef --force-confold</code> so any configuration file you customised keeps its current contents when upstream also changed it. Never overwrites operator-edited configs silently.",
|
||||
"<strong>Confirmation dialog.</strong> After refreshing package lists, the worker asks for an explicit yes before running the package upgrade.",
|
||||
"<strong>apt full-upgrade.</strong> Uses <code>DEBIAN_FRONTEND=noninteractive</code> and <code>--force-confdef --force-confold</code>. Dpkg follows its default action for conffile decisions when available and otherwise retains the existing file.",
|
||||
"<strong>LVM sanity check.</strong> <code>lvm_repair_check</code> refreshes VG metadata when disks passed through to guest VMs (DSM, TrueNAS, storage appliances) come back with old PV headers.",
|
||||
"<strong>DKMS rebuild for ProxMenux-managed drivers.</strong> When the upgrade staged a new kernel, <code>pmx_rebuild_dkms_after_kernel</code> reads <code>components_status.json</code> for the drivers ProxMenux installed (currently <code>nvidia_driver</code> → module <code>nvidia</code>, <code>coral_driver</code> → module <code>gasket</code>), installs the matching kernel headers (<code>proxmox-headers-<newkver></code> when available, else <code>pve-headers-<newkver></code>) and runs <code>dkms autoinstall -k <newkver></code>. If <code>dkms status</code> then doesn't show the modules built against the new kernel, the worker falls back to re-running each installer with <code>--auto-reinstall</code>. Any failure is logged but does not abort the update — you land on the reboot prompt in every case.",
|
||||
"<strong>Post-cleanup.</strong> <code>apt-get autoremove</code> + <code>apt-get autoclean</code> before returning control to the wrapper."
|
||||
@@ -78,21 +78,21 @@
|
||||
"heading": "Post-update cleanup & reboot",
|
||||
"intro": "After the worker exits, the wrapper runs:",
|
||||
"code": "apt-get autoremove -y # drop unused dependencies pulled in by old packages\napt-get autoclean # drop downloaded .deb files no longer in the index",
|
||||
"afterCode": "Then it checks whether a reboot is needed. Two signals trigger the prompt:",
|
||||
"afterCode": "The wrapper also checks whether a reboot is needed. Either of these signals triggers the prompt:",
|
||||
"items": [
|
||||
"<code>/var/run/reboot-required</code> exists (created by the kernel package post-install hook)",
|
||||
"The update log contains <code>linux-image</code> entries (kernel was actually upgraded)"
|
||||
"<code>/var/run/reboot-required</code> exists: a package or system tool has marked the host as needing a reboot.",
|
||||
"The newest installed Proxmox kernel package differs from the running kernel, as determined by <code>dpkg-query</code> and uname -r."
|
||||
],
|
||||
"outro": "If either is true, a whiptail dialog asks <em>\"Some changes require a reboot to take effect. Do you want to restart now?\"</em>. Decline to keep running on the old kernel until you choose to reboot manually (e.g. during a planned maintenance window)."
|
||||
},
|
||||
"end": {
|
||||
"heading": "What you see at the end",
|
||||
"intro": "When the worker finishes, the terminal shows the cleanup output and (if the kernel changed) the reboot prompt:",
|
||||
"intro": "When the worker finishes, the terminal shows the cleanup output and, if a reboot is required, the reboot prompt:",
|
||||
"imageAlt": "Proxmox System Update completion summary with cleanup output and reboot prompt"
|
||||
},
|
||||
"calloutDeclineReboot": {
|
||||
"title": "Decline reboot only if you know why",
|
||||
"body": "Running on an old kernel after upgrading <code>linux-image-*</code> means you're on a half-upgraded system: userspace is new, kernel is old. Most of the time things work, but ZFS modules, IOMMU groups, KSMBD and any out-of-tree drivers will only match the kernel they were built for — a mismatch produces obscure failures. Reboot at the earliest sensible moment."
|
||||
"body": "Installing a new <code>proxmox-kernel-*</code> package does not replace the running kernel until you reboot. The new kernel and its matching modules become active on the next boot. Plan the reboot for a suitable maintenance window, and review any DKMS build warnings beforehand."
|
||||
},
|
||||
"noSub": {
|
||||
"heading": "How the safe worker treats the Enterprise repository",
|
||||
@@ -117,7 +117,7 @@
|
||||
"<strong>Major-version upgrade.</strong> 8 → 9 is a separate operation — see <link>Upgrade PVE 8 to PVE 9</link>.",
|
||||
"<strong>Backup.</strong> No snapshots, no rollback. Apt operations are not transactional. Combine with your normal backup discipline (PBS, vzdump, ZFS snapshots).",
|
||||
"<strong>Container / VM updates.</strong> Only the host is upgraded; guests are left alone.",
|
||||
"<strong>Firmware updates.</strong> CPU microcode, NIC firmware, BIOS — out of scope."
|
||||
"<strong>Dedicated firmware flashing.</strong> This is not a BIOS or device-firmware flashing tool. Installed firmware or CPU-microcode packages can still receive updates through apt."
|
||||
]
|
||||
},
|
||||
"troubleshooting": {
|
||||
@@ -129,15 +129,15 @@
|
||||
},
|
||||
{
|
||||
"title": "dist-upgrade hangs at \"Configuring grub-pc\"",
|
||||
"body": "A dpkg prompt is asking which device(s) to install GRUB to. The wrapper passes <code>--force-confold</code> for config files but boot-loader install is a separate prompt. Use <kbd>Tab</kbd> + <kbd>Space</kbd> to select all your boot disks, then OK. Best avoided by selecting the boot disks once with <code>dpkg-reconfigure grub-pc</code> beforehand."
|
||||
"body": "If an interactive GRUB prompt is visible, it asks which devices should receive the boot loader. The <code>--force-confold</code> option applies to configuration-file decisions, not to this device selection. Use <kbd>Tab</kbd> + <kbd>Space</kbd> to select the appropriate boot disks, then OK. You can configure this selection beforehand with <code>dpkg-reconfigure grub-pc</code>."
|
||||
},
|
||||
{
|
||||
"title": "Kernel upgraded but the new modules are missing for an out-of-tree driver",
|
||||
"body": "The drivers ProxMenux installed via DKMS (currently <code>nvidia_driver</code> and <code>coral_driver</code>) are rebuilt automatically at the end of the upgrade against the incoming kernel version, using <code>dkms autoinstall -k <newkver></code> and, when needed, a fallback to each installer with <code>--auto-reinstall</code>. Confirm with <code>dkms status</code>. Third-party out-of-tree modules that aren't in ProxMenux's <code>components_status.json</code> registry (custom NIC drivers, hand-installed DKMS packages, …) still need a manual <code>dkms autoinstall</code> — the safe worker only touches what it originally installed."
|
||||
"body": "For managed drivers (<code>nvidia_driver</code> and <code>coral_driver</code>), the helper runs <code>dkms autoinstall -k <newkver></code> and can retry their installers with <code>--auto-reinstall</code>. Check the result with <code>dkms status</code>. The autoinstall command can also rebuild other registered DKMS modules; the installer fallback is limited to the managed entries in <code>components_status.json</code>. Inspect any third-party module that remains missing and rebuild it as needed with <code>dkms autoinstall</code>."
|
||||
},
|
||||
{
|
||||
"title": "The reboot prompt didn't appear but I'm sure the kernel changed",
|
||||
"body": "Two signals must agree (<code>/var/run/reboot-required</code> and <code>linux-image</code> in the upgrade log). If the marker file was cleared but the log is being parsed wrong, reboot manually with <code>shutdown -r now</code>. To confirm a kernel upgrade happened: <code>grep linux-image /var/log/apt/history.log</code>."
|
||||
"body": "The signals are alternatives: <code>/var/run/reboot-required</code> or a difference between the running and newest installed Proxmox kernel. The wrapper does not parse linux-image entries in the apt log. Check the running version with <code>uname -r</code> and the installed kernel packages with <code>dpkg-query</code>. If a reboot is needed, schedule it or run <code>shutdown -r now</code> when ready."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "System Utilities Installer | ProxMenux Documentation",
|
||||
"description": "Curated installer for 26 CLI utilities (htop, btop, iperf3, jq, tmux, ncdu, ...) on Proxmox VE. Custom selection or predefined groups (basic, dev, compression, multiplexers, analysis, network). Uses the canonical ensure_repositories + install_single_package flow.",
|
||||
"description": "CLI utility installer for Proxmox VE, with 25 packages in the canonical list (htop, btop, iperf3, tmux, ...). Custom selection, install-all and predefined groups (basic, development, compression, multiplexers, analysis, network). Groups can include additional packages. Uses ensure_repositories + install_single_package.",
|
||||
"ogTitle": "System Utilities Installer | ProxMenux Documentation",
|
||||
"ogDescription": "Install curated CLI tools on Proxmox VE with one click or custom selection."
|
||||
},
|
||||
"header": {
|
||||
"title": "System Utilities Installer",
|
||||
"description": "Curated picker for 26 CLI utilities defined in the canonical PROXMENUX_UTILS list. Offers custom selection, install-all, six predefined groups and a verify-installations check. Uses the shared ensure_repositories() + install_single_package() pair so repo configuration and per-package feedback stay consistent across the project.",
|
||||
"description": "Picker for 25 CLI utilities in the canonical PROXMENUX_UTILS list. Offers custom selection, install-all, six predefined groups and an installation check. Groups can include tools outside the canonical list. Uses shared ensure_repositories() + install_single_package() helpers for consistent repository handling and per-package feedback.",
|
||||
"section": "Utilities"
|
||||
},
|
||||
"info": {
|
||||
"title": "What this does",
|
||||
"body": "Installs CLI tools from a curated list of 26 packages. Every installation goes through the same canonical flow: <code>ensure_repositories</code> checks that the host has a usable Proxmox repository for the running PVE major version, then <code>install_single_package</code> runs the install and verifies the resulting command is in PATH."
|
||||
"body": "Installs CLI tools from a list of 25 packages. Every installation uses the same flow: <code>ensure_repositories</code> checks that the host has a usable Proxmox repository for the running PVE major version, then <code>install_single_package</code> installs the package and checks that its command is in PATH."
|
||||
},
|
||||
"opening": {
|
||||
"heading": "Opening the installer",
|
||||
@@ -26,7 +26,7 @@
|
||||
"rows": [
|
||||
{
|
||||
"option": "1. Custom selection",
|
||||
"behaviourRich": "Dialog checklist of all 26 packages. Use SPACE to toggle, ENTER to confirm; only the selected ones are installed."
|
||||
"behaviourRich": "Checklist of all 25 packages. Use SPACE to toggle and ENTER to confirm; only the selected packages are installed."
|
||||
},
|
||||
{
|
||||
"option": "2. Install ALL utilities",
|
||||
@@ -63,7 +63,7 @@
|
||||
]
|
||||
},
|
||||
"packages": {
|
||||
"heading": "The 26 packages",
|
||||
"heading": "The 25 packages",
|
||||
"intro": "Defined in the shared <code>scripts/global/utils-install-functions.sh</code> as <code>PROXMENUX_UTILS</code> (format: <code>package:verify_command:description</code>). Other ProxMenux scripts (e.g. the network monitoring launchers for iftop / iptraf-ng / iperf3) reuse entries from this list so package + verify command stay in sync.",
|
||||
"headerPackage": "Package",
|
||||
"headerVerify": "Verify command",
|
||||
@@ -193,11 +193,6 @@
|
||||
"package": "zip",
|
||||
"verify": "zip",
|
||||
"description": "Create ZIP files"
|
||||
},
|
||||
{
|
||||
"package": "libguestfs-tools",
|
||||
"verify": "virt-filesystems",
|
||||
"description": "VM disk utilities"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -211,14 +206,14 @@
|
||||
"verifyOutcomes": [
|
||||
"<strong>0 (success):</strong> command available, package counted as <em>Successful</em>.",
|
||||
"<strong>1 (failed):</strong> apt failed, counted as <em>Failed</em>.",
|
||||
"<strong>2 (warning):</strong> apt succeeded but command not yet in PATH (hash refresh pending) — counted as <em>With warnings</em>."
|
||||
"<strong>2 (warning):</strong> apt succeeded but the expected command was not found in PATH — counted as <em>With warnings</em>."
|
||||
],
|
||||
"summary": "At the end of a group / custom install, a summary dialog shows <em>Successful / With warnings / Failed</em> counts."
|
||||
},
|
||||
"verify": {
|
||||
"heading": "Verify installations",
|
||||
"intro": "Option 9 is read-only: it walks <code>PROXMENUX_UTILS</code> and runs <code>command -v</code> for each verify command. Output looks like this:",
|
||||
"code": "Total: 26\nAvailable: 18\nMissing: 8\n\n✓ axel - Download accelerator\n✓ aria2c - Multi-source downloader\n✓ btop - Modern resource monitor\n✗ cabextract - Extract CAB files\n✓ dos2unix - Convert DOS / Unix text files\n✗ genisoimage - Create ISO images\n✓ grc - Generic log colorizer\n...",
|
||||
"code": "Total: 25\nAvailable: 18\nMissing: 8\n\n✓ axel - Download accelerator\n✓ aria2c - Multi-source downloader\n✓ btop - Modern resource monitor\n✗ cabextract - Extract CAB files\n✓ dos2unix - Convert DOS / Unix text files\n✗ genisoimage - Create ISO images\n✓ grc - Generic log colorizer\n...",
|
||||
"outro": "Useful before running scripts that depend on these tools (e.g. <code>uup_dump_iso_creator.sh</code> needs <code>aria2c</code> + <code>cabextract</code> + <code>wimlib-imagex</code>). If anything is missing, run the matching group install or pick the missing packages via custom selection."
|
||||
},
|
||||
"troubleshoot": {
|
||||
@@ -226,7 +221,7 @@
|
||||
"reposTitle": "\"Failed to configure repositories. Installation aborted.\"",
|
||||
"reposBody": "The repository check did not pass: the switch to the no-subscription repository was declined, the subscription status could not be read, or a repository entry needs attention. The message printed above it states the cause. The repositories are listed in <em>Node → Updates → Repositories</em>, and <code>apt-get update</code> from a console shows the error apt reports.",
|
||||
"warningsTitle": "A package is reported \"With warnings\" but the command works after I close the menu",
|
||||
"warningsBody": "Expected. After <code>apt-get install</code>, the new binary is on disk but the current shell's PATH cache (<code>hash -t</code>) doesn't know yet. ProxMenux runs <code>hash -r</code> after each install, but in some shells the refresh only takes effect on the next prompt. Open a new shell and the command will work.",
|
||||
"warningsBody": "After <code>apt-get install</code>, the helper runs <code>hash -r</code>, waits briefly and checks the expected command with <code>command -v</code>. A warning means that check still failed; it does not identify the cause. Try a new shell, then check the package installation and PATH if the command is still missing.",
|
||||
"hangsTitle": "An apt install hangs",
|
||||
"hangsBody": "Most likely a debconf prompt is blocked behind the silenced output. The script wraps all apt calls with <code>DEBIAN_FRONTEND=noninteractive</code>, which usually suppresses prompts, but a few packages still require user input. Cancel with <kbd>Ctrl</kbd>+<kbd>C</kbd>, run <code>apt-get install -y <pkg></code> manually from a shell to see the prompt and decide."
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -8,12 +8,12 @@
|
||||
},
|
||||
"header": {
|
||||
"title": "UUP Dump ISO Creator",
|
||||
"description": "Build an up-to-date Windows installation ISO on your Proxmox host using UUP Dump. ProxMenux handles the dependencies, downloads the UUP files in parallel, runs the official converter and drops the final ISO into the Proxmox ISO storage — ready to attach to a new Windows VM.",
|
||||
"description": "Build an up-to-date Windows installation ISO on your Proxmox host using UUP Dump. ProxMenux handles dependencies, downloads UUP files in parallel, runs the UUP Dump converter and moves the ISO to your chosen output directory, which defaults to the detected Proxmox ISO storage.",
|
||||
"section": "Utilities"
|
||||
},
|
||||
"intro": {
|
||||
"title": "What this script does",
|
||||
"body": "You provide a UUP Dump URL (the one uupdump.net generates after you pick the build, language and edition) and the script does the rest: installs any missing dependencies, downloads the UUP Dump converter, downloads every UUP payload file with aria2, assembles a bootable Windows ISO and moves it into the Proxmox ISO storage so the VM creator can mount it on first boot."
|
||||
"body": "Provide a UUP Dump URL generated by uupdump.net after choosing a build, language and edition. The script installs missing dependencies, downloads the UUP Dump converter and UUP payloads, assembles a bootable Windows ISO and moves it to the output directory you selected. The detected Proxmox ISO storage is offered as the default destination."
|
||||
},
|
||||
"hero": {
|
||||
"imageAlt": "UUP Dump ISO Creator entry in ProxMenux",
|
||||
@@ -77,7 +77,7 @@
|
||||
"Calls <code>https://uupdump.net/get.php?…&aria2=2</code> to generate an aria2 download list.",
|
||||
"Downloads every UUP payload into <code>UUPs/</code> with aria2 (parallel, resumable).",
|
||||
"Runs <code>convert.sh wim UUPs 1</code> from the converter to produce the final ISO.",
|
||||
"Moves the ISO into the Proxmox ISO storage and cleans up temporary files."
|
||||
"Moves the ISO to the chosen output directory and cleans up temporary files."
|
||||
]
|
||||
},
|
||||
"aria2": {
|
||||
@@ -88,7 +88,7 @@
|
||||
"<code>-s16</code> — splits each file into 16 segments.",
|
||||
"<code>-j5</code> — 5 files downloaded in parallel.",
|
||||
"<code>-c</code> — resumes partial downloads.",
|
||||
"<code>-R</code> — retries on failure."
|
||||
"<code>-R</code> — applies the remote file’s timestamp to the downloaded file when available."
|
||||
],
|
||||
"runtime": "Typical runtime is around 10 minutes, dominated by your internet link speed and UUP Dump's mirror load."
|
||||
},
|
||||
@@ -150,12 +150,12 @@
|
||||
"title": "Wait for the build to finish",
|
||||
"img": "/iso-creator/end-uupdump-iso-creator.png",
|
||||
"caption": "Build finished — ISO is ready in Proxmox ISO storage",
|
||||
"bodyRich": "The console shows aria2 progress and then the converter output. When it finishes, the ISO lands in the detected Proxmox ISO storage and is ready to pick from <strong>Create VM → System Windows → Install with ISO from UUP Dump</strong>."
|
||||
"bodyRich": "The console shows aria2 progress and then converter output. The finished ISO is moved to your chosen output directory. If it is in configured Proxmox ISO storage, it can be selected from <strong>Create VM → System Windows → Install with personal ISO</strong>."
|
||||
}
|
||||
]
|
||||
},
|
||||
"tempFiles": {
|
||||
"title": "Temporary files",
|
||||
"body": "By default, temporary files live under <code>/root/uup-temp</code> (<code>uup-temp/</code> for downloads and <code>uup-converter/</code> for the converter script). The creator cleans both after a successful run. On failure it still cleans up and returns you to the menu so a retry starts from scratch."
|
||||
"body": "The default temporary folder is <code>/root/uup-temp</code>, with downloads in <code>UUPs/</code> and the converter in <code>converter/</code>. A custom temporary base path gets a separate session subdirectory. The successful-build and no-ISO-generated branches remove the temporary session. Earlier failures or cancellation can leave temporary files behind."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
},
|
||||
"intro": {
|
||||
"pbsCalloutTitle": "Consider Proxmox Backup Server first",
|
||||
"pbsCalloutBody": "If you have a second machine (a Pi, an old PC, a NAS), running <pbsLink>Proxmox Backup Server</pbsLink> on it gives you incremental, deduplicated, encrypted backups — a much better fit for VM backup than rsync-style cloud sync. The cloud-mount approach in this guide is for users who specifically want backups to land in their personal cloud (Google Drive / Mega / OneDrive / Dropbox).",
|
||||
"pbsCalloutBody": "On a second machine that meets its x86-64 requirements, <pbsLink>Proxmox Backup Server</pbsLink> offers incremental, deduplicated backups and optional client-side encryption. It is designed for VM backups. This guide instead covers mounting personal cloud storage such as Google Drive, Mega, OneDrive or Dropbox as a backup destination.",
|
||||
"stepsTitle": "What you'll do",
|
||||
"steps": [
|
||||
"Create a directory on the Proxmox host and register it as a vzdump-capable datastore.",
|
||||
@@ -21,7 +21,7 @@
|
||||
"Make the mount survive reboots (systemd unit — more robust than crontab)."
|
||||
],
|
||||
"vzdumpCalloutTitle": "Heads up about Proxmox vzdump backups",
|
||||
"vzdumpCalloutBody": "They're <strong>not incremental</strong>. Every backup contains the full VM disk image (compressed). On a quota-limited cloud, this fills up fast. Plan a retention policy from day one (see end of guide)."
|
||||
"vzdumpCalloutBody": "Proxmox vzdump archives are <strong>full backups, not incremental</strong>. Their actual size depends on the data included and compression, not just the virtual disk capacity. If one archive occupies 30 GB, five retained archives need roughly 150 GB. Set a retention policy so the cloud does not fill up."
|
||||
},
|
||||
"createDir": {
|
||||
"heading": "1. Create the host directory and register it as a datastore",
|
||||
@@ -48,10 +48,10 @@
|
||||
"newerCalloutBody": "If you need a newer rclone than what Debian ships, use the official installer:",
|
||||
"newerCode": "curl https://rclone.org/install.sh | bash",
|
||||
"tunnelHeading": "2.1 Browser-based authentication via SSH tunnel",
|
||||
"tunnelBody": "rclone's auth flow opens a local web browser. Since the Proxmox host doesn't have a desktop, <remoteSetupLink>rclone's remote-setup procedure</remoteSetupLink> routes the auth callback through an SSH tunnel back to your laptop's browser.",
|
||||
"tunnelBody": "For providers with browser-based login, the Proxmox host usually has no browser. Follow <remoteSetupLink>rclone’s remote-setup procedure</remoteSetupLink>: use your laptop’s browser and forward its localhost callback connection through SSH to rclone on the host.",
|
||||
"tunnelFrom": "From your <strong>laptop</strong> (replace <code>ip_proxmox</code> with the Proxmox IP):",
|
||||
"tunnelCode": "ssh -L localhost:53682:localhost:53682 root@ip_proxmox",
|
||||
"tunnelAfter": "This SSH session forwards port 53682 from the Proxmox host to your laptop's localhost. Keep it open during the rclone config below.",
|
||||
"tunnelAfter": "This SSH session opens localhost port 53682 on your laptop and forwards connections to the same port on the Proxmox host. Keep it open during the rclone configuration below.",
|
||||
"runHeading": "2.2 Run rclone config",
|
||||
"runBody": "In the SSH session you just opened, run:",
|
||||
"runCode": "rclone config",
|
||||
@@ -64,7 +64,7 @@
|
||||
"heading": "3. Mount the cloud folder",
|
||||
"body": "Create a folder in your personal cloud to hold the backups. Call it something like <code>PBC</code> (Proxmox Backup Cloud).",
|
||||
"mountIntro": "Mount it onto the host directory:",
|
||||
"mountCode": "rclone mount gdrive:/PBC /mnt/gdrive --allow-other --allow-non-empty",
|
||||
"mountCode": "rclone mount gdrive:/PBC /mnt/gdrive --allow-other --allow-non-empty --vfs-cache-mode writes",
|
||||
"mountItems": [
|
||||
"<code>gdrive:/PBC</code> — the folder in your cloud.",
|
||||
"<code>/mnt/gdrive</code> — the host directory you registered as a datastore."
|
||||
@@ -82,20 +82,20 @@
|
||||
"enableCode": "systemctl daemon-reload\nsystemctl enable --now rclone-gdrive.service",
|
||||
"verifyIntro": "Verify:",
|
||||
"verifyCode": "systemctl status rclone-gdrive.service\nmount | grep /mnt/gdrive",
|
||||
"verifyAfter": "If the service ever fails (provider rate-limits, expired auth token, network blip), it'll auto-restart after 10 seconds. Logs are at <code>/var/log/rclone-gdrive.log</code> and via <code>journalctl -u rclone-gdrive.service -f</code>.",
|
||||
"verifyAfter": "The unit requests a restart after 10 seconds if the rclone process exits with a failure. This does not repair expired credentials or guarantee recovery from every network or provider error. Check <code>/var/log/rclone-gdrive.log</code> and <code>journalctl -u rclone-gdrive.service -f</code>.",
|
||||
"vfsCalloutTitle": "Why --vfs-cache-mode writes?",
|
||||
"vfsCalloutBody": "vzdump streams the backup archive to disk; without VFS write caching, every <code>fwrite</code> blocks on a HTTP round-trip to the cloud — backups get slow and providers may rate-limit. The cache buffers writes locally and flushes them in the background."
|
||||
"vfsCalloutBody": "With write caching, writes such as <code>fwrite</code> go to a local disk cache. rclone uploads a file after it is closed and the write-back delay has passed. Reserve enough local space for active backups, and verify the upload has completed before counting the cloud copy as available."
|
||||
},
|
||||
"configureBackup": {
|
||||
"heading": "5. Configure the backup to land in the cloud",
|
||||
"body": "In the Proxmox UI, when scheduling a backup or running an ad-hoc one, pick the storage you registered as the <strong>target</strong>:",
|
||||
"image5Alt": "Selecting backup destination in Proxmox",
|
||||
"after": "After the backup completes, the file appears in your cloud:",
|
||||
"after": "After vzdump finishes, wait for rclone’s background upload to complete and verify the archive in the cloud provider’s interface:",
|
||||
"image6Alt": "Backup file in cloud storage"
|
||||
},
|
||||
"retention": {
|
||||
"heading": "6. Retention — keep cloud quota under control",
|
||||
"body": "Proxmox vzdump backups are <strong>full snapshots, not incremental</strong>. A 30 GB VM = 30 GB per backup. Without retention, the cloud fills up.",
|
||||
"body": "Proxmox vzdump archives are <strong>full backups, not incremental</strong>. Their actual size depends on the data included and compression, not just the virtual disk capacity. If one archive occupies 30 GB, five retained archives need roughly 150 GB. Set a retention policy so the cloud does not fill up.",
|
||||
"uiPath": "In the Proxmox UI: <strong>Datacenter → Backup → [your job] → Retention</strong>:",
|
||||
"image7Alt": "Backup retention settings in Proxmox",
|
||||
"starterIntro": "Reasonable starter values for a home / lab setup:",
|
||||
@@ -109,10 +109,10 @@
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"items": [
|
||||
"<strong><code>Mount point /mnt/gdrive is itself on a fuse.rclone filesystem</code>:</strong> the previous mount didn't unmount cleanly. Force-unmount: <code>fusermount -uz /mnt/gdrive</code>, then restart the systemd unit.",
|
||||
"<strong>Backup is extremely slow:</strong> confirm <code>--vfs-cache-mode writes</code> is on the <code>ExecStart</code> line. Without it, every write blocks on the cloud. Also check your upstream bandwidth — vzdump is bound by it.",
|
||||
"<strong>Backup fails with ''No space left on device'':</strong> the cache directory (<code>~/.cache/rclone/</code>) filled up before the upload caught up. Move it to a larger filesystem with <code>--cache-dir /var/cache/rclone</code> in the systemd unit.",
|
||||
"<strong>rclone auth token expired (typical on Google Drive after a long idle period):</strong> SSH back in with the tunnel (<code>ssh -L localhost:53682:localhost:53682 root@ip_proxmox</code>) and run <code>rclone config reconnect gdrive:</code> to refresh.",
|
||||
"<strong><code>Mount point /mnt/gdrive is itself on a fuse.rclone filesystem</code>:</strong> the directory is already mounted, possibly by another rclone instance. Check that no backup is active before removing the old mount with <code>fusermount -uz /mnt/gdrive</code>, then restart the systemd unit.",
|
||||
"<strong>Backup is extremely slow:</strong> confirm <code>--vfs-cache-mode writes</code> is on the <code>ExecStart</code> line. Check local cache performance, upload bandwidth and provider limits. The background upload can continue after vzdump finishes.",
|
||||
"<strong>Backup fails with No space left on device:</strong> check local cache space and the provider’s quota. The cache commonly uses <code>~/.cache/rclone/</code>. If it is full, select a cache path such as <code>--cache-dir /var/cache/rclone</code> on a filesystem with enough space; a different path on the same full filesystem will not help.",
|
||||
"<strong>rclone authentication token expired:</strong> reconnect over SSH with the tunnel (<code>ssh -L localhost:53682:localhost:53682 root@ip_proxmox</code>) and run <code>rclone config reconnect gdrive:</code> to renew authorization.",
|
||||
"<strong>Backups land but are corrupted on restore:</strong> stop using cloud storage as the <strong>only</strong> backup destination. Combine with local PBS / vzdump on a different disk for resilience."
|
||||
]
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
"steps": [
|
||||
"Create a privileged LXC running Kodi (script-driven).",
|
||||
"Wire your USB keyboard, mouse or controller into the CT.",
|
||||
"(Optional) Update Kodi to the latest version from the team-xbmc PPA."
|
||||
"(Optional) Update Kodi from the container’s configured repositories."
|
||||
]
|
||||
},
|
||||
"createCt": {
|
||||
"heading": "1. Create the Kodi LXC",
|
||||
"body": "The CT needs to be <strong>privileged</strong> so it can access USB input devices (keyboards, remotes, controllers). The script handles privilege flags + GPU wiring + Kodi install + autostart on <code>tty7</code>:",
|
||||
"body": "For this recipe, select <strong>Privileged</strong> in the script’s advanced settings. The script defaults to unprivileged containers, which require appropriate device permissions and ID mapping. It configures GPU access, Kodi and autostart on <code>tty7</code>:",
|
||||
"code": "bash -c \"$(wget -qLO - https://raw.githubusercontent.com/mrrudy/proxmoxHelper/main/ct/kodi-v1.sh)\"",
|
||||
"after": "Be patient — it takes a while to install. When it finishes and Kodi starts on <code>tty7</code>, you can plug your monitor or TV directly into the host's HDMI / DisplayPort output and you should see the Kodi UI."
|
||||
},
|
||||
@@ -32,22 +32,22 @@
|
||||
"body": "Input devices live under <code>/dev/input/</code> on the host. Identify the major number:",
|
||||
"listCode": "ls -l /dev/input",
|
||||
"imageAlt": "Input devices list",
|
||||
"afterList": "Take the first column number (in the example: <code>13</code>). Stop the Kodi LXC, then edit its config (replace <code>'<'CTID'>'</code> with the container ID — for example, <code>102</code>):",
|
||||
"editCode": "nano /etc/pve/lxc/'<'CTID'>'.conf",
|
||||
"afterList": "For character devices, use the major number before the comma (in the example: <code>13</code>). On the host, edit the Kodi LXC's configuration, replacing <code>'<'CTID'>'</code> with its ID, for example <code>102</code>:",
|
||||
"editCode": "nano /etc/pve/lxc/CTID.conf",
|
||||
"addLines": "Add (adjust <code>13</code> to what you saw on <strong>your</strong> host):",
|
||||
"configCode": "lxc.cgroup2.devices.allow = c 13:* rwm\nlxc.mount.entry: /dev/input dev/input none bind,optional,create=dir",
|
||||
"configCode": "lxc.cgroup2.devices.allow: c 13:* rwm\nlxc.mount.entry: /dev/input dev/input none bind,optional,create=dir",
|
||||
"imageConfigAlt": "LXC configuration",
|
||||
"save": "Save (<code>Ctrl+X</code>) and restart <strong>only the container</strong> — no need to reboot the whole Proxmox host:",
|
||||
"restartCode": "pct restart '<'CTID'>'",
|
||||
"restartCode": "pct reboot CTID",
|
||||
"plug": "Plug in the keyboard / mouse / controller and Kodi should respond to it."
|
||||
},
|
||||
"updateKodi": {
|
||||
"heading": "3. (Optional) Update Kodi to the latest release",
|
||||
"heading": "3. (Optional) Update Kodi from the configured repositories",
|
||||
"calloutTitle": "Important",
|
||||
"calloutBody": "The team-xbmc PPA is <strong>Ubuntu-only</strong>. If the Kodi LXC is based on a Debian template, <code>add-apt-repository</code> won't be available and the PPA will not work. The mrrudy script defaults to an Ubuntu template, so this should normally apply. To verify: <code>cat /etc/os-release</code> inside the container — look for <code>NAME=\"Ubuntu\"</code>.",
|
||||
"calloutBody": "The team-xbmc PPA is <strong>Ubuntu-only</strong>, and Kodi currently states that it is unmaintained. A missing <code>add-apt-repository</code> command does not identify the distribution. Check <code>cat /etc/os-release</code> and look for <code>NAME=\"Ubuntu\"</code>; do not add Ubuntu PPAs to Debian. The commands below update packages from the container’s configured repositories.",
|
||||
"body": "Inside the container (<code>pct enter '<'CTID'>'</code>):",
|
||||
"code": "sudo add-apt-repository ppa:team-xbmc/ppa\nsudo apt update\nsudo apt install kodi kodi-bin",
|
||||
"after": "Restart the container when it finishes; on boot you'll have the latest Kodi."
|
||||
"code": "apt update\napt install --only-upgrade kodi kodi-bin",
|
||||
"after": "Restart the container after the update. Kodi will use the version available from its configured repositories, which may differ from the latest upstream release."
|
||||
},
|
||||
"screenshots": {
|
||||
"heading": "Screenshots",
|
||||
@@ -58,9 +58,9 @@
|
||||
"heading": "Troubleshooting",
|
||||
"items": [
|
||||
"<strong>Kodi LXC starts but nothing on the TV:</strong> the CT may not have inherited the iGPU. Confirm with <code>ls /dev/dri</code> inside the container (you should see <code>card0</code>, <code>renderD128</code>). If empty, the GPU passthrough wasn't applied — re-run the script or use the ProxMenux <strong>Add GPU to LXC</strong> menu.",
|
||||
"<strong>Keyboard / mouse not detected after restart:</strong> the major number for <code>/dev/input</code> changed (rare, but happens after kernel updates). Re-run <code>ls -l /dev/input</code> on the host and update the <code>lxc.cgroup2.devices.allow</code> line.",
|
||||
"<strong>Keyboard / mouse not detected after restart:</strong> check that <code>/dev/input</code> is mounted and device permissions let Kodi read it. Run <code>ls -l /dev/input</code> on the host and in the container, and check the <code>lxc.cgroup2.devices.allow</code> rule.",
|
||||
"<strong>Hardware-accelerated playback uses CPU instead of GPU:</strong> install or update VA-API drivers inside the container (<code>intel-media-va-driver</code> for newer Intel iGPUs, <code>i965-va-driver</code> for older ones, <code>mesa-va-drivers</code> on AMD).",
|
||||
"<strong><code>add-apt-repository: command not found</code>:</strong> the container is Debian, not Ubuntu. Either use the Debian Kodi packages (older but stable) or recreate the CT from an Ubuntu template."
|
||||
"<strong><code>add-apt-repository: command not found</code>:</strong> the command is not installed; this does not prove the container is Debian. Check its distribution and available packages. Use Debian’s Kodi packages on Debian, without adding the Ubuntu PPA."
|
||||
]
|
||||
},
|
||||
"further": {
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
"Holding documents that get auto-scanned by Paperless.",
|
||||
"Generic NAS-style storage for the home network."
|
||||
],
|
||||
"privilegedCalloutTitle": "Privileged container required",
|
||||
"privilegedCalloutBody": "Direct device passthrough (<code>mp0</code> with a host path) needs a privileged LXC. Unprivileged CTs can't bind-mount block devices directly — for those you need bind mounts of host directories instead (see ProxMenux <strong>Storage & Share Manager → LXC Mount Points</strong>)."
|
||||
"privilegedCalloutTitle": "Privileged container used in this recipe",
|
||||
"privilegedCalloutBody": "This recipe uses a privileged LXC with a block device as <code>mp0</code>. For an unprivileged container, an alternative is to mount the filesystem on the host and bind-mount its directory, with appropriate ID mapping and permissions. See <strong>Storage & Share Manager → LXC Mount Points</strong> in ProxMenux."
|
||||
},
|
||||
"attach": {
|
||||
"heading": "1. Attach the USB disk to the LXC",
|
||||
@@ -48,10 +48,10 @@
|
||||
"lsblkBody": "You can also use <code>lsblk -o NAME,SIZE,MODEL,SERIAL</code> to list every block device with model and serial.",
|
||||
"stableCalloutTitle": "Important — use a stable identifier",
|
||||
"stableCalloutBody": "<code>/dev/sdb1</code> can change between boots if you have multiple USB disks. Find the persistent identifier:",
|
||||
"stableCalloutCode": "ls -l /dev/disk/by-id/ | grep -v part",
|
||||
"stableCalloutAfter": "Use the <code>/dev/disk/by-id/usb-...</code> path in the LXC config below instead of <code>/dev/sdb1</code>. It survives reboots and re-plugging.",
|
||||
"stableCalloutCode": "ls -l /dev/disk/by-id/",
|
||||
"stableCalloutAfter": "Use the <code>/dev/disk/by-id/usb-...</code> entry for the intended partition in the LXC config, instead of <code>/dev/sdb1</code>. Choose the partition entry, not the whole-disk entry; it identifies the same partition when device enumeration changes.",
|
||||
"formatHeading": "1.2 Format the disk",
|
||||
"formatBody": "ext4 is a sensible default for Linux-backed shares (case-sensitive, supports POSIX ACLs, no file-size limits). Run from the <strong>Proxmox host</strong>, not the container:",
|
||||
"formatBody": "ext4 is a practical choice for Linux-backed shares: it is case-sensitive and supports POSIX ACLs and large files. Formatting destroys the existing filesystem’s contents. Run on the <strong>Proxmox host</strong>, after confirming the partition, not inside the container:",
|
||||
"formatCode": "mkfs.ext4 /dev/sdb1",
|
||||
"formatAfter": "Replace <code>/dev/sdb1</code> with the actual partition device — or with the persistent <code>/dev/disk/by-id/usb-...-part1</code> path.",
|
||||
"mkdirHeading": "1.3 Create the mount point inside the LXC",
|
||||
@@ -59,18 +59,18 @@
|
||||
"mkdirCode": "mkdir /mnt/lxc_USB",
|
||||
"wireHeading": "1.4 Wire the device into the LXC",
|
||||
"wireBody": "On the <strong>Proxmox host</strong> (not inside the CT), edit the container's config. Replace <code>'<'CTID'>'</code> with the container ID:",
|
||||
"wireEditCode": "nano /etc/pve/lxc/'<'CTID'>'.conf",
|
||||
"wireEditCode": "nano /etc/pve/lxc/CTID.conf",
|
||||
"wireAddLine": "Add this line:",
|
||||
"wireConfigCode": "mp0: /dev/disk/by-id/usb-VENDOR_MODEL_SERIAL-part1,mp=/mnt/lxc_USB,backup=0",
|
||||
"wireShortForm": "(Or, if you accept the risk of the device path changing, the shorter form: <code>mp0: /dev/sdb1,mp=/mnt/lxc_USB,backup=0</code>.)",
|
||||
"wireBackupNote": "The <code>backup=0</code> flag excludes this mount point from <code>vzdump</code> backups — usually the right call for large external drives that are the host's target storage rather than its data.",
|
||||
"wireBackupNote": "This example sets <code>backup=0</code>. Device and bind mount contents are not included in container <code>vzdump</code> backups. Arrange a separate backup for the external disk’s data.",
|
||||
"restartHeading": "1.5 Restart the LXC and set permissions",
|
||||
"restartBody": "Restart the CT to apply the mount point:",
|
||||
"restartCode": "pct restart '<'CTID'>'",
|
||||
"permsBody": "Inside the LXC, give the directory permissions appropriate for the user that will own the share:",
|
||||
"permsCode": "# Inside the container\nmkdir -p /mnt/lxc_USB\nchown -R proxmenux:proxmenux /mnt/lxc_USB\nchmod 770 /mnt/lxc_USB",
|
||||
"restartCode": "pct reboot CTID",
|
||||
"permsBody": "Inside the LXC, create the share account before assigning ownership, then set the directory permissions:",
|
||||
"permsCode": "adduser --system --group --no-create-home --shell /usr/sbin/nologin proxmenux\nmkdir -p /mnt/lxc_USB\nchown -R proxmenux:proxmenux /mnt/lxc_USB\nchmod 770 /mnt/lxc_USB",
|
||||
"permsNoteTitle": "Note",
|
||||
"permsNote": "Replace <code>proxmenux</code> with the username you'll create in step 2.2 below. <code>770</code> gives full access to the user and group, no access to others — safer than the wide-open <code>chmod -R 777</code> while still letting the share work."
|
||||
"permsNote": "Replace <code>proxmenux</code> with your chosen account name. The mode <code>770</code> allows the owner and group to access the directory, with no access for others; it is more restrictive than <code>chmod -R 777</code>. The account is created here and registered with Samba in step 2.2."
|
||||
},
|
||||
"samba": {
|
||||
"heading": "2. Install Samba",
|
||||
@@ -78,9 +78,9 @@
|
||||
"installCode": "apt-get update\napt-get install -y samba",
|
||||
"confirmBody": "Confirm the service is running:",
|
||||
"confirmCode": "systemctl status smbd.service",
|
||||
"userHeading": "2.2 Create the share user",
|
||||
"userBody": "Pick a username (here we use <code>proxmenux</code>; substitute your own). Create it as a system user with no shell:",
|
||||
"userCode": "adduser proxmenux",
|
||||
"userHeading": "2.2 Verify the share user",
|
||||
"userBody": "The account <code>proxmenux</code> was created in step 1.5 as a system user without a login shell. Check it before setting its Samba password; substitute your chosen name throughout:",
|
||||
"userCode": "id proxmenux",
|
||||
"passwordBody": "Set the Samba password (separate from the system password — Samba maintains its own credential store):",
|
||||
"passwordCode": "smbpasswd -a proxmenux",
|
||||
"aclHeading": "2.3 Set ownership / ACLs",
|
||||
@@ -109,11 +109,11 @@
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"items": [
|
||||
"<strong><code>pct restart</code> fails with \"device not found\":</strong> the device path in <code>mp0</code> doesn't exist on the host. Check with <code>ls -l /dev/disk/by-id/</code> and update the path.",
|
||||
"<strong>CT starts but <code>/mnt/lxc_USB</code> is empty:</strong> the disk isn't mounted inside the CT. Check from the host: <code>pct exec '<'CTID'>' -- mount | grep lxc_USB</code>. If absent, the mount point in the config is wrong.",
|
||||
"<strong>Samba authenticates but writes fail with \"Permission denied\":</strong> Linux permissions on the directory don't allow the Samba user to write. Re-check <code>chown</code> / <code>setfacl</code> in section 1.5 / 2.3.",
|
||||
"<strong>Share doesn't appear in network browsers but <code>smb://'<'ip'>'/lxc_usb</code> works:</strong> browseability over the LAN depends on NetBIOS / WS-Discovery. Add <code>nmbd</code>: <code>apt-get install -y samba-common-bin</code> and ensure <code>nmbd</code> is enabled.",
|
||||
"<strong>Want to add a second user to the same share:</strong> create the user with <code>adduser</code>, register with <code>smbpasswd -a</code>, add to the share's <code>valid users =</code> list comma-separated."
|
||||
"<strong><code>pct reboot</code> fails with \"device not found\":</strong> the device path in <code>mp0</code> doesn't exist on the host. Check with <code>ls -l /dev/disk/by-id/</code> and update the path.",
|
||||
"<strong>CT starts but <code>/mnt/lxc_USB</code> is empty:</strong> the disk may not be mounted, or its filesystem may be empty. Check from the host with <code>pct exec '<'CTID'>' -- mount | grep lxc_USB</code>. If the mount is absent, inspect its configuration, device path and startup errors.",
|
||||
"<strong>Samba authenticates but writes fail with \"Permission denied\":</strong> check the directory’s Linux permissions and the share’s write settings. Review <code>chown</code> and <code>setfacl</code> in sections 1.5 and 2.3.",
|
||||
"<strong>Share discovery fails but <code>smb://'<'ip'>'/lxc_usb</code> works:</strong> legacy NetBIOS discovery uses <code>nmbd</code>. Modern Windows discovery uses WS-Discovery instead; on Debian 12 install <code>apt-get install -y wsdd</code>; on Debian 13, where <code>wsdd</code> is not in the stable archive, use <code>apt-get install -y wsdd2</code>. Check the service and firewall. Enabling <code>nmbd</code> alone does not provide WS-Discovery.",
|
||||
"<strong>To add a second user to the share:</strong> create the account with <code>adduser</code>, register it with <code>smbpasswd -a</code> and add it to the comma-separated <code>valid users =</code> list. Also grant the required filesystem permissions or ACLs."
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
"blacklistBody": "Check whether the open-source <code>nouveau</code> driver is already blacklisted:",
|
||||
"blacklistCheckCode": "cat /etc/modprobe.d/blacklist.conf",
|
||||
"blacklistAdd": "If <code>blacklist nouveau</code> does not appear, add it and reboot:",
|
||||
"blacklistAddCode": "echo \"blacklist nouveau\" '>>' /etc/modprobe.d/blacklist.conf\nreboot",
|
||||
"blacklistAddCode": "echo \"blacklist nouveau\" >> /etc/modprobe.d/blacklist.conf\nupdate-initramfs -u -k all\nreboot",
|
||||
"blacklistImageAlt": "Blacklist check",
|
||||
"reposHeading": "1.2 Verify repositories (PVE 9 / Trixie)",
|
||||
"reposBody": "If you ran the ProxMenux Post-Install script (or any other Proxmox post-install tooling), the repositories are already in place — skip this step.",
|
||||
"reposBody": "Post-install tools may already have configured the repositories. Inspect the existing sources first and skip changes that are already in place; do not create duplicate entries.",
|
||||
"reposOtherwise": "Otherwise, on a vanilla PVE 9 install with no enterprise subscription:",
|
||||
"reposEditCode": "nano /etc/apt/sources.list.d/proxmox.sources",
|
||||
"reposPveBody": "Make sure it contains the no-subscription source for Trixie:",
|
||||
@@ -47,7 +47,7 @@
|
||||
"installDriver": {
|
||||
"heading": "2. Install the NVIDIA driver on the host",
|
||||
"pickHeading": "2.1 Pick a driver version",
|
||||
"pickBody": "Check the latest stable driver:",
|
||||
"pickBody": "Choose a driver branch that supports your GPU and running kernel. The newest branch may not support older GPU models; check NVIDIA’s supported-products list for the chosen release:",
|
||||
"pickUrlCode": "https://download.nvidia.com/XFree86/Linux-x86_64/latest.txt",
|
||||
"nvencCallout": "If you plan to apply the NVENC patch (step 4), verify the patch supports your chosen driver version first: <patchLink>github.com/keylase/nvidia-patch</patchLink>",
|
||||
"nvencCalloutTitle": "Heads up",
|
||||
@@ -56,27 +56,27 @@
|
||||
"pickImageAlt": "NVIDIA driver download",
|
||||
"pickVersionNote": "Throughout the rest of this guide, replace <code>'<'VERSION'>'</code> with the actual version (for example <code>580.95.05</code>).",
|
||||
"downloadHeading": "2.2 Download and run the installer",
|
||||
"downloadCode": "mkdir -p /opt/nvidia\ncd /opt/nvidia\nwget https://download.nvidia.com/XFree86/Linux-x86_64/'<'VERSION'>'/NVIDIA-Linux-x86_64-'<'VERSION'>'.run\nchmod +x NVIDIA-Linux-x86_64-'<'VERSION'>'.run",
|
||||
"firstPassBody": "First pass — this disables <code>nouveau</code> and prepares the system:",
|
||||
"firstPassCode": "./NVIDIA-Linux-x86_64-'<'VERSION'>'.run --no-questions --ui=none --disable-nouveau\nreboot",
|
||||
"downloadCode": "mkdir -p /opt/nvidia\ncd /opt/nvidia\nwget https://download.nvidia.com/XFree86/Linux-x86_64/VERSION/NVIDIA-Linux-x86_64-VERSION.run\nchmod +x NVIDIA-Linux-x86_64-VERSION.run",
|
||||
"firstPassBody": "Run the installer. The option below can disable <code>nouveau</code> if necessary; installation may need a reboot before it can finish:",
|
||||
"firstPassCode": "./NVIDIA-Linux-x86_64-VERSION.run --no-questions --ui=none --disable-nouveau\nreboot",
|
||||
"secondPassBody": "After the host comes back, run the installer again to compile and install the kernel module:",
|
||||
"secondPassCode": "/opt/nvidia/NVIDIA-Linux-x86_64-'<'VERSION'>'.run --no-questions --ui=none",
|
||||
"secondPassCode": "/opt/nvidia/NVIDIA-Linux-x86_64-VERSION.run --no-questions --ui=none",
|
||||
"modulesHeading": "2.3 Load NVIDIA modules at boot",
|
||||
"modulesBody": "Edit the modules-load configuration:",
|
||||
"modulesEditCode": "nano /etc/modules-load.d/modules.conf",
|
||||
"modulesAddBody": "Add the VFIO and NVIDIA modules:",
|
||||
"modulesAddCode": "vfio\nvfio_iommu_type1\nvfio_pci\nvfio_virqfd\nnvidia\nnvidia_uvm",
|
||||
"modulesAddBody": "Add the NVIDIA modules needed for host/LXC use. VFIO modules are for VM passthrough and are not required for this LXC setup:",
|
||||
"modulesAddCode": "nvidia\nnvidia_uvm",
|
||||
"modulesSaveBody": "Save (<code>Ctrl+X</code>) and rebuild initramfs:",
|
||||
"modulesSaveCode": "update-initramfs -u -k all",
|
||||
"udevHeading": "2.4 Create udev rules",
|
||||
"udevBody": "So that <code>/dev/nvidia*</code> device nodes are created when the modules load:",
|
||||
"udevEditCode": "nano /etc/udev/rules.d/70-nvidia.rules",
|
||||
"udevRulesCode": "# /etc/udev/rules.d/70-nvidia.rules\n# Create /dev/nvidia0, /dev/nvidia1 ... and /dev/nvidiactl when nvidia module is loaded\nKERNEL==\"nvidia\", RUN+=\"/bin/bash -c ''/usr/bin/nvidia-smi -L''\"\n\n# Create the CUDA node when nvidia_uvm CUDA module is loaded\nKERNEL==\"nvidia_uvm\", RUN+=\"/bin/bash -c ''/usr/bin/nvidia-modprobe -c0 -u''\"",
|
||||
"udevRulesCode": "# /etc/udev/rules.d/70-nvidia.rules\nKERNEL==\"nvidia\", RUN+=\"/bin/bash -c '/usr/bin/nvidia-smi -L'\"\nKERNEL==\"nvidia_uvm\", RUN+=\"/bin/bash -c '/usr/bin/nvidia-modprobe -c0 -u'\"",
|
||||
"udevSaveBody": "Save (<code>Ctrl+X</code>)."
|
||||
},
|
||||
"persistence": {
|
||||
"heading": "3. NVIDIA driver persistence service",
|
||||
"body": "The persistence daemon keeps the GPU initialised between uses, which avoids the latency hit and occasional state loss that happens when the kernel module is loaded and unloaded repeatedly:",
|
||||
"body": "The persistence daemon keeps the GPU initialized when no other application is using it. This reduces repeated initialization latency and preserves GPU-initialization state between clients:",
|
||||
"installCode": "cd /opt/nvidia\ngit clone https://github.com/NVIDIA/nvidia-persistenced.git\ncd nvidia-persistenced/init\n./install.sh\nreboot",
|
||||
"verifyBody": "Verify the driver is loaded and the service is running after reboot:",
|
||||
"verifySmiCode": "nvidia-smi",
|
||||
@@ -86,7 +86,7 @@
|
||||
},
|
||||
"nvenc": {
|
||||
"heading": "4. (Optional) Lift the NVENC concurrent-session limit",
|
||||
"body": "Consumer NVIDIA GPUs ship with a hardcoded limit on the number of simultaneous NVENC encoding sessions (typically 3, 5 or 8 depending on generation). The keylase patch removes that restriction. Useful when running Plex / Jellyfin / Frigate transcoding workloads.",
|
||||
"body": "NVENC session limits depend on the GPU model and driver version; consult NVIDIA’s support matrix rather than assuming a fixed limit by GPU generation. The keylase patch removes the software limit for supported driver versions. It can help encoding workloads such as Plex or Jellyfin transcoding.",
|
||||
"code": "cd /opt/nvidia\ngit clone https://github.com/keylase/nvidia-patch.git\ncd nvidia-patch\n./patch.sh",
|
||||
"imageAlt": "NVIDIA patch application",
|
||||
"after": "The patch must be re-applied after every driver update. The keylase repo also includes <code>patch-fbc.sh</code> for the FBC (frame buffer capture) limit if you need it."
|
||||
@@ -103,24 +103,36 @@
|
||||
"major": "Typical major"
|
||||
},
|
||||
"tableRows": [
|
||||
{ "device": "<code>/dev/nvidia0</code>, <code>/dev/nvidiactl</code>", "major": "195" },
|
||||
{ "device": "<code>/dev/nvidia-uvm</code>, <code>/dev/nvidia-uvm-tools</code>", "major": "509 (varies)" },
|
||||
{ "device": "<code>/dev/dri/*</code>", "major": "226" },
|
||||
{ "device": "<code>/dev/nvidia-modeset</code>", "major": "195 (shares with nvidia)" }
|
||||
{
|
||||
"device": "<code>/dev/nvidia0</code>, <code>/dev/nvidiactl</code>",
|
||||
"major": "195"
|
||||
},
|
||||
{
|
||||
"device": "<code>/dev/nvidia-uvm</code>, <code>/dev/nvidia-uvm-tools</code>",
|
||||
"major": "509 (varies)"
|
||||
},
|
||||
{
|
||||
"device": "<code>/dev/dri/*</code>",
|
||||
"major": "226"
|
||||
},
|
||||
{
|
||||
"device": "<code>/dev/nvidia-modeset</code>",
|
||||
"major": "195 (shares with nvidia)"
|
||||
}
|
||||
],
|
||||
"editHeading": "5.2 Edit the LXC config",
|
||||
"editBody": "Stop the container first if it's running. Open its config file (replace <code>'<'CTID'>'</code> with the container ID):",
|
||||
"editCode": "nano /etc/pve/lxc/'<'CTID'>'.conf",
|
||||
"editCode": "nano /etc/pve/lxc/CTID.conf",
|
||||
"editConfigBody": "Comment out any pre-existing <code>lxc.cgroup2.devices.allow</code> or <code>/dev/dri</code> lines that conflict, then append the NVIDIA wiring (adjust the major numbers to match what <code>ls -l /dev/nv*</code> showed on <strong>your</strong> host):",
|
||||
"editConfigCode": "lxc.cgroup2.devices.allow: c 195:* rwm\nlxc.cgroup2.devices.allow: c 509:* rwm\nlxc.cgroup2.devices.allow: c 10:* rwm\nlxc.cgroup2.devices.allow: c 238:* rwm\nlxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file\nlxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file\nlxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file\nlxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file\nlxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file\nlxc.mount.entry: /dev/nvram dev/nvram none bind,optional,create=file",
|
||||
"editConfigCode": "lxc.cgroup2.devices.allow: c 195:* rwm\nlxc.cgroup2.devices.allow: c 509:* rwm\nlxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file\nlxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file\nlxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file\nlxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file\nlxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file",
|
||||
"editConfigImageAlt": "LXC configuration",
|
||||
"editSave": "Save (<code>Ctrl+X</code>) and start the container.",
|
||||
"installCtHeading": "5.3 Install the driver inside the container",
|
||||
"installCtCalloutTitle": "Important",
|
||||
"installCtCalloutBody": "This part runs <strong>inside</strong> the container, not on the host.",
|
||||
"installCtBody": "The kernel module is already loaded by the host — the container only needs the userland libraries that match the same driver version:",
|
||||
"installCtCode": "mkdir -p /opt/nvidia\ncd /opt/nvidia\nwget https://download.nvidia.com/XFree86/Linux-x86_64/'<'VERSION'>'/NVIDIA-Linux-x86_64-'<'VERSION'>'.run\nchmod +x NVIDIA-Linux-x86_64-'<'VERSION'>'.run\n./NVIDIA-Linux-x86_64-'<'VERSION'>'.run --no-kernel-module",
|
||||
"installCtAfter": "Accept the defaults at every prompt.",
|
||||
"installCtCode": "mkdir -p /opt/nvidia\ncd /opt/nvidia\nwget https://download.nvidia.com/XFree86/Linux-x86_64/VERSION/NVIDIA-Linux-x86_64-VERSION.run\nchmod +x NVIDIA-Linux-x86_64-VERSION.run\n./NVIDIA-Linux-x86_64-VERSION.run --no-kernel-module",
|
||||
"installCtAfter": "Review the prompts and keep this installation limited to user-space libraries. Do not build or install a kernel module inside the LXC.",
|
||||
"installCtImageAlt": "NVIDIA driver installation",
|
||||
"verifyCtHeading": "5.4 Verify inside the container",
|
||||
"verifyCtSmiCode": "nvidia-smi",
|
||||
@@ -129,25 +141,25 @@
|
||||
"verifyCtLsImageAlt": "NVIDIA devices in LXC",
|
||||
"verifyCtAfter": "You should see the GPU listed and the device nodes mounted into the container's filesystem.",
|
||||
"workloadHeading": "5.5 Confirm a real workload picks up the GPU",
|
||||
"workloadBody": "For Plex / Jellyfin, transcode a video and check the dashboard / logs — hardware-accelerated transcoding is now active.",
|
||||
"workloadBody": "Enable NVIDIA hardware acceleration in Plex or Jellyfin, start a video transcode and check its dashboard or logs for actual GPU use. Installing the driver alone does not enable acceleration in the application.",
|
||||
"workloadImage1Alt": "Plex using NVIDIA GPU",
|
||||
"workloadImage2Alt": "Plex using NVIDIA GPU - active session",
|
||||
"repeatNote": "To wire the GPU into another container, repeat <strong>section 5</strong> for each additional CTID. The driver install inside the container only needs to be done once per container."
|
||||
"repeatNote": "Repeat <strong>section 5</strong> for each additional container that needs GPU access. Keep the user-space driver libraries in every container aligned when the host driver is updated."
|
||||
},
|
||||
"docker": {
|
||||
"heading": "6. (Optional) NVIDIA Docker inside an LXC",
|
||||
"body": "If the container runs Docker and you want containers-inside-the-container to use the GPU, install <code>nvidia-docker2</code>. From inside the LXC:",
|
||||
"code": "wget https://raw.githubusercontent.com/MacRimi/manuales/main/NVIDIA/nvidia-docker.sh\nchmod +x nvidia-docker.sh\n./nvidia-docker.sh",
|
||||
"after": "The script handles the repository setup, package install and Docker daemon configuration in one go."
|
||||
"body": "If Docker already runs inside the LXC, install <code>nvidia-container-toolkit</code> there to expose the GPU to its Docker containers. GPU access from the LXC must work first. The following commands are for a rootful Docker installation:",
|
||||
"code": "apt-get update\napt-get install -y ca-certificates curl gnupg\ncurl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor --yes -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg\ncurl -fsSL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' > /etc/apt/sources.list.d/nvidia-container-toolkit.list\napt-get update\napt-get install -y nvidia-container-toolkit\nnvidia-ctk runtime configure --runtime=docker\nsystemctl restart docker",
|
||||
"after": "These commands configure NVIDIA’s repository, install the toolkit, configure the Docker runtime and restart Docker. LXC device permissions and cgroup restrictions still apply; verify GPU use with a test workload."
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Troubleshooting",
|
||||
"items": [
|
||||
"<strong><code>nvidia-smi</code> on the host shows the GPU, but inside the container it errors with \"No devices found\":</strong> the driver versions don't match. Re-download the same <code>'<'VERSION'>'</code> inside the container and run with <code>--no-kernel-module</code>.",
|
||||
"<strong>Driver compile fails on the host with \"No precompiled kernel interface was found\":</strong> kernel headers are missing or out of sync. Re-run <code>apt-get install pve-headers-$(uname -r)</code> and confirm <code>uname -r</code> matches the running kernel.",
|
||||
"<strong>NVENC sessions still capped after applying the patch:</strong> the patch was overwritten by a driver update. Re-run <code>./patch.sh</code> from <code>/opt/nvidia/nvidia-patch</code>.",
|
||||
"<strong>GPU stops responding after a few hours of idle:</strong> persistence daemon isn't running. Check with <code>systemctl status nvidia-persistenced</code> and start / enable it.",
|
||||
"<strong>Container starts but <code>ls /dev/nv*</code> shows nothing:</strong> the major numbers in the LXC config don't match the host's. Re-run <code>ls -l /dev/nv*</code> on the host and adjust the <code>lxc.cgroup2.devices.allow</code> lines accordingly."
|
||||
"<strong><code>nvidia-smi</code> works on the host but reports \"No devices found\" in the container:</strong> check device mounts, permissions and matching driver libraries. If versions differ, install the host’s <code>'<'VERSION'>'</code> in the container with <code>--no-kernel-module</code>.",
|
||||
"<strong>Driver compilation fails:</strong> inspect the build log. \"No precompiled kernel interface was found\" can simply mean the installer must compile locally. Install headers matching <code>uname -r</code> using <code>apt-get install pve-headers-$(uname -r)</code>, or the equivalent proxmox-headers package for that kernel.",
|
||||
"<strong>NVENC sessions remain limited:</strong> confirm the patch supports the active driver. A driver update can overwrite it. For a supported version, reapply <code>./patch.sh</code> from <code>/opt/nvidia/nvidia-patch</code> and review its output.",
|
||||
"<strong>GPU stops responding after idle:</strong> check <code>systemctl status nvidia-persistenced</code> and enable the service if intended. Also inspect kernel and driver logs; a stopped persistence daemon is not the only possible cause.",
|
||||
"<strong>Container starts but <code>ls /dev/nv*</code> shows no NVIDIA devices:</strong> check the bind-mount entries and host device paths. Use <code>ls -l /dev/nv*</code> on the host to verify NVIDIA major numbers, then check the <code>lxc.cgroup2.devices.allow</code> rules and permissions."
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user