Nel 2026, hostare carichi di lavoro AI su VPS condiviso con Plesk rappresenta una sfida tecnica sempre più frequente. Ho iniziato a ricevere richieste da clienti che volevano eseguire inference di modelli language model, training di machine learning classici e preprocessing dati direttamente su infrastrutture multitenancy. Il problema? Senza limiti di risorse dinamici, un singolo container AI poteva prosciugare RAM e CPU, causando instabilità in tutti gli altri domini.
In questo articolo vi mostro come ho risolto questo scenario negli ultimi mesi: configurazione di container AI-native in Plesk, implementazione di resource limits granulari tramite cgroups, e soprattutto, come attribuire accuratamente i costi per ogni workload AI in ambienti multi-tenant. Ho testato questa procedura su VPS Hetzner e Vultr da 8-16 vCore con risultati solidi.
Perché i Workload AI Richiedono una Gestione Risorse Diversa
La maggior parte dei siti WordPress tradizionali richiede risorse stabili e prevedibili. Ma un training di modello scikit-learn, un’inferenza LLM o un preprocessing batch ha pattern di consumo completamente diversi:
- Picchi di CPU e RAM improvvisi: durante il training di un albero decisionale XGBoost o forward pass di una rete neurale, l’utilizzo può salire dal 10% al 85% in pochi secondi
- Consumi di I/O disco persistenti: machine learning legge dataset interi ripetutamente; senza throttling, il disco NVMe satura
- Memoria volatile instabile: modelli large language model durante l’inferenza consumano gigabyte di RAM; poca memoria disponibile = crash OOM
- Difficoltà di accounting: in Plesk standard, non riesco a tracciare quanto un container AI costa davvero rispetto a un altro subscriber
Per questo motivo, la gestione dei costi Plesk nel 2026 diventa cruciale: se non isolo le risorse, rischio di perdere marginalità o di offrire piani carenti.
Architettura: Container AI-Native con Plesk Obsidian 18.0.76+
Nel mio lab ho implementato questa configurazione:
- Host principale: Plesk Obsidian 18.0.76+ su AlmaLinux 9 / Ubuntu 22.04 (systemd obbligatorio)
- Container runtime: Docker CE integrato in Plesk (tramite estensione Docker)
- Isolamento risorse: cgroups v2 di Linux (Resource Controller di Plesk)
- Modelli AI: Ollama per inference locale, o SDK Python (PyTorch, scikit-learn) per training
- Monitoraggio: Plesk Monitoring + custom Prometheus per metriche granulari
Ho scelto Docker anziché KVM perché i container sono più leggeri, e su un VPS 8 vCore con 16GB RAM, ogni megabyte conta.
Step 1: Abilitare il Resource Controller in Plesk
Per prima cosa, il Resource Controller di Plesk usa cgroups (control groups di Linux). Plesk Cgroups Manager conta il consumo medio di risorse ogni 5 minuti, non in tempo reale. Questo è il primo compromesso che devo accettare.
Procedura di abilitazione:
- Accedo a Plesk > Tools & Settings > Services Management
- Cerco “Resource Controller” nella lista
- Clicco su “Start” (deve essere su AlmaLinux/CentOS 7+ o Ubuntu 16.04+; CloudLinux preferibile)
- Verifico che il servizio sia “Running”:
systemctl status pam_cgroup
Comando per validare che cgroups sia attivo:
cat /proc/filesystems | grep cgroup ls /sys/fs/cgroup/
Se ottengo output, sono a posto. Se no, devo aggiornare il kernel o cambiare OS.
Step 2: Configurare Service Plan con Limiti Dinamici per AI
In Plesk, un Service Plan</strong definisce i limiti massimi per ciascun subscriber. Per un workload AI, non posso usare i limiti standard da hosting web.
Mio template per un “AI Model Training Plan”:”
- CPU: 2 core (200% in notazione Plesk) — sufficiente per training small-to-medium su classical ML
- RAM: 4GB — buffer per caricamento dataset + memoria di sistema
- Disk I/O: 100 IOPS write, 300 IOPS read (NVMe può fare di più, ma preservo altri subscriber)
- Disk Space: 100GB (per dataset + modelli salvati)
- Processes: 200 (Python + worker processes + logging)
- File Descriptors: 8192
Procedura in Plesk:
- Plesk > Service Plans
- “Create a Service Plan” > Name = “AI Training Basic”
- Navigo a RAM, CPU, Disk I/O
- Configuro i limiti come sopra
- Salvo
Ho testato inizialmente con limiti più alti (4 core), ma ho notato che un cliente faceva brute-force di feature engineering e prosciugava tutto. Con 2 core + 4GB, il training è più lento, ma stabile.
Step 3: Distribuire Container AI con Docker e Limiti di Risorsa
Non sto hostando l’AI inside Plesk subscription direttamente — troppo rischioso. Invece, creo un container Docker per ogni client AI, legandolo alla subscription Plesk.
Esempio: Ollama (LLM server) con inference di Llama 2:
docker run -d --name ollama-client-alice --cpus="2" --memory="4g" --memory-swap="5g" --blkio-weight=300 -v /var/www/alice-ai:/root/.ollama -p 11434:11434 ollama/ollama:latest ollama serve
Spiegazione flags:
--cpus="2"— massimo 2 CPU core (come nel Service Plan)--memory="4g"— hard limit 4GB RAM (OOM killer interviene se superato)--memory-swap="5g"— permetto 1GB swap (non ideale per AI, ma fallback utile)--blkio-weight=300— priorizzazione I/O relativa (default 500)-v /var/www/alice-ai:/root/.ollama— bind mount directory cliente, isolata
Per training Python + PyTorch con limiti CPU/GPU:
docker run -d --name pytorch-training-bob --cpus="2.5" --memory="6g" --gpus='"device=0"' -v /var/www/bob-training:/workspace -e CUDA_VISIBLE_DEVICES=0 pytorch/pytorch:latest python train.py
Se il VPS ha una GPU (rara su VPS, ma possibile con Vultr GPU), posso allocarla tramite --gpus.
Step 4: Monitoraggio Granulare e Troubleshooting
Qui affrontiamo il primo vero problema: in Plesk c’è spesso un grande divario tra ciò che mostra il Monitoring, cosa applica cgroups, e il Process List reale. Ho dovuto sviluppare una procedura di troubleshooting.
Verificare applicazione limiti cgroups real-time:
cat /sys/fs/cgroup/system.slice/docker-CONTAINER_ID.scope/memory.max cat /sys/fs/cgroup/system.slice/docker-CONTAINER_ID.scope/cpu.max
Monitorare container dentro Plesk Obsidian:
- Vado a Plesk > Subscriptions > [cliente AI]
- Navigo a Resources tab
- Vedo utilizzo RAM, CPU, Disk — ma è aggregato e ritardato (5-min average)
- Per real-time, lancio da SSH su container:
docker stats ollama-client-alice
Ho creato uno script bash di monitoraggio custom per tracciare anomalie:
#!/bin/bash
# monitor-ai-containers.sh
echo "=== Container AI Resource Usage ==="
for container in $(docker ps --filter "label=type=ai" --format "{{.Names}}"); do
echo "Container: $container"
docker inspect $container | jq '.[] | {Memory: .HostConfig.Memory, CpuPeriod: .HostConfig.CpuPeriod, CpuQuota: .HostConfig.CpuQuota}'
docker stats $container --no-stream --format "CPU: {{.CPUPerc}} | MEM: {{.MemUsage}}"
echo "---"
done
Quando un cliente si lamenta che il training “va lento”, eseguo questo script e capisco se è davvero throttled dai limiti oppure se è il codice che è inefficiente.
Step 5: Cost Attribution e Billing per Workload AI
Il punto critico: come fatturo il cliente AI in modo equo? Non posso semplicemente dirgli “€50/mese per un container” — devo mostrare cosa ha consumato realmente.
Approccio FinOps che uso:
- Compute CPU-hour: traccia ore di utilizzo CPU medio (da cgroups) × tariffa €/CPU-hour
- Memoria peak: RAM massima allocata durante il mese × tariffa GB
- Storage training: dataset + checkpoints modello × GB-month
- I/O operazioni: IOPS consumati (discreto, da cgroups blkio)
Implemento questo tramite uno script Python + database SQLite/PostgreSQL:
# cost_attribution.py
import subprocess
import json
from datetime import datetime
def get_container_stats(container_id):
cmd = f"docker stats {container_id} --no-stream --format '{{{{json .}}}}'"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
return json.loads(result.stdout)
def calculate_hourly_cost(cpu_percent, memory_bytes, iops):
cpu_cost = (float(cpu_percent.rstrip('%')) / 100) * 2 * 0.05 # 2 CPU cores @ $0.05/CPU-hour
mem_cost = (memory_bytes / (1024**3)) * 0.01 # $0.01/GB-hour
io_cost = iops * 0.0001 # $0.0001 per 100 IOPS
return cpu_cost + mem_cost + io_cost
# Logging in database
for container in ['ollama-client-alice', 'pytorch-training-bob']:
stats = get_container_stats(container)
cost = calculate_hourly_cost(stats['CPUPerc'], int(stats['MemUsage'].split('M')[0])*1024*1024, 50)
print(f"{container}: ${cost:.4f} this hour")
Ogni ora, uno scheduler (cron o systemd timer) esegue questo script e scrive i dati in una tabella. Al fine mese, genero una fattura dettagliata per ogni cliente AI.
Struttura dati di cost attribution:
container_id— identificatore unicosubscriber_id— ID Plesk del clientetimestamp— quando è stato misuratocpu_percent— % CPU medio (da cgroups)memory_mb— memoria usataiops_read,iops_write— operazioni discocost_usd— costo imputato quella ora
Step 6: Throttling Intelligente Quando Risorse Scarseggiano
Su un VPS da 8 vCore, se due clienti lanciano training contemporaneamente, il server crolla. Ho implementato un throttling dinamico.
Script di health check e throttling:
#!/bin/bash
# throttle-ai-containers.sh
CPU_THRESHOLD=75 # se CPU > 75%, throttle
MEM_THRESHOLD=80 # se RAM > 80%, throttle
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print int($2)}')
MEM_USAGE=$(free | grep Mem | awk '{printf("%.0f", $3/$2 * 100.0)}')
if [ $CPU_USAGE -gt $CPU_THRESHOLD ]; then
echo "CPU overloaded ($CPU_USAGE%). Throttling AI containers..."
for container in $(docker ps --filter "label=type=ai" --format "{{.Names}}"); do
# Reduce CPU quota to 1 core temporarily
docker update --cpus="1" $container
done
fi
if [ $MEM_USAGE -gt $MEM_THRESHOLD ]; then
echo "Memory overloaded ($MEM_USAGE%). Killing lowest-priority container..."
docker stop $(docker ps --filter "label=priority=low" --format "{{.Names}}" | head -1)
fi
Questo script gira ogni 2 minuti via cron. Se la CPU sale oltre 75%, riduco i core allocati ai container AI da 2 a 1, dandoli priorità a WordPress/web standard.
Sfide e Soluzioni Reali che Ho Affrontato
Problema 1: MySQL/MariaDB Ottiene Priorità Bassa
MySQL/MariaDB opera come processo singolo, quindi non è possibile monitorare il consumo CPU specifico di una subscription nei tool di monitoraggio Plesk. Se un cliente AI fa heavy JOIN con il database, blocca tutti gli altri. Ho risolto con:
- Separazione database: database read-only per training, database transazionale per web
- Connection pooling: PgBouncer per limitare connessioni/query concorrenti
Problema 2: Cgroups Non Blocca in Real-Time
Cgroups non è utile per bot aggressivi o picchi improvvisi; bot moderni sopraffanno il server in pochi minuti prima che cgroups rilevino il problema. La soluzione:
- Implemento un WAF (ModSecurity in Plesk) per bloccare bot
- Rate limiting a livello nginx per subscription
- Per AI container, uso timeout stretti (30 secondi per inference) + job queue (Celery)
Problema 3: Docker vs Plesk Non Sincronizzano Limiti
Se creo un docker container con --memory="4g" ma il Service Plan Plesk dice 2GB, chi vince? Docker. Plesk non ha visibilità sui container. Ho risolto con uno script di validazione:
#!/bin/bash
# validate-limits.sh
SUBSCRIBER_ID=$1
SERVICE_PLAN=$(plesk bin subscription --info $SUBSCRIBER_ID | grep -i "plan" | awk '{print $2}')
PLAN_MEMORY=$(plesk bin service_plan --info "$SERVICE_PLAN" | grep -i "memory" | awk '{print $NF}')
CONTAINER_ID=$(docker ps -a --filter "label=subscriber=$SUBSCRIBER_ID" --format "{{.ID}}")
CONTAINER_MEMORY=$(docker inspect $CONTAINER_ID | jq -r '.[].HostConfig.Memory')
if [ "$PLAN_MEMORY" != "$CONTAINER_MEMORY" ]; then
echo "WARNING: Mismatch! Plan=$PLAN_MEMORY, Container=$CONTAINER_MEMORY"
docker update --memory="${PLAN_MEMORY}b" $CONTAINER_ID
fi
Eseguo questo script ogni notte per sincronizzare.
FAQ
Posso fare training di modelli LLM grandi (7B+ parametri) su un VPS Plesk condiviso?
Teoricamente sì, ma è rischioso. Un Llama 2 7B richiede ~14GB VRAM solo per inferenza. Su un VPS 32GB con 4-5 subscriber, non ho margine. Consiglio: usa VPS dedicato per training LLM, oppure caching + batch inference. Il costo real dei workload AI nel 2026 spesso giustifica un server separato.
Come Plesk Obsidian MCP 2.0 aiuta con AI?
Plesk MCP 2.0 permette agenti IA autonomi di gestire domini e database tramite linguaggio naturale. Per cost tracking, posso far loggare gli agenti IA tutte le operazioni (creazione container, allocation risorse), ottenendo un audit trail completo per billing.
Quale framework ML scegliere? PyTorch o TensorFlow?
PyTorch: più leggero, ideale per VPS. TensorFlow: overkill per risorse limitate. Scikit-learn + XGBoost = scelta migliore per classical ML su shared hosting. Se necessario deep learning, Ollama per inference pura (no training).
Come evitare che un cliente AI rompa il VPS di tutti gli altri?
Tre strati di difesa: (1) cgroups limits (CPU, RAM, I/O), (2) container isolation (Docker, namespace di rete), (3) throttling dinamico (script che monitora e riduce risorse se picchi). Se uno fallisce, i altri due frenano i danni.
Quale provider VPS mi consigli per AI + Plesk?
Ho testato Hetzner (buon rapporto CPU/RAM), Vultr (GPU disponibili, prezzati orariamente) e OVHcloud (server locali EU per compliance). Per un VPS 8-16 vCore + AI, budget €30-60/mese. Evito provider con SLA di rete deboli (latency >50ms danneggia inference).
Conclusione: Gestire AI su Plesk VPS Condiviso è Possibile
Nel 2026, molti mi chiedono: “Posso mettere AI training su Plesk standard?” La risposta è sì, ma con disciplina. Ho mostrato come:
- Container Docker + cgroups isolano i workload AI
- Service Plan dinamici assegnano risorse equamente
- Cost attribution scripts tracciabili fatturazione precisa
- Throttling intelligente protegge gli altri subscriber
Chiave del successo: non fidarsi solo di Plesk — aggiungere layer di container orchestration (Docker), monitoring custom (Prometheus), e accounting (database SQLite). Plesk rimane l’interfaccia di gestione, ma il vero controllo sta in scripts e automation.
Se gestite Plesk con clienti AI, comentate qui: quali problemi di resource management affrontate? Avete metodi diversi per cost attribution?