feat: méthode WebSocket HA pour Lovelace + vue lumières créée
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"registry": "https://clawhub.ai",
|
||||
"slug": "portainer",
|
||||
"installedVersion": "1.0.0",
|
||||
"installedAt": 1771773615728
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
---
|
||||
name: portainer
|
||||
description: Control Docker containers and stacks via Portainer API. List containers, start/stop/restart, view logs, and redeploy stacks from git.
|
||||
metadata: {"clawdbot":{"emoji":"🐳","requires":{"bins":["curl","jq"],"env":["PORTAINER_API_KEY"]},"primaryEnv":"PORTAINER_API_KEY"}}
|
||||
---
|
||||
|
||||
# 🐳 Portainer Skill
|
||||
|
||||
```
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🐳 P O R T A I N E R C O N T R O L C L I 🐳 ║
|
||||
║ ║
|
||||
║ Manage Docker containers via Portainer API ║
|
||||
║ Start, stop, deploy, redeploy ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
```
|
||||
|
||||
> *"Docker containers? I'll handle them from my lily pad."* 🐸
|
||||
|
||||
---
|
||||
|
||||
## 📖 What Does This Skill Do?
|
||||
|
||||
The **Portainer Skill** gives you control over your Docker infrastructure through Portainer's REST API. Manage containers, stacks, and deployments without touching the web UI.
|
||||
|
||||
**Features:**
|
||||
- 📊 **Status** — Check Portainer server status
|
||||
- 🖥️ **Endpoints** — List all Docker environments
|
||||
- 📦 **Containers** — List, start, stop, restart containers
|
||||
- 📚 **Stacks** — List and manage Docker Compose stacks
|
||||
- 🔄 **Redeploy** — Pull from git and redeploy stacks
|
||||
- 📜 **Logs** — View container logs
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Requirements
|
||||
|
||||
| What | Details |
|
||||
|------|---------|
|
||||
| **Portainer** | Version 2.x with API access |
|
||||
| **Tools** | `curl`, `jq` |
|
||||
| **Auth** | API Access Token |
|
||||
|
||||
### Setup
|
||||
|
||||
1. **Get API Token from Portainer:**
|
||||
- Log into Portainer web UI
|
||||
- Click username → My Account
|
||||
- Scroll to "Access tokens" → Add access token
|
||||
- Copy the token (you won't see it again!)
|
||||
|
||||
2. **Configure credentials:**
|
||||
```bash
|
||||
# Add to ~/.clawdbot/.env
|
||||
PORTAINER_URL=https://your-portainer-server:9443
|
||||
PORTAINER_API_KEY=ptr_your_token_here
|
||||
```
|
||||
|
||||
3. **Ready!** 🚀
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Commands
|
||||
|
||||
### `status` — Check Portainer Server
|
||||
|
||||
```bash
|
||||
./portainer.sh status
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Portainer v2.27.3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `endpoints` — List Environments
|
||||
|
||||
```bash
|
||||
./portainer.sh endpoints
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
3: portainer (local) - ✓ online
|
||||
4: production (remote) - ✓ online
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `containers` — List Containers
|
||||
|
||||
```bash
|
||||
# List containers on default endpoint (4)
|
||||
./portainer.sh containers
|
||||
|
||||
# List containers on specific endpoint
|
||||
./portainer.sh containers 3
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
steinbergerraum-web-1 running Up 2 days
|
||||
cora-web-1 running Up 6 weeks
|
||||
minecraft running Up 6 weeks (healthy)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `stacks` — List All Stacks
|
||||
|
||||
```bash
|
||||
./portainer.sh stacks
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
25: steinbergerraum - ✓ active
|
||||
33: cora - ✓ active
|
||||
35: minecraft - ✓ active
|
||||
4: pulse-website - ✗ inactive
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `stack-info` — Stack Details
|
||||
|
||||
```bash
|
||||
./portainer.sh stack-info 25
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```json
|
||||
{
|
||||
"Id": 25,
|
||||
"Name": "steinbergerraum",
|
||||
"Status": 1,
|
||||
"EndpointId": 4,
|
||||
"GitConfig": "https://github.com/user/repo",
|
||||
"UpdateDate": "2026-01-25T08:44:56Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `redeploy` — Pull & Redeploy Stack 🔄
|
||||
|
||||
```bash
|
||||
./portainer.sh redeploy 25
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
✓ Stack 'steinbergerraum' redeployed successfully
|
||||
```
|
||||
|
||||
This will:
|
||||
1. Pull latest code from git
|
||||
2. Rebuild containers if needed
|
||||
3. Restart the stack
|
||||
|
||||
---
|
||||
|
||||
### `start` / `stop` / `restart` — Container Control
|
||||
|
||||
```bash
|
||||
# Start a container
|
||||
./portainer.sh start steinbergerraum-web-1
|
||||
|
||||
# Stop a container
|
||||
./portainer.sh stop steinbergerraum-web-1
|
||||
|
||||
# Restart a container
|
||||
./portainer.sh restart steinbergerraum-web-1
|
||||
|
||||
# Specify endpoint (default: 4)
|
||||
./portainer.sh restart steinbergerraum-web-1 4
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
✓ Container 'steinbergerraum-web-1' restarted
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `logs` — View Container Logs
|
||||
|
||||
```bash
|
||||
# Last 100 lines (default)
|
||||
./portainer.sh logs steinbergerraum-web-1
|
||||
|
||||
# Last 50 lines
|
||||
./portainer.sh logs steinbergerraum-web-1 4 50
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Example Workflows
|
||||
|
||||
### 🚀 "Deploy Website Update"
|
||||
```bash
|
||||
# After merging PR
|
||||
./portainer.sh redeploy 25
|
||||
./portainer.sh logs steinbergerraum-web-1 4 20
|
||||
```
|
||||
|
||||
### 🔧 "Debug Container"
|
||||
```bash
|
||||
./portainer.sh containers
|
||||
./portainer.sh logs cora-web-1
|
||||
./portainer.sh restart cora-web-1
|
||||
```
|
||||
|
||||
### 📊 "System Overview"
|
||||
```bash
|
||||
./portainer.sh status
|
||||
./portainer.sh endpoints
|
||||
./portainer.sh containers
|
||||
./portainer.sh stacks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### ❌ "Authentication required / Repository not found"
|
||||
|
||||
**Problem:** Stack redeploy fails with git auth error
|
||||
|
||||
**Solution:** The stack needs `repositoryGitCredentialID` parameter. The script handles this automatically by reading from the existing stack config.
|
||||
|
||||
---
|
||||
|
||||
### ❌ "Container not found"
|
||||
|
||||
**Problem:** Container name doesn't match
|
||||
|
||||
**Solution:** Use exact name from `./portainer.sh containers`:
|
||||
- Include the full name: `steinbergerraum-web-1` not `steinbergerraum`
|
||||
- Names are case-sensitive
|
||||
|
||||
---
|
||||
|
||||
### ❌ "PORTAINER_URL and PORTAINER_API_KEY must be set"
|
||||
|
||||
**Problem:** Credentials not configured
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Add to ~/.clawdbot/.env
|
||||
echo "PORTAINER_URL=https://your-server:9443" >> ~/.clawdbot/.env
|
||||
echo "PORTAINER_API_KEY=ptr_your_token" >> ~/.clawdbot/.env
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Integration with Clawd
|
||||
|
||||
```
|
||||
"Redeploy the website"
|
||||
→ ./portainer.sh redeploy 25
|
||||
|
||||
"Show me running containers"
|
||||
→ ./portainer.sh containers
|
||||
|
||||
"Restart the Minecraft server"
|
||||
→ ./portainer.sh restart minecraft
|
||||
|
||||
"What stacks do we have?"
|
||||
→ ./portainer.sh stacks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📜 Changelog
|
||||
|
||||
| Version | Date | Changes |
|
||||
|---------|------|---------|
|
||||
| 1.0.0 | 2026-01-25 | Initial release |
|
||||
|
||||
---
|
||||
|
||||
## 🐸 Credits
|
||||
|
||||
```
|
||||
@..@
|
||||
(----)
|
||||
( >__< ) "Containers are just fancy lily pads
|
||||
^^ ^^ for your code to hop around!"
|
||||
```
|
||||
|
||||
**Author:** Andy Steinberger (with help from his Clawdbot Owen the Frog 🐸)
|
||||
**Powered by:** [Portainer](https://portainer.io/) API
|
||||
**Part of:** [Clawdbot](https://clawdhub.com) Skills Collection
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
**Made with 💚 for the Clawdbot Community**
|
||||
|
||||
*Ribbit!* 🐸
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"ownerId": "kn708cyzn4v97wzx09d6zz7j3s7zx1t2",
|
||||
"slug": "portainer",
|
||||
"version": "1.0.0",
|
||||
"publishedAt": 1769330831658
|
||||
}
|
||||
Executable
+185
@@ -0,0 +1,185 @@
|
||||
#!/bin/bash
|
||||
# Portainer CLI - Control Docker containers via Portainer API
|
||||
# Author: Andy Steinberger (with help from his Clawdbot Owen the Frog 🐸)
|
||||
|
||||
set -e
|
||||
|
||||
# Load config from environment or .env
|
||||
PORTAINER_URL="${PORTAINER_URL:-}"
|
||||
PORTAINER_API_KEY="${PORTAINER_API_KEY:-}"
|
||||
|
||||
# Try to load from clawdbot .env if not set
|
||||
if [[ -z "$PORTAINER_URL" || -z "$PORTAINER_API_KEY" ]]; then
|
||||
ENV_FILE="$HOME/.clawdbot/.env"
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
export $(grep -E "^PORTAINER_" "$ENV_FILE" | xargs)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$PORTAINER_URL" || -z "$PORTAINER_API_KEY" ]]; then
|
||||
echo "Error: PORTAINER_URL and PORTAINER_API_KEY must be set"
|
||||
echo "Add to ~/.clawdbot/.env or export as environment variables"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
API="$PORTAINER_URL/api"
|
||||
AUTH_HEADER="X-API-Key: $PORTAINER_API_KEY"
|
||||
|
||||
# Helper function for API calls
|
||||
api_get() {
|
||||
curl -s -H "$AUTH_HEADER" "$API$1"
|
||||
}
|
||||
|
||||
api_post() {
|
||||
curl -s -X POST -H "$AUTH_HEADER" -H "Content-Type: application/json" "$API$1" -d "$2"
|
||||
}
|
||||
|
||||
api_put() {
|
||||
curl -s -X PUT -H "$AUTH_HEADER" -H "Content-Type: application/json" "$API$1" -d "$2"
|
||||
}
|
||||
|
||||
# Commands
|
||||
case "$1" in
|
||||
status)
|
||||
api_get "/status" | jq -r '"Portainer v\(.Version)"'
|
||||
;;
|
||||
|
||||
endpoints|envs)
|
||||
api_get "/endpoints" | jq -r '.[] | "\(.Id): \(.Name) (\(.Type == 1 | if . then "local" else "remote" end)) - \(if .Status == 1 then "✓ online" else "✗ offline" end)"'
|
||||
;;
|
||||
|
||||
containers)
|
||||
ENDPOINT="${2:-4}"
|
||||
api_get "/endpoints/$ENDPOINT/docker/containers/json?all=true" | jq -r '.[] | "\(.Names[0] | ltrimstr("/"))\t\(.State)\t\(.Status)"' | column -t -s $'\t'
|
||||
;;
|
||||
|
||||
stacks)
|
||||
api_get "/stacks" | jq -r '.[] | "\(.Id): \(.Name) - \(if .Status == 1 then "✓ active" else "✗ inactive" end)"'
|
||||
;;
|
||||
|
||||
stack-info)
|
||||
STACK_ID="$2"
|
||||
if [[ -z "$STACK_ID" ]]; then
|
||||
echo "Usage: portainer.sh stack-info <stack-id>"
|
||||
exit 1
|
||||
fi
|
||||
api_get "/stacks/$STACK_ID" | jq '{Id, Name, Status, EndpointId, GitConfig: .GitConfig.URL, UpdateDate: (.UpdateDate | todate)}'
|
||||
;;
|
||||
|
||||
redeploy)
|
||||
STACK_ID="$2"
|
||||
if [[ -z "$STACK_ID" ]]; then
|
||||
echo "Usage: portainer.sh redeploy <stack-id> [endpoint-id]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get stack info for env vars and endpoint
|
||||
STACK_INFO=$(api_get "/stacks/$STACK_ID")
|
||||
ENDPOINT_ID=$(echo "$STACK_INFO" | jq -r '.EndpointId')
|
||||
ENV_VARS=$(echo "$STACK_INFO" | jq -c '.Env')
|
||||
GIT_CRED_ID=$(echo "$STACK_INFO" | jq -r '.GitConfig.Authentication.GitCredentialID // 0')
|
||||
|
||||
PAYLOAD=$(jq -n \
|
||||
--argjson env "$ENV_VARS" \
|
||||
--argjson gitCredId "$GIT_CRED_ID" \
|
||||
'{env: $env, prune: false, pullImage: true, repositoryAuthentication: true, repositoryGitCredentialID: $gitCredId}')
|
||||
|
||||
RESULT=$(api_put "/stacks/$STACK_ID/git/redeploy?endpointId=$ENDPOINT_ID" "$PAYLOAD")
|
||||
|
||||
if echo "$RESULT" | jq -e '.Id' > /dev/null 2>&1; then
|
||||
STACK_NAME=$(echo "$RESULT" | jq -r '.Name')
|
||||
echo "✓ Stack '$STACK_NAME' redeployed successfully"
|
||||
else
|
||||
echo "✗ Redeploy failed:"
|
||||
echo "$RESULT" | jq -r '.message // .details // .'
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
start)
|
||||
ENDPOINT="${3:-4}"
|
||||
CONTAINER="$2"
|
||||
if [[ -z "$CONTAINER" ]]; then
|
||||
echo "Usage: portainer.sh start <container-name> [endpoint-id]"
|
||||
exit 1
|
||||
fi
|
||||
# Get container ID
|
||||
CONTAINER_ID=$(api_get "/endpoints/$ENDPOINT/docker/containers/json?all=true" | jq -r ".[] | select(.Names[0] == \"/$CONTAINER\") | .Id")
|
||||
if [[ -z "$CONTAINER_ID" ]]; then
|
||||
echo "✗ Container '$CONTAINER' not found"
|
||||
exit 1
|
||||
fi
|
||||
api_post "/endpoints/$ENDPOINT/docker/containers/$CONTAINER_ID/start" "{}" > /dev/null
|
||||
echo "✓ Container '$CONTAINER' started"
|
||||
;;
|
||||
|
||||
stop)
|
||||
ENDPOINT="${3:-4}"
|
||||
CONTAINER="$2"
|
||||
if [[ -z "$CONTAINER" ]]; then
|
||||
echo "Usage: portainer.sh stop <container-name> [endpoint-id]"
|
||||
exit 1
|
||||
fi
|
||||
CONTAINER_ID=$(api_get "/endpoints/$ENDPOINT/docker/containers/json?all=true" | jq -r ".[] | select(.Names[0] == \"/$CONTAINER\") | .Id")
|
||||
if [[ -z "$CONTAINER_ID" ]]; then
|
||||
echo "✗ Container '$CONTAINER' not found"
|
||||
exit 1
|
||||
fi
|
||||
api_post "/endpoints/$ENDPOINT/docker/containers/$CONTAINER_ID/stop" "{}" > /dev/null
|
||||
echo "✓ Container '$CONTAINER' stopped"
|
||||
;;
|
||||
|
||||
restart)
|
||||
ENDPOINT="${3:-4}"
|
||||
CONTAINER="$2"
|
||||
if [[ -z "$CONTAINER" ]]; then
|
||||
echo "Usage: portainer.sh restart <container-name> [endpoint-id]"
|
||||
exit 1
|
||||
fi
|
||||
CONTAINER_ID=$(api_get "/endpoints/$ENDPOINT/docker/containers/json?all=true" | jq -r ".[] | select(.Names[0] == \"/$CONTAINER\") | .Id")
|
||||
if [[ -z "$CONTAINER_ID" ]]; then
|
||||
echo "✗ Container '$CONTAINER' not found"
|
||||
exit 1
|
||||
fi
|
||||
api_post "/endpoints/$ENDPOINT/docker/containers/$CONTAINER_ID/restart" "{}" > /dev/null
|
||||
echo "✓ Container '$CONTAINER' restarted"
|
||||
;;
|
||||
|
||||
logs)
|
||||
ENDPOINT="${3:-4}"
|
||||
CONTAINER="$2"
|
||||
TAIL="${4:-100}"
|
||||
if [[ -z "$CONTAINER" ]]; then
|
||||
echo "Usage: portainer.sh logs <container-name> [endpoint-id] [tail-lines]"
|
||||
exit 1
|
||||
fi
|
||||
CONTAINER_ID=$(api_get "/endpoints/$ENDPOINT/docker/containers/json?all=true" | jq -r ".[] | select(.Names[0] == \"/$CONTAINER\") | .Id")
|
||||
if [[ -z "$CONTAINER_ID" ]]; then
|
||||
echo "✗ Container '$CONTAINER' not found"
|
||||
exit 1
|
||||
fi
|
||||
curl -s -H "$AUTH_HEADER" "$API/endpoints/$ENDPOINT/docker/containers/$CONTAINER_ID/logs?stdout=true&stderr=true&tail=$TAIL" | strings
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Portainer CLI - Control Docker via Portainer API"
|
||||
echo ""
|
||||
echo "Usage: portainer.sh <command> [args]"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " status Show Portainer version"
|
||||
echo " endpoints List all environments"
|
||||
echo " containers [endpoint] List containers (default endpoint: 4)"
|
||||
echo " stacks List all stacks"
|
||||
echo " stack-info <id> Show stack details"
|
||||
echo " redeploy <stack-id> Pull and redeploy a stack"
|
||||
echo " start <container> Start a container"
|
||||
echo " stop <container> Stop a container"
|
||||
echo " restart <container> Restart a container"
|
||||
echo " logs <container> [ep] [n] Show container logs (last n lines)"
|
||||
echo ""
|
||||
echo "Environment:"
|
||||
echo " PORTAINER_URL Portainer server URL"
|
||||
echo " PORTAINER_API_KEY API access token"
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user