Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Proxmoxve Laravel Package

zzantares/proxmoxve

A Laravel/PHP client for the Proxmox VE API that lets you manage nodes, virtual machines, LXC containers, storage, and cluster resources directly from your application using a clean, fluent, object-oriented interface. Includes support for VM lifecycle operations, snapshots, and task monitoring.

Deep Wiki
Context7

Getting Started

This is a plain PHP library, not a Laravel package — there's no service provider, facade, or config file to publish. Expect to wire it up yourself, which is usually 20–30 lines.

  1. Install:
composer require zzantares/proxmoxve

Requires PHP 5.5+ and the cURL extension (Proxmox's API is HTTPS on port 8006, not HTTP).

  1. First connect (ticket auth):
use ProxmoxVE\Proxmox;

$proxmox = new Proxmox([
    'hostname' => 'pve.example.com',
    'username' => 'root@pam',   // realm is mandatory
    'password' => 'secret',
    'port'     => 8006,
]);
  1. Confirm it works and get oriented:
$proxmox->get('/nodes');                 // [{node: "pve", status: "online", ...}]
$proxmox->get('/nodes/pve/qemu');        // QEMU VMs on that node
$proxmox->get('/nodes/pve/lxc');         // LXC containers

The four generic verbs — get(), create(), set(), delete() — map to Proxmox's GET/POST/PUT/DELETE and cover the entire API. That's the whole surface area; the rest of the library is convenience wrappers.

  1. Where to look first in the source: src/ProxmoxVE/Proxmox.php for the transport, then the Access/ classes (Nodes, VirtualMachines, Containers, Pools, Storage). The Access/ classes give you typed helpers like $proxmox->getVirtualMachines()->getVMList($node) instead of hand-writing paths.

  2. Realistic first use case: a /admin/servers page in your app that lists nodes and VMs by querying /nodes and /nodes/{node}/qemu, then starts/stops a VM with create('/nodes/{node}/qemu/{vmid}/status/start').

Implementation Patterns

Bind it as a singleton in a service provider. Don't new Proxmox(...) in controllers — you'll re-login (extra ticket round-trip) on every request and you can't mock it in tests.

// config/services.php
'proxmox' => [
    'hostname' => env('PROXMOX_HOST'),
    'username' => env('PROXMOX_USER'),
    'password' => env('PROXMOX_PASS'),
    'port'     => env('PROXMOX_PORT', 8006),
],

// AppServiceProvider::register()
$this->app->singleton(Proxmox::class, fn () => new Proxmox(config('services.proxmox')));

Prefer API tokens over username/password. Ticket auth expires (~2h) and breaks if TFA is enabled on the account; tokens don't expire and can be scoped read-only for dashboards. Check the current README for the exact token config key — the library added token support after its ticket-only era, and the shape differs between versions.

Wrap it in your own domain service, not the vendor class. The library returns raw decoded API payloads and throws one generic exception type. Put your business methods behind an interface so you can swap implementations or fake it:

interface ProxmoxGateway {
    public function listVms(string $node): array;
    public function startVm(string $node, int $vmid): string; // returns UPID
}

Task polling is on you. Every mutating call (start, stop, create, clone, resize) returns a UPID, not a result. The library does not wait. Poll /nodes/{node}/tasks/{upid}/status until status === 'stopped' and check exitstatus === 'OK'. Wrap this in a helper — you'll write it once and reuse it everywhere:

public function waitForTask(string $node, string $upid, int $timeout = 60): void
{
    $deadline = time() + $timeout;
    do {
        usleep(500_000);
        $status = $this->proxmox->get("/nodes/$node/tasks/$upid/status");
        if ($status['status'] === 'stopped') {
            if ($status['exitstatus'] !== 'OK') {
                throw new ProxmoxTaskFailed($status['exitstatus']);
            }
            return;
        }
    } while (time() < $deadline);
    throw new ProxmoxTaskTimeout($upid);
}

Push provisioning into queued jobs. Creating or cloning a VM takes 10–60s. A synchronous controller action will time out and the polling loop will block a PHP-FPM worker. Dispatch a job that creates the VM, stores the UPID, then dispatches a second job (or uses retry/backoff) to poll.

Use the Access/ helpers for read paths, the generic verbs for everything else. The helpers are thin and the API is enormous; don't expect a typed method for migrate, resize, or snapshot. Raw paths are the norm.

Batch reads for dashboards. get('/nodes') then one get("/nodes/{$node}/qemu") per node is N+1 network calls. If you're rendering many rows, cache the raw responses for 30–60 seconds in Redis — Proxmox's API is not fast and you'll hammer it from page loads otherwise.

Gotchas and Tips

  • Self-signed certificates are the #1 first-run failure. Proxmox ships a self-signed cert on 8006; cURL will reject it with SSL certificate problem. Check the constructor options and the cURL setup in Proxmox.php for the verify toggle, or supply a CA bundle. Do not globally disable peer verification.
  • The realm is part of the username. root will fail; root@pam works. Same for tokens: user@realm!tokenname.
  • config:cache will bake your credentials into the cached config. That's fine if you accept it, but if you rotate Proxmox passwords/tokens you'll need php artisan config:clear. Consider reading the secret via env() in a dedicated non-cached binding.
  • Paths are relative to /api2/json. Don't include the prefix in your path strings, and don't include a trailing slash — /nodes/pve/ and /nodes/pve behave differently in Proxmox.
  • The library is a thin transport, so API errors surface raw. You'll get a ProxmoxException on cURL failures or non-2xx responses. Proxmox returns structured errors in the body (permission denied, invalid VMID, locked VM); inspect the response to distinguish "your credentials are wrong" from "that VM is locked for backup." Catch and translate into your own exception types at the boundary.
  • A VM in locked state silently rejects every mutating call. Check $vm['lock'] before you try to start/stop/delete, or you'll get confusing 500s that look like auth problems.
  • Ticket refresh is easy to get wrong. Create the client once per request/job and let it hold the ticket. If you're seeing sporadic 401s on long-running queue workers, explicitly re-login or switch to tokens.
  • TFA-enabled accounts can't use password auth. If root@pam has TFA, ticket login fails outright. Use a dedicated API token for automation — this is the recommended production setup anyway.
  • Testing: never hit a real Proxmox in the test suite. Because the class is final-ish and takes an options array, inject your gateway interface and use a fake; you cannot meaningfully mock the vendor class's internals.
  • Extension points are minimal. There's no event system, no retry middleware, no pluggable HTTP client. If you need retries, logging of request/response, or a PSR-18 transport, you'll build it around the class or replace it with a thin Guzzle/Http:: client of your own against the documented Proxmox API — for nontrivial workloads, that's often the better call.
  • Version pinning matters. The last release is from early 2023; the API surface (token support, access classes) changed across versions and there's no changelog discipline. Pin the exact version and read the source when something looks undocumented.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus