Proxmox VM Self Service (PVMSS)
PVMSS is a web application that simplifies the creation of virtual machines for users without having to go through the web interface or command line of Proxmox VE.
By leaving the choice of parameters such as the amount of virtual processors and memory, the size of the virtual storage, the boot ISO image, the user will be autonomous and able to create as many virtual machines as they are authorized by the administrators. PVMSS is compatible with Proxmox VE 9.0 and above. It is not compatible with versions 8 and below because the roles have changed in PVE.
Context#
My observation in June 2025, after more than 10 years of observing and responding to needs in different situations where I have used Proxmox, is that there is a lack of on-demand virtual machine creation interface.
More recently, colleagues have asked me for machines to perform tests and be autonomous, which I could not provide on demand, at any minute.
That’s when I had the idea of “Proxmox VM Self-Service” (abbreviated PVMSS). PVMSS does not support PVE’s LXC containers.
Why not use the Proxmox web console directly?#
The creation of virtual machines in PVE is done via the web interface after authentication, or via the command line.
As a user, you can create virtual machines via the web interface, but you need to have the access and rights set up by the administrators.
However, for non-initiates, the Proxmox virtual machine creation web interface can be confusing, or even unusable. There are many parameters to choose from without knowing quickly what they are for. The Proxmox web interface is reserved for the initiated (even though their documentation is well provided).
Features for users#
- Create a VM : Create a new virtual machine with customizable resources (CPU, RAM, storage, description, machine name, operating system).
- Access to the VM console: integrated web client (noVNC console).
- VM management : Start, stop, restart and delete virtual machines, resize CPU, RAM and network card quantities, choose network bridges.
- VM search : Find virtual machines by their VMID, tag or name, or all three.
- VM details : Display complete VM information including status, description, tags, uptime, CPU, memory, disk usage and network configuration.
- Profile management : View your list of VMs, reset your password.
- Multi-language : The interface is available in French and English.- Documentation : A help document for using PVMSS is available in both languages, to help users exploit PVMSS.
Features for administrators#
- PVMSS app informations : Many informations of the state of PVMSS as an administrator.
- Nodes management: Display the Proxmox cluster and nodes available for VM deployment.
- User pool management : Add or remove users accessing PVMSS.
- Tags management : Create and manage tags for VM organization.
- ISO management : Configure ISO images available for VM installation (does not allow adding models or ISOs from PVMSS).
- Network configuration: Manage accessible network bridges (VMBRs) for VM networking, and the number of network cards a VM can have.
- Storage management : Configure storage locations for VM disks, and the amount of virtual disk space a VM can have.
- Resource limits : Define CPU, RAM and disk limits for VM creation, the amount of disk and network cards a VM can have (having imposed limits) and the limits a Proxmox node can support for PVMSS.
User interface#
Todo
Administrator interface#
Todo
An administration interface for the application allows administrators to limit resources, organize and distribute everything necessary for users.
Thus, the choice of ISO images, tags, network bridges, and resource limits for VMs are in the hands of administrators.
Workflow#
You must create two secrets, one for the local security of the PVMSS application and the other for the password of the local administrator account of PVMSS.
For the first, you can freely enter what you wish or use, for example, the result of the command openssl rand -hex 32. For the administrator account password, you will need to enter the result of a bcrypt hash. You can easily create this hash with the htpasswd utility under Linux: htpasswd -bnBC 12 "" my_secret_password | cut -d : -f 2 (source
).
Before deploying PVMSS, the administrator must prepare the Proxmox server. You need to create an API token (token api), then add the necessary rights for the proper functioning of the PVMSS application.
Creation of the API token in command line and assignment of rights: TODO
Via the Proxmox web interface:
- go to
Datacenter>Permissions>Users - click on the
Addbutton, enter the username, select the realm (realm) on “Proxmox VE Authentication” and enter a strong password (you will not need the password, but it is crucial to put one to avoid abuse of connection with this privileged account). For the example, I created a user “jhdocker”. - then, go to
Datacenter>Permissions>API Tokens - click on the
Addbutton, select the user you just created (jhdocker@pve) and enter a name for the API token. - by clicking on the ‘Add’ button of the form, the API token secret will be displayed only once. Copy the secret to a secure location, you will need it for the proper functioning of the app. For the example, my token is called “test”
- finally, go to
Datacenter>Permissions, click on the “Add” button then onAPI Token Permissions, select the path “/” and your API token that you just created (in my case, “jhdocker@pve!test”), select the role “PVEAdmin”, and check the “propagate” box.
Once the application is started, access the administration interface by logging in as an administrator and the password you generated. Then navigate through the different tabs on the left of the application to apply, activate and create your configuration according to your environment. Finally, create users from PVMSS. The creation of these users via PVMSS will use the API token to create local accounts on the Proxmox server, create a specific pool for the user and assign the necessary rights. Thus, each user will have their own personal space for their virtual machines, which will not be visible to other users.
Configure the environment variables#
You can use the provided example file env.example to create your own .env file. Or you can modify the example file directly.
ADMIN_PASSWORD_HASH: A bcrypt hash of the password for the administration panel. You can generate one using an online tool or a simple scriptLOG_LEVEL: Set the log level of the application:INFOorDEBUG(default:INFO).PROXMOX_API_TOKEN_NAME: The name of your Proxmox API token for backend operations (e.g.,user@pve!token).PROXMOX_API_TOKEN_VALUE: The secret value of your API token.PROXMOX_URL: The complete URL to your Proxmox API endpoint (e.g.,https://proxmox.example.com:8006/api2/json).PROXMOX_VERIFY_SSL: Set tofalseif you are using a self-signed certificate on Proxmox (default:false).PVMSS_ENV: “prod” or “dev”, this argument will be used to unlock or freeze some featuresPVMSS_OFFLINE: When your Proxmox node is not reachable, but you want to access the application without making API calls, set this option to “true”. Thus, you will be able to configure some options of PVMSSPVMSS_SETTINGS_PATH: The default path in the app to store its configuration can be modified, it is not useful for the moment, but the option exists.SESSION_SECRET: Secret key for session encryption (change to a random unique string, for example$ openssl rand -hex 32)
environment:
# Proxmox VE settings
PROXMOX_API_TOKEN_NAME: "nom_user_pvmss@pve!nom_jeton_api"
PROXMOX_API_TOKEN_VALUE: "aaaaaaaa-0000-44aa-1111-aaaaaaaaaaa"
PROXMOX_URL: "https://ip-or-name:8006/api2/json"
PROXMOX_VERIFY_SSL: false
# PVMSS settings
ADMIN_PASSWORD_HASH: "$2y$10$Ppg7Wl3sNYrmxZmWgcq4reOyznt7AeqMrQucaH4HY.dBrzavhPP1e"
LOG_LEVEL: "INFO"
SESSION_SECRET: "changeMeWithSomethingElseUnique"
PVMSS_ENV: "prod" # Environment: production/prod or development/dev/developpement
PVMSS_OFFLINE: "false"
PVMSS_SETTINGS_PATH: "/app/settings.json"
TZ: "Europe/Paris"Launch the container#
Create the settings.json file that will be used by PVMSS to store its configurations:
{
"tags": ["pvmss"],
"isos": [],
"vmbrs": [],
"max_network_cards": 1,
"max_disk_per_vm": 1,
"enabled_storages": [],
"limits": {
"nodes": {},
"vm": {
"cores": {
"max": 2,
"min": 1
},
"disk": {
"max": 12,
"min": 6
},
"ram": {
"max": 4,
"min": 1
},
"sockets": {
"max": 1,
"min": 1
}
}
}
}Create the docker-compose.yml file and enter this content:
---
services:
pvmss:
image: jhmmt/pvmss:0.4.0
container_name: pvmss
restart: unless-stopped
ports:
- "50000:50000/tcp"
# Use either the .env file for environment variables
# or the environment variables in the docker-compose.yml file.
# env_file:
# - .env
environment:
# Proxmox VE settings
PROXMOX_API_TOKEN_NAME: "tokenName@changeMe!value"
PROXMOX_API_TOKEN_VALUE: "aaaaaaaa-0000-44aa-1111-aaaaaaaaaaa"
PROXMOX_URL: "https://ip-or-name:8006/api2/json"
PROXMOX_VERIFY_SSL: "false"
# PVMSS settings
ADMIN_PASSWORD_HASH: "$2y$10$Ppg7Wl3sNYrmxZmWgcq4reOyznt7AeqMrQucaH4HY.dBrzavhPP1e"
LOG_LEVEL: "INFO"
SESSION_SECRET: "changeMeWithSomethingElseUnique"
PVMSS_ENV: "prod" # Environment: production/prod or development/dev/developpement
PVMSS_OFFLINE: "false"
PVMSS_SETTINGS_PATH: "/app/settings.json"
TZ: "Europe/Paris"
volumes:
- ./settings.json:/app/settings.json
deploy:
resources:
limits:
cpus: "1"
memory: 64MWith Docker running, execute the following command from the project root docker compose up -d, or launch the container with docker run :
docker run -d \
--name pvmss \
--restart unless-stopped \
-p 50000:50000 \
-v $(pwd)/settings.json:/app/settings.json \
-e ADMIN_PASSWORD_HASH="$2y$10$Ppg7Wl3sNYrmxZmWgcq4reOyznt7AeqMrQucaH4HY.dBrzavhPP1e" \
-e LOG_LEVEL=INFO \
-e PROXMOX_API_TOKEN_NAME="tokenName@changeMe!value" \
-e PROXMOX_API_TOKEN_VALUE="aaaaaaaa-0000-44aa-1111-aaaaaaaaaaa" \
-e PROXMOX_URL=https://ip-or-name:8006/api2/json \
-e PROXMOX_VERIFY_SSL=false \
-e PVMSS_ENV="prod" \
-e PVMSS_OFFLINE="false" \
-e PVMSS_SETTINGS_PATH="/app/settings.json" \
-e SESSION_SECRET="$(openssl rand -hex 32)" \
-e TZ=Europe/Paris \
jhmmt/pvmss:0.4.0The application will be available at http://localhost:50000.
Consult the logs#
Via the docker command line : docker logs -f pvmss.
Find the images on the docker hub at this address : https://hub.docker.com/r/jhmmt/pvmss/tags
Deployment of the application in Kubernetes#
A manifest containing all the necessary information is available at the root of this repository, named pvmss-deployment.yaml. This manifest contains :
- A namespace
- A service account
- A secret
- A configmap
- A persistent volume claim (pvc)
- A deployment
- A service
apiVersion: v1
kind: Namespace
metadata:
name: pvmss
---
apiVersion: v1
kind: ServiceAccount
automountServiceAccountToken: true
metadata:
name: pvmss-sa
namespace: pvmss
---
apiVersion: v1
kind: Secret
metadata:
name: pvmss-secrets
type: Opaque
data:
admin-password: changemebase64hash
pve-api-token: changemebase64hash
session-secret: changemebase64hash
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pvmss-config
data:
settings.json: |
{
"tags": [
"pvmss"
],
"isos": [],
"vmbrs": [],
"max_network_cards": 1,
"max_disk_per_vm": 1,
"enabled_storages": [],
"limits": {
"nodes": {},
"vm": {
"cores": {
"min": 1,
"max": 4
},
"disk": {
"min": 6,
"max": 12
},
"ram": {
"min": 1,
"max": 4
},
"sockets": {
"min": 1,
"max": 1
}
}
}
}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvmss-settings-pvc
namespace: pvmss
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: "" # Use default storage class
---
kind: Deployment
metadata:
name: pvmss
namespace: pvmss
labels:
app.kubernetes.io/name: pvmss
app.kubernetes.io/instance: pvmss
app.kubernetes.io/version: 0.4.0
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: pvmss
template:
metadata:
labels:
app.kubernetes.io/name: pvmss
spec:
automountServiceAccountToken: true
serviceAccountName: pvmss-sa
securityContext:
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
fsGroupChangePolicy: OnRootMismatch
terminationGracePeriodSeconds: 5
restartPolicy: Always
containers:
- name: pvmss
image: jhmmt/pvmss:0.4.0
imagePullPolicy: IfNotPresent
ports:
- name: backend
containerPort: 50000
protocol: TCP
env:
- name: ADMIN_PASSWORD_HASH
valueFrom:
secretKeyRef:
name: pvmss-secrets
key: admin-password
- name: LOG_LEVEL
value: "INFO"
- name: PROXMOX_API_TOKEN_NAME
value: "changeme"
- name: PROXMOX_API_TOKEN_VALUE
valueFrom:
secretKeyRef:
name: pvmss-secrets
key: pve-api-token
- name: PROXMOX_VERIFY_SSL
value: "false"
- name: PROXMOX_URL
value: "https://changeme:8006/api2/json"
- name: SESSION_SECRET
valueFrom:
secretKeyRef:
name: pvmss-secrets
key: session-secret
- name: PVMSS_ENV
value: "production" # Can be 'dev', 'developpement', 'prod'
- name: PVMSS_OFFLINE
value: "false" # Set to true to disable Proxmox connection
- name: PVMSS_SETTINGS_PATH
value: "/data/settings.json"
- name: TZ
value: "Europe/Paris"
volumeMounts:
- name: pvmss-settings
mountPath: /data
readOnly: false
resources:
requests:
memory: "64Mi"
cpu: "25m"
limits:
memory: "128Mi"
cpu: "50m"
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
volumes:
- name: pvmss-settings
persistentVolumeClaim:
claimName: pvmss-settings-pvc
---
apiVersion: v1
kind: Service
metadata:
name: pvmss
namespace: pvmss
spec:
selector:
app.kubernetes.io/name: pvmss
app.kubernetes.io/instance: pvmss
app.kubernetes.io/version: 0.4.0
ports:
- name: backend
protocol: TCP
port: 50000
targetPort: 50000To deploy the application in Kubernetes, run the following command : kubectl apply -f pvmss-deployment.yaml.
Limitations of PVMSS#
- No rigorous security tests have been conducted, be careful when deploying.
- No (yet) OpenID Connect support.
- Only a local administrator at PVMSS can manage the application, there is no possibility yet to create additional administrators.
The technical stack#
Based on the Go language for the engine (backend) and HTML and CSS for the user interface (frontend), I want to keep the tool as simple as possible technically. The sources are available on GitHub at this address .
Licence#
PVMSS is licensed under “Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International”. For more information, visit https://creativecommons.org/licenses/by-nc-nd/4.0/ .
Divers#
Proxmox VE (PVE) is a suite of tools under Debian 13 that allows you to have a virtualized infrastructure for your needs. Provided for free and with a paid support service, PVE is accessible and is taking up more and more space in different contexts.
To install Proxmox in Debian 13, you can find an article I wrote here https://j.hommet.net/installer-proxmox-sur-debian/ .
- Tags
- #pvmss
- Published
- Reading time
- 10 minutes
- Word count
- 2077 words
- Last modified