Powerwa Management – Manuale a Tab

Powerwa Management

Manuale a schede (tab) per principianti: dal primo container fino alle API avanzate di Portainer.

Benvenuto πŸ‘‹

Ogni blocco di codice ha il tasto Copia. I placeholder (PORTAINER, LA_TUA_CHIAVE, ENDPOINT_ID, ecc.) vengono sostituiti con i valori inseriti nel tab CRUD Cookbook. Tieni premuto Ctrl/⌘ + K per cercare, G poi C per aprire il tab CRUD.

Il tema Giorno/Notte, l'ultimo tab e la configurazione vengono ricordati automaticamente.

Installare Docker (Ubuntu)

sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Test
docker version && docker compose version

Avviare Portainer

mkdir -p ~/portainer && cd ~/portainer
cat > docker-compose.yml <<'YAML'
version: '3.8'
services:
  portainer:
    image: portainer/portainer-ce:latest
    command: -H unix:///var/run/docker.sock
    ports:
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./portainer_data:/data
    restart: unless-stopped
YAML

docker compose up -d
# Apri http://IP:9000 e crea l'utenza admin

HTTPS con Caddy (consigliato)

version: '3.8'
services:
  portainer:
    image: portainer/portainer-ce:latest
    command: -H unix:///var/run/docker.sock
    expose:
      - "9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./portainer_data:/data
    restart: unless-stopped

  caddy:
    image: caddy:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy_data:/data
      - ./caddy_config:/config
    depends_on:
      - portainer
    restart: unless-stopped
# Caddyfile
portainer.tuodominio.it {
  reverse_proxy portainer:9000
  tls tuaemail@example.com
}

API Key

  1. Login in Portainer β†’ My account β†’ API keys.
  2. Genera la chiave e conservala.
  3. Autenticati sempre con header X-API-Key: LA_TUA_CHIAVE.

Operazioni veloci

Crea volume

curl -X POST -H "Content-Type: application/json" -H "X-API-Key: LA_TUA_CHIAVE" \
-d '{"Name":"mio_volume","Driver":"local"}' \
https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/volumes/create

Crea+start container

# Create
curl -X POST -H "Content-Type: application/json" -H "X-API-Key: LA_TUA_CHIAVE" \
-d '{"Image":"nginx:alpine"}' \
"https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/create?name=web"
# Start
curl -X POST -H "X-API-Key: LA_TUA_CHIAVE" \
https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/web/start

Monitoraggio

# Stats singolo container (CPU/RAM/rete)
curl -H "X-API-Key: LA_TUA_CHIAVE" \
https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/ID_CONTAINER/stats?stream=false

Sicurezza minima

  • Usa HTTPS con Caddy/Traefik o Tunnel.
  • API Key con permessi minimi (RBAC).
  • IP allow-list sul proxy verso la tua app.
  • Non esporre porte 9000/9443 direttamente su internet.

πŸ“š CRUD Cookbook – tutte le operazioni principali

Le ultime scelte vengono salvate e ripristinate. Ctrl/⌘+K per cercare i comandi.

Sezione pensata anche per soluzioni di vibe coding/no‑code: ogni blocco indica Metodo, URL, Header, Body JSON.

1) Container

Create

POST https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/create?name=NOME
Headers:
  X-API-Key: LA_TUA_CHIAVE
  Content-Type: application/json
Body:
{
  "Image": "nginx:alpine",
  "Env": [{"Name":"TZ","Value":"Europe/Rome"}],
  "HostConfig": {
    "PortBindings": {"80/tcp": [{"HostPort": "8080"}]},
    "Binds": ["mio_volume:/usr/share/nginx/html"]
  }
}
# Start
POST https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/NOME/start
Header: X-API-Key

Read

# Lista
GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/json
Header: X-API-Key

# Dettaglio
GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/ID_CONTAINER/json
Header: X-API-Key

Update

POST https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/ID_CONTAINER/update
Headers:
  X-API-Key: LA_TUA_CHIAVE
  Content-Type: application/json
Body:
{
  "Memory": 2147483648,           
  "NanoCPUs": 2000000000          
}

Delete

DELETE https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/ID_CONTAINER?force=1
Header: X-API-Key

Extra utili

# Logs (ultimi 200)
GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/ID/logs?stdout=1&stderr=1&tail=200
# Stats istantanee
GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/containers/ID/stats?stream=false
# Start/Stop/Restart
POST .../containers/ID/start
POST .../containers/ID/stop
POST .../containers/ID/restart

2) Images

Create (pull)

POST https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/images/create?fromImage=nginx&tag=alpine
Header: X-API-Key

Read

GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/images/json
Header: X-API-Key
GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/images/NAME/json
Header: X-API-Key

Delete

DELETE https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/images/NAME
Header: X-API-Key

3) Volumes

Create

POST https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/volumes/create
Headers:
  X-API-Key: LA_TUA_CHIAVE
  Content-Type: application/json
Body:
{ "Name":"mio_volume","Driver":"local" }

Read

GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/volumes
Header: X-API-Key
GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/volumes/NOME
Header: X-API-Key

Delete

DELETE https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/volumes/NOME
Header: X-API-Key

4) Network

Create

POST https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/networks/create
Headers:
  X-API-Key: LA_TUA_CHIAVE
  Content-Type: application/json
Body:
{ "Name":"mianet","Driver":"bridge" }

Read

GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/networks
Header: X-API-Key
GET https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/networks/ID
Header: X-API-Key

Update (connect/disconnect)

POST https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/networks/ID/connect
Header: X-API-Key
Body:
{ "Container":"ID_CONTAINER" }

POST https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/networks/ID/disconnect
Header: X-API-Key
Body:
{ "Container":"ID_CONTAINER" }

Delete

DELETE https://PORTAINER/api/endpoints/ENDPOINT_ID/docker/networks/ID
Header: X-API-Key

5) Stacks (Compose)

Create

POST https://PORTAINER/api/stacks?type=2&method=string&endpointId=ENDPOINT_ID
Headers:
  X-API-Key: LA_TUA_CHIAVE
  Content-Type: application/json
Body:
{
  "Name":"mystack",
  "StackFileContent":"version: \"3.8\"\nservices:\n  web:\n    image: nginx:alpine\n    ports:\n      - \"8080:80\"\n"
}

Read

GET https://PORTAINER/api/stacks
Header: X-API-Key
GET https://PORTAINER/api/stacks/STACK_ID
Header: X-API-Key

Update

PUT https://PORTAINER/api/stacks/STACK_ID
Headers:
  X-API-Key: LA_TUA_CHIAVE
  Content-Type: application/json
Body:
{ "StackFileContent":"version: \"3.8\"\nservices:\n  web:\n    image: nginx:latest\n" }

Delete

DELETE https://PORTAINER/api/stacks/STACK_ID
Header: X-API-Key

Snippet "vibe coding" (Node fetch)

// Esempio generico per blocco HTTP (Node/fetch)
const base = "https://PORTAINER/api";
const token = process.env.PORTAINER_TOKEN; // imposta la tua chiave
async function http(path, opts={}){
  const res = await fetch(base+path, {headers:{"X-API-Key":token,"Content-Type":"application/json",...(opts.headers||{})}, ...opts});
  if(!res.ok) throw new Error(await res.text());
  return res.json();
}
// Create volume
await http(`/endpoints/${ENDPOINT_ID}/docker/volumes/create`, {method:'POST', body: JSON.stringify({Name:'mio_volume'})});
// List containers
const containers = await http(`/endpoints/${ENDPOINT_ID}/docker/containers/json`);
Nei tool no/low‑code imposta X-API-Key come header fisso nel connettore; poi riusa gli endpoint variando solo path e body.
Copiato negli appunti βœ“