ptctools - Portainer Client Tools
CLI for managing Portainer stacks, volume backups, and database operations.
Note: Only tested on Portainer 2.33.6
Installation
# From Git repository
uv tool install git+https://github.com/tamntlib/ptctools.git
# or
uv tool install ptctools --from git+https://github.com/tamntlib/ptctools.git
# From local path
uv tool install openapi-generator-cli==7.19.0
openapi-generator-cli generate \
-i portainer_openapi.yml \
-g python \
-o ./src/ptctools/portainer_client \
--skip-validate-spec \
--additional-properties=generateSourceCodeOnly=true
uv tool install . --no-cache --reinstall
Stack deployment status
Portainer can return a stack while deployment is still in progress. The bundled
OpenAPI schema and client recognize Active=1, Inactive=2, Deploying=3, and
Error=4 (plus the legacy unspecified value 0).
docker stack deploy reports submitted, not verified service health. A
Deploying response is accepted without retrying the deployment; requested
ownership updates still run. An Error response exits non-zero before subsequent
ownership writes. The command does not wait for deployment completion or poll
service health, so exit code zero is not a health check. Stack response environment
values are not printed.
If an older client crashes decoding a response after submission, inspect the stack and its services before retrying: the server may already have applied it.
Environment Variables
| Variable | Required | Description |
|---|---|---|
PORTAINER_URL |
Yes* | Portainer base URL (can also use -u flag) |
PORTAINER_ACCESS_TOKEN |
Yes | Portainer API key |
S3_ACCESS_KEY |
For S3 | S3 access key |
S3_SECRET_KEY |
For S3 | S3 secret key |
S3_ENDPOINT |
For S3 | S3/MinIO endpoint URL |
DUPLICATI_PASSPHRASE |
No | Backup encryption passphrase |
* Required for docker commands. Can be provided via -u flag instead.
Usage
# Set environment variables
export PORTAINER_URL=https://portainer.example.com
export PORTAINER_ACCESS_TOKEN=your-api-key
export S3_ACCESS_KEY=your-s3-key
export S3_SECRET_KEY=your-s3-secret
export S3_ENDPOINT=https://s3.<region>.amazonaws.com
# Stack deployment (Swarm-only)
ptctools docker stack deploy -n mystack -f compose.yaml
# Secret management (Swarm-only)
echo "postgresql://user:pass@db:5432/mydb" | ptctools docker secret create db_dsn
ptctools docker secret create -f /path/to/secret.txt my_secret
ptctools docker secret create -v "secret-value" my_secret
# Config management (Swarm-only)
ptctools docker config set -n my-config -d "config content"
ptctools docker config set -n nginx.conf -f ./nginx.conf
ptctools docker config set -n my-config -d "new content" --force
ptctools docker config list
ptctools docker config get -n my-config
ptctools docker config delete -n my-config
# Volume backup/restore (uses Duplicati)
ptctools docker volume backup -v vol1,vol2 -o s3://mybucket
ptctools docker volume restore -i s3://mybucket/vol1 # volume name derived from URI path
ptctools docker volume restore -v vol1 -i s3://mybucket/vol1 # explicit volume name
# Volume copy (raw copy using mc/busybox)
ptctools docker volume cp source dest # volume to volume
ptctools docker volume cp s3://mybucket/path dest # S3 to volume
ptctools docker volume cp source s3://mybucket/path # volume to S3
# Volume management
ptctools docker volume rm myvolume # remove volume (with confirmation)
ptctools docker volume rm -y myvolume # remove without confirmation
ptctools docker volume rename old_name new_name # rename volume (copy + delete)
# Database backup/restore (uses minio/mc for S3)
ptctools docker db backup -c container_id -v db_data \
--db-user postgres --db-name mydb -o backup.sql.gz
ptctools docker db backup -c container_id -v db_data \
--db-user postgres --db-name mydb -o s3://mybucket/backups/db.sql.gz
ptctools docker db restore -c container_id -v db_data \
--db-user postgres --db-name mydb -i backup.sql.gz
ptctools docker db restore -c container_id -v db_data \
--db-user postgres --db-name mydb -i s3://mybucket/backups/db.sql.gz
# Clean up exited containers and unused images
ptctools docker clean
ptctools docker clean -y # skip confirmation
# Override PORTAINER_URL with -u flag
ptctools docker secret create -u https://other.portainer.com -f dsn.txt my_secret
# Utils - local Duplicati operations (no Portainer needed)
ptctools utils backup --input ./data --output s3://backups/mydata
ptctools utils restore --input s3://backups/mydata --output ./restored
CLI Structure
ptctools
├── docker # Docker commands (via Portainer Docker proxy)
│ ├── stack deploy # Deploy/update stack (Swarm-only)
│ ├── secret create # Create Docker secret (Swarm-only)
│ ├── config set/get/list/delete # Manage configs (Swarm-only)
│ ├── volume backup/restore/cp/rm/rename
│ ├── db backup/restore
│ └── clean # Remove exited containers & unused images
├── utils backup/restore # Local Duplicati operations
└── k8s ... # Kubernetes commands (future)
Commands
ptctools docker stack deploy
Deploy or update a Docker Swarm stack in Portainer.
ptctools docker secret create
Create a Docker Swarm secret. Value can be provided via stdin, file, or command-line argument.
ptctools docker config set/get/list/delete
Manage Docker Swarm configs via Portainer API.
ptctools docker volume backup/restore
- backup: Backup multiple Docker volumes (comma-separated) to S3 using Duplicati container.
- restore: Restore a single Docker volume from S3. Volume name can be specified via
--volumeor derived from the input URI path.
ptctools docker volume cp
Copy data between volumes and S3 (raw file copy).
- volume to volume: Uses
busyboxwithcp -a - S3 to volume: Uses
minio/mcto download files - volume to S3: Uses
minio/mcto upload files
ptctools docker volume rm
Remove a Docker volume. Use -y to skip confirmation, -f to force removal.
ptctools docker volume rename
Rename a volume by copying data to a new volume and deleting the original.
ptctools docker db backup/restore
Backup/restore PostgreSQL database. Supports both local files and S3 URIs.
- Uses
pg_dump/psqlfor database operations - Uses
minio/mccontainer for S3 transfers
ptctools docker clean
Remove all exited containers and unused (dangling) images. Use -y to skip confirmation.
ptctools utils backup/restore
Local backup/restore operations using Duplicati CLI (docker or local). Does not require Portainer.
Releasing
The Release GitHub Actions workflow creates a new stable release from main.
Run it from the Actions tab and provide a canonical version in X.Y.Z format
(without leading zeroes), such as 0.2.2. The workflow:
- Requires the requested version to be greater than the current package version.
- Updates
pyproject.toml,uv.lock, andsrc/ptctools/__init__.py. - Runs the test suite and builds the wheel and source distribution.
- Commits the version change to
mainand creates an annotatedvX.Y.Ztag. - Creates a GitHub Release with generated notes and both distribution files.
- Publishes the same distribution files to PyPI through Trusted Publishing.
The workflow uses the repository GITHUB_TOKEN for GitHub and an ephemeral OIDC
token for PyPI; no additional release secret is required. The PyPI Trusted
Publisher must authorize repository tamntlib/ptctools and workflow
release.yml, with environment pypi. A failed test, invalid version, existing
tag, or distribution check stops the release before the commit and tag are
pushed.
Release files for ptctools 0.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ptctools-0.2.3.tar.gz | 651.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ptctools-0.2.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.2 MB
Release files / ptctools-0.2.3.tar.gz
| Download URL | ptctools-0.2.3.tar.gz |
|---|---|
| Size | 651.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cd64a55324db79227f7798b3b8be8f7df0dc607bb474fed7502603c9f794f4b4
|
|
BLAKE2b-256 checksum How to use checksums |
7dc8788b4dcc1a640cb879d198499c98f00483337358a4d2557b171c4363d035
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / ptctools-0.2.3-py3-none-any.whl
| Download URL | ptctools-0.2.3-py3-none-any.whl |
|---|---|
| Size | 2.5 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
670eeb5c76f276c427adcd6c62f69a3083829e145aa9f522b48a9b8312f25512
|
|
BLAKE2b-256 checksum How to use checksums |
df61449c30ea208e161e67b7ec4e6e0179af7310c059b997795a74b282bec984
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|