mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 10:52:22 +00:00
docs: review practical guides in all seven translations
This commit is contained in:
@@ -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>). Stop the Kodi LXC and edit its 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/13 install <code>apt-get install -y wsdd</code> and check its 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