Guides

Proxmox helper scripts: what they run on your host, and how to pin them

Proxmox VE helper scripts run as root on your host: what a script does, how to read and pin it to a commit, what post-install changes and how to roll back.

Published ~12 min read
On this page

The Proxmox VE helper scripts are the one-line installers that turn a fresh Proxmox host into a Home Assistant box, a Jellyfin server or a Docker VM in a few minutes. Most guides stop at “copy the command, paste it into the shell”. This one reads the code first: what a script changes on your host, how to pin it so the same code runs every time, and which scripts belong on a server you depend on.

Short answer

Proxmox helper scripts are bash installers from the community-scripts project, started by tteck. One command downloads a script from GitHub and runs it as root on the host, where it creates an LXC container or VM with preset defaults and installs an app in it. Read the script first, pin it to a commit, and snapshot before you run anything that changes the host.

Proxmox helper scripts at a glance (read 2 November 2026)

Repository
github.com/community-scripts/ProxmoxVE
Website with every command
community-scripts.org
Engine (since August 2026)
github.com/community-scripts/core
Supported Proxmox VE
8.0 to 8.4 and 9.0 to 9.2 (README)
Runs as
root on the Proxmox host
Scripts in the repo
649 container, 20 VM, 35 host tools
License
MIT
Original author
tteck (repo tteck/Proxmox, archived November 2024)

What the Proxmox helper scripts are, and who maintains them

The collection began in August 2021 as tteck’s personal repository, tteck/Proxmox. When he could no longer maintain it, the project moved to the community-scripts organization on 1 November 2024, with the full history carried over (18,582 commits on the day we checked). The old repository is archived. The README now credits tteck “in memory”, and a core team of volunteers reviews changes. New scripts are tested in a separate DevScripts repository before they reach the main one.

That history matters when you copy a command from an old forum post or video. A URL that contains tteck/Proxmox still downloads, but it runs code frozen in November 2024, and its version check only accepts pve-manager/8.1 to 8.3. On Proxmox VE 9 it stops with “This version of Proxmox Virtual Environment is not supported”. Always start from the current repository or community-scripts.org.

FolderWhat is in itWhere it runs
ct/The script you paste: the app's name, default resources and update functionProxmox host
install/What gets installed inside the new containerInside the container
vm/Full virtual machines: Debian, Ubuntu, Home Assistant OS, OPNsense, TrueNAS, a Docker VM and othersProxmox host
tools/pve/Host tools: post-install, microcode, kernel clean and pin, container updatesProxmox host
tools/addon/Add-ons installed into an existing container, such as Tailscale or PortainerHost or container

Since August 2026 the shared engine (the code that asks the questions, creates the container and handles errors) lives in a second repository, community-scripts/core. The scripts in ct/ are now short: the Debian one is 45 lines, and its third line loads the engine from core at run time. Keep that in mind for the pinning section below, because a pin on one repository no longer pins the other. The README also notes that the same scripts run unchanged on an Incus host, through the project’s separate Incus repository.

The most-installed helper scripts

If you came for a specific script, these were the ten most installed in the last 30 days according to the counter on community-scripts.org (read 2 November 2026). Each runs with the same command as the Debian example below; only the path at the end of the URL changes.

ScriptTypeInstalls (30 days)Path in the command URL
DockerContainer5,897ct/docker.sh
DebianContainer4,638ct/debian.sh
ImmichContainer4,278ct/immich.sh
Jellyfin Media ServerContainer3,956ct/jellyfin.sh
AdGuard HomeContainer3,874ct/adguard.sh
Home Assistant OSVM3,483vm/haos-vm.sh
Pi-holeContainer3,477ct/pihole.sh
Nginx Proxy ManagerContainer3,385ct/nginxproxymanager.sh
TailscaleAdd-on for an existing container3,308tools/addon/add-tailscale-lxc.sh
FrigateContainer2,688ct/frigate.sh

What happens when you run a helper script

Every script page on the website gives one command in the same form. For the plain Debian container it is:

Proxmox VE shell, as root
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)"

curl -fsSL downloads the script quietly and fails on an HTTP error, the $(...) turns the file into a string, and bash -c runs that string. Nothing is saved to disk, so there is nothing left to read afterwards. main in the URL means “whatever is on the main branch right now”. We traced what a run does from the source, at the commits listed in the test box at the end:

  1. 1Load the engine from the second repository

    Line 3 of ct/debian.sh sources core/build.func from community-scripts/core, branch main, unless you point it elsewhere. The engine then fetches around 20 more function files the same way.

  2. 2Check the host

    It stops unless it runs as root, in bash, on amd64 or arm64, on a Proxmox node with a supported version. Over SSH from outside the node’s network it warns and recommends the Proxmox web shell instead; sessions from the node itself or the same /24 get no warning.

  3. 3Ask about diagnostics, once

    On the first run a dialog asks “Send Diagnostics of LXC Installation?”. Your answer is stored in /usr/local/community-scripts/diagnostics. With DIAGNOSTICS=yes, each install reports the app, the container’s resources, CPU, GPU and RAM facts and, when it fails, the failing command and its log lines to telemetry.community-scripts.org. Answer no, or set DIAGNOSTICS=no in that file, to send nothing.

  4. 4Default or Advanced

    Default asks only what it must, such as the storage when there is more than one. Advanced shows every setting below before anything is created.

  5. 5Download a template and create the container

    It updates the template list with pveam, downloads the OS template if it is not cached, and calls pct create with the next free ID.

  6. 6Run the install half inside the container

    It fetches install/debian-install.sh and runs it through lxc-attach: update the OS, set up the message of the day, configure console login, clean up. For an app such as Uptime Kuma, this is where the app itself is downloaded.

  7. 7Leave an update command behind

    It writes /usr/bin/update into the container. Typing update in the container console downloads the same ct/ script again, from the same branch, and runs its update function.

What Default mode gives you

Read these before you accept the defaults on a server rather than a home lab. They come from the engine’s built-in values and the Debian script’s own header; other apps set their own CPU, RAM and disk.

SettingDefaultWhat to check
Container typeUnprivilegedKeep it. Some apps ask for privileged; read why first.
Debian resources1 vCPU, 512 MB RAM, 2 GB disk, Debian 13Each app script sets its own; Advanced changes them.
Networkvmbr0, IPv4 by DHCP, IPv6 offWithout a DHCP server on that bridge the container gets no address. Set a static IP in Advanced.
Featuresnesting=1, plus keyctl=1 when unprivilegedNeeded for Docker inside the container; also a wider surface.
SSHOffIf you enable root SSH access, the engine sets PermitRootLogin yes.
Root passwordEmpty: root logs in on the console automaticallySet one in Advanced if anyone else can open the console.
Tagscommunity-scriptHandy for finding them later in the web UI.

How to read a helper script before you run it

The project’s own README says it plainly: the commands run as root on your host, so read the script before you paste it. Because the work is split into three parts, reading only the file in the URL is not enough. Download all three and page through them:

any Linux machine, no root needed
APP=debian
mkdir -p ~/cs-review && cd ~/cs-review
curl -fsSLO https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/$APP.sh
curl -fsSLO https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/$APP-install.sh
less $APP.sh $APP-install.sh

# every place the code downloads or runs something else
grep -nE 'curl|wget|source|bash -c|eval' $APP.sh $APP-install.sh

What to look for in the two files:

  • The var_ lines at the top of the ct/ script: CPU, RAM, disk, OS version and var_unprivileged. A 0 there means a privileged container.
  • Every URL. App installs often call fetch_and_deploy_gh_release, which downloads the app’s latest GitHub release. Check that the repository it names is the app’s official one.
  • Anything that writes outside the container in the ct/ half: pct set, bind mounts, device passthrough, edits under /etc/pve.
  • The engine is the larger part: core/build.func and the files it loads come to several thousand lines. You do not have to read it every time, but read it once, and read its changes when you move your pin.

Pin a helper script to a commit

A URL with main in it can run different code tomorrow than it ran today. Pinning means replacing main with a full commit hash, so the code you read is the code you run. The common advice is to pin the script’s URL. Since the engine moved out, that pins only the 45-line script, while the engine still comes from core/main. Pin both repositories:

Proxmox VE shell: look up the current commits first
git ls-remote https://github.com/community-scripts/ProxmoxVE refs/heads/main
git ls-remote https://github.com/community-scripts/core refs/heads/main
Proxmox VE shell: run the Debian script with both repositories pinned
S=7774a1a28d6e637c47a7476de3e9167fbe337d25   # ProxmoxVE commit you read
E=09fac1952f6050395aae8e6ecc9d4900c5c180d2   # core (engine) commit you read

COMMUNITY_SCRIPTS_URL=https://raw.githubusercontent.com/community-scripts/ProxmoxVE/$S \
COMMUNITY_SCRIPTS_CORE_URL=https://raw.githubusercontent.com/community-scripts/core/$E \
  bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/$S/ct/debian.sh)"

Both variables are the ones the project documents for testing a fork or branch: COMMUNITY_SCRIPTS_URL decides where the install/ half comes from, COMMUNITY_SCRIPTS_CORE_URL where the engine comes from. The two hashes above are the heads of both branches on 2 November 2026; both URLs answered 200, and the pinned file’s SHA-256 matched our clone. Use the commits you actually read, not ours.

The stricter way: run from a local checkout

If you want to read diffs instead of URLs, clone both repositories next to each other and check out the commits you reviewed. The ct/ script looks for the engine at ../../core relative to itself and the engine finds install/ next to ct/. Everything still comes from the commits you checked out, but not all of it from disk: the half that runs inside the container downloads the engine files from GitHub, and in checkout mode the engine points that download at community-scripts/core at the short hash of your checkout. That detection needs git on the node, which a fresh install may not have:

Proxmox VE shell
apt install -y git
mkdir -p /root/cs && cd /root/cs
git clone https://github.com/community-scripts/ProxmoxVE.git
git clone https://github.com/community-scripts/core.git
git -C ProxmoxVE checkout 7774a1a28d6e637c47a7476de3e9167fbe337d25
git -C core checkout 09fac1952f6050395aae8e6ecc9d4900c5c180d2
bash /root/cs/ProxmoxVE/ct/debian.sh

# next time: see exactly what changed before you move the pin
git -C ProxmoxVE fetch && git -C ProxmoxVE log --oneline HEAD..origin/main -- ct/debian.sh install/debian-install.sh
git -C core fetch && git -C core diff --stat HEAD origin/main

Two limits apply to every pin:

  • A pin fixes the installer, not the app. 449 of the 635 files in install/ call the release helper, and its default version is latest. Two installs a month apart can get two app versions.
  • The update command inside the container reuses the scripts URL from the install and loads the engine from core/main unless you set the variable again: COMMUNITY_SCRIPTS_CORE_URL=https://raw.githubusercontent.com/community-scripts/core/$E update.

The Proxmox post-install script: what it changes

The most-run host tool is post-pve-install.sh, usually the first thing people run on a new node. It asks before every change, but the prompts are short, so here is what each yes does on Proxmox VE 9. The first two rows only appear on a node that has no .sources file in /etc/apt/sources.list.d yet, such as an old 8.x layout upgraded by hand or a provider image. A fresh 9.x install, or a node upgraded with the official 8 to 9 guide, already has .sources files: the script shows “Deb822 sources detected”, leaves the source format alone and goes straight to the enterprise repository.

Proxmox VE shell, as root
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/post-pve-install.sh)"
PromptWhat yes doesWatch out
Disable legacy sources? (only without .sources files)Renames every *.list file in /etc/apt/sources.list.d to *.list.bak, copies sources.list to sources.list.bak and comments out its deb linesReversible: rename the .bak files back. Repositories you need must exist as .sources files afterwards.
Migrate to deb822 sources format? (only without .sources files)Deletes any *.list file still in /etc/apt/sources.list.d and writes a new debian.sources for trixieIf you answered no to the previous prompt, repositories a provider or you added as .list files are gone without a backup. The new file lists main contrib only, without non-free-firmware, where Debian ships CPU microcode.
pve-enterpriseKeep, disable (Enabled: false) or delete the enterprise repository fileDisable rather than delete if you may buy a subscription later.
pve-no-subscriptionAdds proxmox.sources with the free repositoryThe same change the Proxmox docs describe for hosts without a subscription.
Ceph repositoriesDisables Ceph enterprise and adds Ceph no-subscriptionHarmless if you do not use Ceph.
pve-testAdds the test repository, disabledLeave it disabled on a production node.
Subscription nagPatches proxmoxlib.js and adds an APT hook that re-applies the patch after every package runVendor code changed on every update; a UI bug after an update may come from the patch.
Disable high availabilityStops and disables pve-ha-lrm and pve-ha-crm; a second prompt can disable corosyncOnly on a single node. Never in a cluster.
Update Proxmox VE now?Runs apt -y dist-upgrade with output hiddenYou do not see what is upgraded; run it yourself if you want to read the list.
RebootReboots the nodeEvery VM and container on it stops.

Before you run it, keep a copy of what it edits. On a ZFS install a root snapshot is the cleanest undo; on the default ext4 or XFS layout copy the files:

Proxmox VE shell, before the post-install script
cp -a /etc/apt /root/apt-before-post-install

# ZFS root only: check the dataset name first, then snapshot it
zfs list -o name | grep ROOT
zfs snapshot rpool/ROOT/pve-1@before-post-install

Only if the script wrote a new debian.sources (the migrate prompt above): add non-free-firmware back to its Components: lines and install intel-microcode or amd64-microcode with apt, so microcode keeps receiving updates. On a fresh Proxmox VE 9 install the file is untouched, and the Proxmox documentation lists non-free-firmware there by default.

Useful helper scripts for a server node

Most of the 649 container scripts are apps. The host tools in tools/pve/ are the ones that touch the node itself. We read each of these; this is what it does and whether we would run it on a production host:

ScriptWhat it does on the hostOn a production nodeWithout the script
post-pve-installRepositories, nag patch, HA services, upgrade, reboot (table above)Once, on a fresh node, reading each promptEdit the .sources files by hand
microcodeInstalls iucode-tool, lists every intel-microcode .deb in Debian’s pool, lets you pick one and installs it with dpkg -i (AMD branch the same with amd64-microcode)Prefer the apt package, which gets updatesapt install intel-microcode
kernel-cleanLists old proxmox-kernel packages, purges the ones you select, runs autoremoveFine; keep the running kernel and one olderapt purge proxmox-kernel-X.Y.Z-N-pve-signed
kernel-pinWraps proxmox-boot-tool kernel pin in a menuFine, but the command is one lineproxmox-boot-tool kernel pin VERSION
update-lxcsRuns the package upgrade in every container via pct exec, lets you skip some. In Debian and Ubuntu containers that is apt-get update, dist-upgrade, autoremove, autoclean, and then rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED: it silently removes the PEP 668 marker that stops pip from installing into the system PythonAfter a backup, with a list of skips; check Python apps afterwardspct exec ID -- sh -c 'apt-get update && apt-get -y dist-upgrade'
cron-update-lxcsInstalls /usr/local/bin/update-lxcs.sh and a root crontab entry for unattended upgrades of all containersNo: unattended upgrades with no snapshot firstA backup job, then upgrades you watch
fstrimRuns pct fstrim per container, logs to /var/log/fstrim.logFine on thin storagepct fstrim ID
clean-lxcsDeletes every file under /var/log and /tmp in each selected container. Debian/Ubuntu: also /var/cache and the APT lists, then autoremove. CentOS/RHEL family: yum clean all, then yum upgrade -y, so it also upgrades those containersNo: it wipes logs you may still needpct exec ID -- apt-get clean
host-backupA tar.gz of directories you tick under /etcA quick copy, not a backup strategyvzdump plus a copy of /etc/pve
scaling-governorSets the CPU frequency governor and adds a crontab line to keep it after rebootsOnly if you measured a reasonLeave the default

For the guests themselves, the VM scripts (debian-vm, ubuntu-vm, docker-vm, opnsense-vm) save the fiddly parts of building a cloud image VM, and they have no updater: you patch the guest like any other machine. If you are weighing a single Docker VM against many containers, installing Docker on Debian by hand takes about as long as the script and leaves nothing you have not read.

Production node or home lab?

Why people run them

  • Minutes instead of an evening per app, with sane container defaults
  • Readable bash under the MIT license, with every change in public git history
  • Each container gets an update command, so updates are not forgotten
  • Active maintenance: commits land daily and new scripts are tested before they merge

What you take on

  • Code from main runs as root on the hypervisor that holds every other guest
  • Three moving parts per run: script, engine and the app's latest release
  • A failed step ends the run and removes the broken container by default: Enter or 60 seconds without an answer both remove it, only choosing keep (n, or option 2 in the recovery menu) saves it for debugging, so read the error first
  • Diagnostics are on if you answered yes once, and stay on for every later run

Our rule of thumb: in a home lab, run them from the website and enjoy the time saved. On a node that carries customer or business workloads, pin both repositories, read the diff when you move the pin, avoid the nag patch and unattended updates, and test new scripts on a spare node first. If you are still choosing a hypervisor for that node, Hyper-V vs VMware covers the main commercial options, and what is Hyper-V the Windows one.

Snapshot and roll back

Undoing a helper script means undoing what it created, which is usually one container. Before an update or any change inside it, take a snapshot from the host:

Proxmox VE shell (105 = your container ID)
pct snapshot 105 before-update
pct listsnapshot 105

# the update went wrong
pct rollback 105 before-update

# it worked: drop the snapshot again
pct delsnapshot 105 before-update

Container snapshots need storage that supports them. local-lvm (LVM-thin) and local-zfs, the two layouts the Proxmox installer creates, both do; a container on plain Directory storage does not, so back it up instead with vzdump 105 --mode stop --storage local. Snapshot mode is no way around that: the vzdump documentation says it needs every backed up volume on storage that supports snapshots. Stop mode shuts the container down for a consistent copy and starts it again; --mode suspend keeps the downtime shorter. A new container is only in your backup job if that job covers all guests; a job with a fixed list of IDs needs it added.

Proxmox VE shell: remove a container a script created
pct stop 105
pct destroy 105 --purge    # --purge also removes it from backup, replication and HA jobs

To undo the post-install script, put back the copy of /etc/apt (or roll back the ZFS snapshot), then run apt update. To drop the nag patch, delete /etc/apt/apt.conf.d/no-nag-script and /usr/local/bin/pve-remove-nag.sh and reinstall the original file with apt --reinstall install proxmox-widget-toolkit, plus apt --reinstall install pve-yew-mobile-gui if that package is installed, because the hook patches the mobile UI too. If you disabled HA by mistake, systemctl enable --now pve-ha-lrm pve-ha-crm corosync turns it back on.

Rolling back rpool/ROOT/pve-1 resets more than APT: the cluster configuration database /var/lib/pve-cluster/config.db lives on that dataset, so every VM and container config created after the snapshot disappears from the node. Plan a reboot straight after the rollback.

Common helper script errors

Symptom, cause, fix

  1. Symptom: This version of Proxmox VE is not yet supported.

    Cause
    Your Proxmox VE is newer than the engine's check allows (on 2 November 2026 the newest accepted release was 9.2).
    Fix
    Wait for the project to raise the check, or upgrade from a supported minor release. Editing the check out of a script you then run as root defeats the point of reading it.
  2. Symptom: curl: (22) The requested URL returned error: 404, then header_info: command not found

    Cause
    A command pinned to a commit from before the script moved to the core engine (late August to early October 2026, depending on the script) loads the engine from misc/build.func, which no longer exists.
    Fix
    Take the current command from the website, or pin both repositories as shown in the pinning section.
  3. Symptom: This version of Proxmox Virtual Environment is not supported

    Cause
    The command points at the archived tteck/Proxmox repository, which only accepts 8.1 to 8.3.
    Fix
    Replace tteck/Proxmox with community-scripts/ProxmoxVE and use the current script name from the website.
  4. Symptom: Debian must be run on the Proxmox VE host. (the app name comes first)

    Cause
    You pasted the command into a container, a VM or another Linux machine.
    Fix
    Open the shell of the node itself: in the web UI, click the node, then Shell.
  5. Symptom: Please run this script as root.

    Cause
    You are logged in as a normal user with sudo.
    Fix
    Use sudo -i first, then paste the command. The check also fails when the parent process is sudo, so sudo bash -c does not work either.
  6. Symptom: The container starts but has no IP address

    Cause
    Default mode uses DHCP on vmbr0, and nothing on that bridge hands out addresses.
    Fix
    Set a static address: pct set 105 -net0 name=eth0,bridge=vmbr0,ip=192.0.2.50/24,gw=192.0.2.1, or rerun the script in Advanced mode.

How we tested

OS image
Debian 12, not a Proxmox node (no script was executed)
Versions
community-scripts/ProxmoxVE 7774a1acommunity-scripts/core 09fac19git 2.39.5curl 7.88.1
Tested on
Method
Both repositories cloned at the heads of main and read: ct/debian.sh, install/debian-install.sh, the engine's defaults, container creation, telemetry and version checks, post-pve-install.sh and the host tools in the table. Checked that pinned raw URLs answer 200 and match the clone by SHA-256, that the old misc/build.func URL answers 404, and what an old pinned command prints because of it.
Not tested
Running a script on a Proxmox VE node. The run sequence and defaults above are read from the code, not observed on a host.

A helper script saves you from building the container, not from running the app. If all you need is one of these apps online and you do not need a hypervisor of your own, a Standard KVM VPS runs it directly, with snapshots and a browser VNC console in the panel for the day an update goes wrong.

Frequently asked

Are Proxmox helper scripts safe?

They are open source and actively reviewed, but every one runs as root on your Proxmox host and pulls more code from GitHub while it runs. Read the script and its install half first, pin both the ProxmoxVE and the core (engine) repository to a commit, and take a snapshot or backup before you run anything that changes the host.

What happened to tteck's Proxmox helper scripts?

tteck started the collection in 2021. When he could no longer maintain it, the project moved to the community-scripts organization on GitHub in November 2024, with its full history, and his tteck/Proxmox repository was archived. Old commands that point at tteck/Proxmox run frozen 2024 code that does not accept Proxmox VE 9.

What does the Proxmox post install script do?

On Proxmox VE 9 it asks before each step. Only on a node without any .sources file yet (an old 8.x layout or a provider image) does it first offer to rename legacy .list files to .list.bak and to write a new debian.sources; a fresh 9.x install or a node upgraded with the official guide skips that. Then it can keep, disable or delete the enterprise repositories, add the no-subscription and Ceph repositories, patch out the subscription nag, disable high availability on a single node, run a full upgrade and reboot. Each step only happens if you answer yes.

How do I update an LXC container created by a helper script?

Open the container's console and type update. The command downloads the app's script again and runs its update function. Take a snapshot first with pct snapshot ID before-update on the host, so pct rollback can undo a bad update. VM scripts have no updater; patch those guests with their own package manager.

Do the Proxmox helper scripts work on Proxmox VE 9?

Yes. On 2 November 2026 the project README listed Proxmox VE 8.0 to 8.4 and 9.0 to 9.2, and the engine refuses newer minor releases with 'This version of Proxmox VE is not yet supported.' until the project raises the check.

Related articles

All guides