# portainer-cli A Ruby command-line tool for interacting with [Portainer](https://www.portainer.io/) via its REST API. List environments, stacks, containers, volumes and networks — and open fully interactive shells inside running containers directly from your terminal. > **This tool was fully generated by AI** (Claude, by Anthropic) through an iterative conversation-driven development session. ## Features - List endpoints, stacks, containers, volumes, and networks - Create stacks (from file or inline compose) and containers - **Interactive exec into containers** via WebSocket — works like `docker exec -it` but through Portainer - Smart container name resolution: fuzzy matching using Docker Compose naming conventions (`--`) - Automatic endpoint resolution — no need to look up endpoint IDs manually - Supports both API key and JWT token authentication - Configurable SSL verification (useful for self-signed certificates) - `--run CMD` flag for running a specific command (e.g. `rails c`) - `--quiet` flag for scripting and AI agent use cases ## Requirements - Ruby 3.x - [`websocket`](https://rubygems.org/gems/websocket) gem - A running Portainer instance (v2.x or later) ## Installation ```sh git clone https://github.com/grzlus/portainer-cli cd portainer-cli bundle install chmod +x bin/portainer-cli # Link into your PATH (adjust the target to wherever suits you) ln -sf "$PWD/bin/portainer-cli" ~/bin/portainer-cli ``` ## Configuration ```sh portainer-cli configure ``` You will be prompted for: - **Portainer URL** — e.g. `https://portainer.example.com` - **Authentication** — API key (recommended, no expiry) or JWT token - **SSL verification** — answer `n` if your instance uses a self-signed certificate Configuration is saved to `~/.config/portainer-cli/config.yml` (mode `0600`). ### Manual config ```yaml # ~/.config/portainer-cli/config.yml url: https://portainer.example.com api_key: ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_verify: true ``` ## Usage ### List resources ```sh portainer-cli list endpoints portainer-cli list stacks portainer-cli list containers portainer-cli list volumes portainer-cli list networks ``` ### Open an interactive shell ```sh # Resolves endpoint automatically from the stack name. # Container name defaults to the stack name, then falls back to 'app'. portainer-cli console portainer-cli console # Examples portainer-cli console myapp portainer-cli console myapp worker portainer-cli console myapp --shell /bin/bash ``` ### Run a specific command ```sh portainer-cli console myapp --run "rails c" portainer-cli console myapp --run "bundle exec rake db:migrate" ``` ### Quiet mode (scripting / AI agents) Suppresses all status output — only the container's own stdout/stderr is printed. ```sh portainer-cli console myapp --quiet --run "rails runner 'puts User.count'" ``` ### Create resources ```sh # Stack from a compose file portainer-cli create stack --endpoint 1 --name myapp --file docker-compose.yml # Stack from inline compose portainer-cli create stack --endpoint 1 --name myapp --compose "version: '3' services: web: image: nginx" # Container portainer-cli create container --endpoint 1 --image nginx:alpine --name web \ --port 8080:80 --env APP_ENV=production ``` ### Low-level exec (manual endpoint ID) ```sh portainer-cli exec portainer-cli exec --shell /bin/bash ``` ## Container name resolution When using `console`, names are resolved in this order: 1. **Exact match** — full container name or ID prefix 2. **Compose pattern** — `--` (e.g. `librarian` → `librarian-librarian-1`) 3. **Substring match** — scoped to the stack's own containers 4. **`app` fallback** — tries `-app-1` as a last resort If multiple containers match ambiguously, a list is printed and the command exits. ## Debugging ```sh portainer-cli --debug console myapp ``` Prints the WebSocket URL, auth headers, and the full HTTP upgrade handshake request/response — useful for diagnosing connection issues behind reverse proxies. ## License This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See [LICENSE](LICENSE) for the full text.