Dialogo con Gemini.
Potresti introdurre la gestione di Docker con Ubuntu 26.04 desktop.
La gestione di Docker su Ubuntu 26.04 Desktop (LTS) consente di isolare servizi, database e stack di sviluppo mantenendo pulito l’ambiente host.
1. Installazione di Docker Engine (Repository Ufficiale)
Per avere l’ultima versione del runtime Docker (dockerd), il plugin Compose e gli strumenti CLI, è consigliabile utilizzare il repository ufficiale Docker anziché i pacchetti di sistema predefiniti.
Bash
# 1. Aggiorna l'indice dei pacchetti e installa le dipendenze
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# 2. Aggiungi la chiave GPG ufficiale di Docker
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# 3. Aggiungi il repository APT
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 4. Installa Docker Engine, CLI, Containerd e Docker Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
2. Configurazione Post-Installazione (Senza sudo)
Per evitare di anteporre sudo a ogni comando docker, aggiungi il tuo utente al gruppo di sistema docker:
Bash
# Crea il gruppo docker (se non presente) e aggiungi l'utente corrente
sudo usermod -aG docker $USER
# Applica subito le modifiche al gruppo nella sessione corrente
newgrp docker
# Abilita l'avvio automatico del demone al boot
sudo systemctl enable --now docker
3. Comandi Essenziali di Gestione
| Ambito | Comando | Scopo |
|---|---|---|
| Verifica | docker run --rm hello-world | Esegue un test rapido per verificare il setup |
| Stato | docker ps -a | Mostra tutti i container (attivi e fermati) |
| Immagini | docker images | Elenca le immagini presenti localmente |
| Log | docker logs -f <nome_o_id> | Ispeziona i log in streaming di un container |
| Pulizia | docker system prune -a --volumes | Rimuove container fermati, reti e volumi non utilizzati |
4. Gestione Multi-Container con Docker Compose
Per definire servizi complessi (ad esempio un database con persistenza dati su volume dedicato), si utilizza compose.yaml:
YAML
services:
database:
image: postgres:17
container_name: local_postgres
restart: unless-stopped
environment:
POSTGRES_DB: appdb
POSTGRES_USER: devuser
POSTGRES_PASSWORD: secretpassword
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
- Avvio in background:
docker compose up -d - Arresto dei container:
docker compose down
5. Interfacce Grafiche su Ubuntu Desktop
Se preferisci una gestione visuale di container, log e volumi integrata con il desktop:
- Portainer CE: Container leggero con interfaccia web accessibile da browser.Bash
docker volume create portainer_data docker run -d -p 9000:9000 --name portainer --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data portainer/portainer-ce:latest(Accessibile poi da browser suhttp://localhost:9000) - Docker Desktop per Linux: Pacchetto
.debcon GUI dedicata e integrazione Kubernetes locale.
Come si configura NVIDIA Container Toolkit per Docker su Ubuntu Desktop per abilitare l’accelerazione GPU nei container?
Per abilitare l’accelerazione GPU hardware nei container Docker su Ubuntu Desktop, è necessario configurare NVIDIA Container Toolkit (nvidia-container-toolkit), che registra il runtime NVIDIA all’interno del demone Docker (dockerd).
1. Prerequisiti: Driver NVIDIA sull’Host
Prima di procedere, assicurati che i driver proprietari NVIDIA siano installati e funzionanti sull’host:
Bash
nvidia-smi
Se il comando restituisce la tabella con la GPU, il driver e la versione CUDA supportata, il sistema host è pronto.
2. Installazione di NVIDIA Container Toolkit
Aggiungi il repository ufficiale NVIDIA APT e installa il pacchetto del toolkit:
Bash
# 1. Aggiungi la chiave GPG ufficiale NVIDIA
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
# 2. Configura il repository APT
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
# 3. Aggiorna l'indice dei pacchetti e installa il toolkit
sudo apt update
sudo apt install -y nvidia-container-toolkit
3. Configurazione del Runtime Docker
Configura il demone Docker affinché riconosca nvidia come runtime alternativo (modificando /etc/docker/daemon.json) e riavvia il servizio:
Bash
# Configura automaticamente il runtime NVIDIA per Docker
sudo nvidia-ctk runtime configure --runtime=docker
# Riavvia il demone Docker per applicare le modifiche
sudo systemctl restart docker
4. Verifica del Funzionamento
Esegui un container di test per verificare che Docker possa dialogare direttamente con la GPU tramite il flag --gpus all:
Bash
docker run --rm --gpus all ubuntu:24.04 nvidia-smi
oppure utilizzando un’immagine CUDA ufficiale:
Bash
docker run --rm --gpus all nvidia/cuda:12.6.0-base-ubuntu24.04 nvidia-smi
5. Utilizzo con Docker Compose
Per riservare l’accesso alla GPU all’interno di un file compose.yaml, si definisce la sezione deploy.resources.reservations:
YAML
services:
llm-inference:
image: ollama/ollama:latest
container_name: local_ollama_gpu
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all # o specifica un numero (es. 1) o ID dispositivo
capabilities: [gpu]
volumes:
ollama_data:
Come si configura un container Docker con PostgreSQL e pgvector per la memorizzazione di vettori ed embedding locali?
Per configurare un container PostgreSQL con l’estensione pgvector (ideale per memorizzare embedding e calcolare distanze vettoriali come coseno, L2 o prodotto scalare per pipeline RAG), il metodo più rapido e affidabile è utilizzare l’immagine ufficiale fornita dal team di pgvector: pgvector/pgvector:pg17 (o pg16).
1. Configurazione con Docker Compose
Crea una cartella di progetto con la seguente struttura:
Plaintext
rag-database/
├── compose.yaml
└── init-db/
└── 01-init-pgvector.sql
compose.yaml
YAML
services:
vectordb:
image: pgvector/pgvector:pg17
container_name: local_pgvector
restart: unless-stopped
environment:
POSTGRES_DB: vectordb
POSTGRES_USER: raguser
POSTGRES_PASSWORD: ragpassword
ports:
- "5432:5432"
volumes:
- pgvector_data:/var/lib/postgresql/data
# Esegue automaticamente gli script SQL all'inizializzazione del database
- ./init-db:/docker-entrypoint-initdb.d:ro
volumes:
pgvector_data:
2. Script di Inizializzazione Automatica (01-init-pgvector.sql)
Qualsiasi file .sql o .sh inserito in /docker-entrypoint-initdb.d viene eseguito una sola volta, alla creazione del volume dati.
SQL
-- 1. Abilita l'estensione pgvector nel database corrente
CREATE EXTENSION IF NOT EXISTS vector;
-- 2. Esempio di tabella per documenti ed embedding (es. 768 dimensioni per modelli come nomic-embed-text o bge-base)
CREATE TABLE IF NOT EXISTS documents (
id BIGSERIAL PRIMARY KEY,
content TEXT NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb,
embedding vector(768),
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
-- 3. Indice per ricerca rapida approssimata (HNSW con distanza coseno)
CREATE INDEX IF NOT EXISTS documents_embedding_hnsw_idx
ON documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
3. Avvio e Gestione
Bash
# Avvia il container in background
docker compose up -d
# Verifica che i log confermino l'avvio corretto
docker logs -f local_pgvector
4. Test Rapido con psql
Puoi accedere alla sessione interattiva di PostgreSQL dentro il container:
Bash
docker exec -it local_pgvector psql -U raguser -d vectordb
Verifica la presenza dell’estensione e prova una query di similarità vettoriale:
SQL
-- Verifica estensioni installate
\dx
-- Inserimento di dati di test con vettori a 3 dimensioni per prova rapida
CREATE TABLE test_items (id serial PRIMARY KEY, embedding vector(3));
INSERT INTO test_items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]'), ('[1,1,1]');
-- Query di similarità (K-Nearest Neighbors con distanza Coseno: operatore <=>)
SELECT id, embedding, embedding <=> '[1,2,3]' AS cosine_distance
FROM test_items
ORDER BY cosine_distance ASC
LIMIT 2;
5. Tipologie di Indici pgvector consigliate
| Tipo Indice | Nome Operatore (Coseno) | Vantaggi | Quando Usarlo |
|---|---|---|---|
HNSW (hnsw) | vector_cosine_ops (<=>) | Massima velocità di query e recall elevato | Scelta raccomandata per la maggior parte dei sistemi RAG |
IVFFlat (ivfflat) | vector_cosine_ops (<=>) | Minor consumo di RAM, costruzione indice rapida | Grandi volumi di dati su macchine con RAM limitata |
Mostrami un esempio pratico in Python per connettersi a PostgreSQL con pgvector, inserire embedding e fare una query semantica.
Ecco un esempio pratico end-to-end in Python utilizzando il driver moderno psycopg (v3) insieme all’integrazione ufficiale pgvector-python e ollama (oppure sentence-transformers) per generare gli embedding localmente.
1. Installazione delle dipendenze
Bash
pip install psycopg[binary] pgvector ollama
(Se preferisci generare gli embedding direttamente in PyTorch/CPU senza Ollama, puoi usare pip install sentence-transformers).
2. Script Python Completo (rag_pgvector_demo.py)
Questo script:
- Registra l’adattatore vettoriale
pgvectorsulla connessionepsycopg. - Crea la tabella con supporto vettoriale.
- Genera gli embedding testuali tramite il modello locale
nomic-embed-text(dimensione 768). - Esegue l’inserimento e una ricerca semantica basata sulla distanza coseno (
<=>).
Python
import ollama
import psycopg
from pgvector.psycopg import register_vector
# Parametri di connessione al database Docker
DB_PARAMS = {
"host": "localhost",
"port": 5432,
"dbname": "vectordb",
"user": "raguser",
"password": "ragpassword",
}
EMBED_MODEL = "nomic-embed-text" # Dimensione output: 768
def get_embedding(text: str) -> list[float]:
"""Genera l'embedding di una stringa tramite Ollama."""
response = ollama.embeddings(model=EMBED_MODEL, prompt=text)
return response["embedding"]
def main():
# 1. Connessione a PostgreSQL
with psycopg.connect(**DB_PARAMS, autocommit=True) as conn:
# Abilita l'estensione nel DB e registra i tipi vettoriali in psycopg
conn.execute("CREATE EXTENSION IF NOT EXISTS vector;")
register_vector(conn)
with conn.cursor() as cur:
# 2. Creazione della tabella per i documenti
cur.execute("""
CREATE TABLE IF NOT EXISTS articles (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT NOT NULL,
embedding vector(768)
);
""")
# Svuota la tabella per la demo
cur.execute("TRUNCATE TABLE articles;")
# 3. Dati di esempio da indicizzare
dataset = [
{
"title": "Fisica Classica e Meccanica",
"content": "La dinamica newtoniana descrive il moto dei corpi macroscopici attraverso i tre principi fondamentali della dinamica e le equazioni differenziali del secondo ordine.",
},
{
"title": "Infrastrutture Docker e GPU",
"content": "NVIDIA Container Toolkit consente l'accesso diretto ai dispositivi GPU dall'interno dei container Docker per accelerare l'inferenza di modelli LLM.",
},
{
"title": "Protocolli Industriali Modbus",
"content": "La comunicazione seriale Modbus RS-485 permette lo scambio dati deterministico tra master e slave industriali tramite registri di lettura e scrittura.",
},
{
"title": "Sistemi Elettrici a Bassa Tensione e Batterie",
"content": "I banchi batteria LiFePO4 a 48V offrono elevata densità energetica e stabilità termica quando abbinati a regolatori di carica solare MPPT e inverter.",
},
]
print("Generazione embedding e inserimento nel database...")
for item in dataset:
emb = get_embedding(item["content"])
cur.execute(
"""
INSERT INTO articles (title, content, embedding)
VALUES (%s, %s, %s);
""",
(item["title"], item["content"], emb),
)
# Crea l'indice HNSW per ottimizzare le ricerche su volumi maggiori
cur.execute("""
CREATE INDEX IF NOT EXISTS articles_embedding_hnsw_idx
ON articles USING hnsw (embedding vector_cosine_ops);
""")
print("Dati memorizzati con successo.\n")
# 4. Query Semantica di Test
query_test = "Come posso collegare accumulatori al litio con impianti fotovoltaici?"
print(f"--- Esecuzione Query Semantica: \"{query_test}\" ---")
query_embedding = get_embedding(query_test)
# L'operatore <=> calcola la distanza Coseno (0.0 = identico, 2.0 = opposto)
# Similarità Coseno = 1 - Distanza Coseno
cur.execute(
"""
SELECT
id,
title,
content,
1 - (embedding <=> %s) AS cosine_similarity
FROM articles
ORDER BY embedding <=> %s ASC
LIMIT 2;
""",
(query_embedding, query_embedding),
)
results = cur.fetchall()
for doc_id, title, content, similarity in results:
print(f"\n[ID: {doc_id}] Similarità: {similarity:.4f}")
print(f"Titolo: {title}")
print(f"Contenuto: {content}")
if __name__ == "__main__":
main()
3. Alternativa con SQLAlchemy + pgvector
Se utilizzi un ORM come SQLAlchemy (v2.0), la definizione del modello e la query si integrano in modo dichiarativo:
Python
from pgvector.sqlalchemy import Vector
from sqlalchemy import BigInteger, String, Text, create_engine, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = "articles"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
title: Mapped[str] = mapped_column(String(255))
content: Mapped[str] = mapped_column(Text)
embedding = mapped_column(Vector(768))
# Connessione
engine = create_engine(
"postgresql+psycopg://raguser:ragpassword@localhost:5432/vectordb"
)
Session = sessionmaker(bind=engine)
# Query con operatore cosine_distance
with Session() as session:
query_vector = [...] # Vettore float generato
stmt = (
select(Article)
.order_by(Article.embedding.cosine_distance(query_vector))
.limit(3)
)
results = session.scalars(stmt).all()
4. Operatori di Distanza in pgvector
| Operatore SQL | Metodo SQLAlchemy | Metrica di Distanza | Utilizzo Tipico |
|---|---|---|---|
<=> | .cosine_distance() | Distanza Coseno | Modelli di Embedding standard (consigliato) |
<-> | .l2_distance() | Distanza Euclidea (L2) | Cluster geometrici / Coordinate fisiche |
<#> | .max_inner_product() | Prodotto Scalare Negativo | Vettori già normalizzati a norma unitaria |