Selling GPU servers by the hour with WHMCS
How to rent out NVIDIA GPUs by the hour from WHMCS: container hosts, offers, Metric Billing for GPU hours, and prepaid credit so every hour gets paid.
6 min read
If you have servers with NVIDIA cards and already run WHMCS, you can rent the cards out by the hour: the customer orders, gets root in a container with whole cards a minute or so later, and WHMCS bills the hours they used.
VorticPanel sells a GPU two ways. A KVM node can pass a card of any make through to a virtual machine, sold from a package like any other server. A GPU container host rents NVIDIA cards out in containers, sold as offers. A node is one or the other. GPU servers compares the two side by side. For hourly rental, containers are the better fit: nothing to install or boot, and the images already have the frameworks people ask for. This post covers containers.
1. The host
A GPU container host is a node that runs Docker instead of KVM. It needs:
- Ubuntu 22.04 or 24.04, Debian 12, or Rocky or Alma Linux 9, freshly installed.
- NVIDIA cards. Turing and newer (RTX 20 series on, T4, A-series, L4, L40S, H100) run on NVIDIA's open driver. GTX 10, Tesla P100 and V100 need its closed driver, which the installer adds with
--nvidia-proprietary. - Secure Boot off, or a console at the next boot to enroll the driver's key.
- Ports 40000–49151 open to customers, TCP and UDP, in your provider's firewall. Instances' forwarded ports come from that range.
In the panel, go to Nodes → Enroll node, choose GPU containers under What it runs, and run the command it gives on the machine. It installs the driver, Docker and the NVIDIA Container Toolkit, and turns on Docker's user namespaces, which map root in a customer's container to an unprivileged user on the host. Then, on the host's Assets tab, switch on each card you rent out. See Adding a GPU container host.
2. Images and offers
Images are what instances run. A new panel starts with CUDA on Ubuntu, PyTorch, TensorFlow with Jupyter, vLLM and Ollama, and you can add any Docker image. Pin a version tag rather than latest, so every host runs the same thing. Each image says how it's reached: SSH, JupyterLab with SSH, or the image's own program on its own ports, such as Ollama's API on 11434.
Offers are what you sell, the way packages are for servers: the cards (1 to 8 of a model), vCPU, memory, the size of /workspace (which survives a change of image), the container disk, the network (forwarded ports or an IPv4 address of its own) and the locations it's sold in. The offers list shows how many more instances fit in each location. See GPU containers.
3. The WHMCS product
Install the WHMCS module and add your panel as a server, then make a product for each offer:
- Module Settings → Package: the GPU offer.
- Operating system: an image, or The client chooses it in the panel, or a configurable option. With that, the instance is created waiting for setup with its cards held, and the client picks the image when they first open it. Or add a configurable option named Operating System with one choice per image.
- A custom field called SSH Key, so clients can sign in over SSH as soon as the instance runs. JupyterLab works without one.
- Automatically setup the product as soon as the first payment is received.
The client area then shows the instance's cards, its SSH command and its JupyterLab link, with Start, Restart and Stop.
4. Charging by the hour
The panel measures the hours and the module reports them to WHMCS, which puts them on invoices. Each instance has two numbers in WHMCS's Metric Billing:
- GPU running hours: time the container was running.
- GPU allocated hours: time the instance existed, running or not. Its cards, ports and address are held either way, so a stopped instance still keeps a card from someone else.
To bill only for usage, set the product's Payment Type to Recurring, monthly, at 0.00. Don't use Free: a free product doesn't renew, so its usage would not be invoiced. Turn on Enable Metric Usage Invoicing under General Settings → Invoices, then on the product's Module Settings, switch GPU running hours on and give it a price per unit, such as $0.45 an hour. Add allocated hours at a lower price if you want stopped instances to cost something too.
Each month's hours go on the next renewal invoice. When a service ends before then, the module bills what's left as billable items priced with the product's own Metric Billing, such as:
GPU running hours for train-1 (gi_7k2m9q), October 2026: 12.5 hours (final usage)
With the module's Immediate cancellations setting left on its default, a client's immediate cancellation ends the instance when the request comes in, which stops the hours there rather than at WHMCS's daily run.
5. Getting paid before the hours run up
Usage billed after the fact leaves a gap: a client can run a card all week, cancel and not pay the invoice. For GPU products, turn on Pay from credit on the product's Module Settings, and the product works as a prepaid account:
- An instance starts only when the client's credit covers its Hours of credit (2 by default) at your prices. Without enough, the order waits, the client is emailed and their page asks them to add funds, and the instance is made once their payment arrives.
- Every five minutes, after WHMCS's cron, the module compares what the client owes (this month's hours, unpaid invoices and items not invoiced yet) with their credit. The client area shows the credit left and about how many hours it covers.
- When credit runs low, the client is emailed once to add funds.
- When it runs out, the instance is suspended with "Out of credit: add funds to start it again". Its
/workspace, address and ports are kept, and it's unsuspended when the client tops up. - After a week out of credit (the product's Time out of credit, which takes minutes, hours or days), it's terminated so its cards are free for someone else, after an email warning the client. WHMCS's own overdue termination wouldn't catch it, since no invoice is overdue.
When an instance ends, its last hours are invoiced at once and paid from the credit as far as it goes. The module doesn't take money itself: the hours go on invoices, which WHMCS pays from the credit. Turn on Add Funds under General Settings → Credit, and leave No Auto Apply Credit unticked. See Paying from credit.
All of this runs from WHMCS's cron, so check the cron runs. On a WHMCS hosted in Plesk, ours failed without a word because Plesk ran the cron on a different PHP version from the one WHMCS's ionCube loader was installed for. Set the cron's PHP to the same version as the site's.
How instances are isolated
Containers share the host's kernel. Instances run without privileges or raw sockets, in user namespaces, with their own disk limits, and can't reach your internal networks or cloud metadata. They're still not virtual machines: rent GPU hosts to customers you'd sell a server to, and give a card to a KVM server when a customer needs a kernel of their own.
Related
- GPU hosting: what the panel does for GPU rental
- The WHMCS module, for servers and GPU instances
- GPU containers: images, offers, instances and how they run
- WHMCS module: GPU instances