Proxmox LXC Lifecycle Management Tool
Project description
pxrun - Proxmox LXC Lifecycle Management Tool
A CLI tool to simplify LXC container lifecycle management on remote Proxmox clusters.
Features
- Quick Container Creation: Create containers with < 6 prompts in under 60 seconds
- YAML Configuration: Save and reuse container configurations
- Secure Credentials: SOPS encryption for sensitive data
- Docker Support: Automatic Docker installation and setup
- Tailscale Integration: Built-in VPN configuration and automatic node management
- Stateless Operation: Always queries Proxmox for current state
- Smart Cleanup: Automatically detects and removes associated Tailscale nodes on container destruction
Hardware Acceleration: Support for device passthrough (Intel QSV)not yetMount Points: Easy host directory sharingnot yet
Installation
Via uv (fastest)
uv pip install pxrun
Via pip (traditional)
pip install pxrun
From source
git clone https://github.com/yourusername/pxrun.git
cd pxrun
# Using uv (recommended, 10-100x faster)
uv pip install -e .
# Or using pip
pip install -e .
Using Docker
docker pull pxrun:latest
docker run -v ~/.env:/home/pxrun/.env pxrun --help
Shell Completions
Enable command-line auto-completion for your shell:
# Bash
source <(pxrun completion bash)
# Or add to ~/.bashrc:
echo 'source <(pxrun completion bash)' >> ~/.bashrc
# Zsh
source <(pxrun completion zsh)
# Or add to ~/.zshrc:
echo 'source <(pxrun completion zsh)' >> ~/.zshrc
# Fish
pxrun completion fish | source
# Or add to config:
pxrun completion fish > ~/.config/fish/completions/pxrun.fish
Quick Start
1. Configure credentials
cp .env.example .env
# Edit .env with your Proxmox credentials
2. Create your first container
# Interactive mode
pxrun create
# From configuration file
pxrun create -f container.yaml
3. List containers
pxrun list
4. Destroy container
pxrun destroy <vmid>
# Automatically detects and removes associated Tailscale node
# Skip Tailscale node removal
pxrun destroy <vmid> --no-remove-tailscale-node
5. Manage Tailscale
# List nodes in your Tailnet
pxrun tailscale list-nodes
# Show only online nodes
pxrun tailscale list-nodes --online-only
# Output in different formats
pxrun tailscale list-nodes --format json
# Generate auth keys (requires API credentials)
pxrun tailscale generate-key
# Generate reusable key
pxrun tailscale generate-key --reusable --expires 86400
Configuration
Environment Variables
Create a .env file with your Proxmox and Tailscale credentials:
# Proxmox Configuration
PROXMOX_HOST=https://proxmox.example.com:8006
PROXMOX_TOKEN_ID=user@pve!pxrun
PROXMOX_TOKEN_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# Tailscale Configuration (optional)
TAILSCALE_API_KEY=tskey-api-xxxxx # For auth key generation & node management
TAILSCALE_TAILNET=your-org.ts.net # Your tailnet domain
TAILSCALE_AUTH_KEY=tskey-auth-xxxxx # Fallback if API not configured (often expired)
Container Configuration
Example container.yaml:
version: "1.0"
container:
hostname: dev-web-1
template: debian-13
resources:
cores: 4
memory: 2048
storage: 20
network:
ip: dhcp
mount_points:
- host: /srv/data
container: /data
provisioning:
packages:
- nginx
- git
docker: true
tailscale: true # Auto-generates auth key if API configured
# Or with options:
# tailscale:
# hostname: dev-web-1
# ephemeral: false # Persistent node (default)
Tailscale Integration
pxrun provides deep integration with Tailscale for VPN connectivity and node management.
Features
- Automatic Auth Key Generation: Generates fresh, ephemeral auth keys for each container when API credentials are configured
- Smart Key Management: Automatically detects expired keys and generates new ones
- Persistent vs Ephemeral Nodes: Configure whether nodes persist across reboots (default: persistent for containers)
- Automatic Node Detection: When destroying containers, pxrun automatically detects associated Tailscale nodes
- Smart Matching: Matches container hostnames to Tailscale nodes, including FQDN matching
- Safe Removal: Prompts for confirmation before removing nodes from your Tailnet
- Node Management: List and manage Tailscale nodes directly from pxrun
Configuration
Set the following environment variables in your .env file:
# Recommended: API credentials for automatic auth key generation
TAILSCALE_API_KEY=tskey-api-xxxxx
TAILSCALE_TAILNET=your-org.ts.net
# Optional: Fallback auth key (often expired, API is preferred)
TAILSCALE_AUTH_KEY=tskey-auth-xxxxx
With API credentials configured, pxrun will:
- Automatically generate fresh auth keys for each container
- Skip expired keys in your .env file
- Create persistent nodes by default (survive container reboots)
Usage
# Create container with Tailscale (auto-generates auth key)
pxrun create --provision tailscale
# Or from YAML with simple config
# tailscale: true # Uses auto-generated key
# List all Tailscale nodes
pxrun tailscale list-nodes
# Generate auth keys manually
pxrun tailscale generate-key
pxrun tailscale generate-key --reusable --expires 86400
# Destroy container and remove Tailscale node
pxrun destroy 100 # Prompts for Tailscale node removal
# Force destroy without prompts
pxrun destroy 100 --force
# Destroy without removing Tailscale node
pxrun destroy 100 --no-remove-tailscale-node
Development
Setup development environment
Option 1: Using Virtual Environment (Recommended for local development)
# Clone repository
git clone https://github.com/yourusername/pxrun.git
cd pxrun
# Setup virtual environment automatically
make venv
# Or manually:
./scripts/setup-venv.sh
# Activate virtual environment
source .venv/bin/activate
# Your prompt should now show (.venv)
Option 2: Using Docker (Recommended for consistent testing)
# Build test container
make docker-test-build
# Run all tests in Docker
make docker-test
# Run specific test suites
make docker-test-contract # Contract tests only
make docker-test-integration # Integration tests only
make docker-test-unit # Unit tests only
# Interactive shell in test container
make docker-test-shell
Run tests
In Virtual Environment
# Activate virtual environment first
source .venv/bin/activate
# All tests
pytest
# With coverage
pytest --cov=src --cov-report=html
# Specific test types
pytest tests/unit
pytest tests/contract
pytest tests/integration -m "not slow"
Using Docker (Isolated Environment)
# Run all tests in Docker container
make docker-test
# Or using docker compose directly
docker compose -f docker-compose.test.yml run --rm test
# Run specific test suites
docker compose -f docker-compose.test.yml run --rm test-contract
docker compose -f docker-compose.test.yml run --rm test-integration
docker compose -f docker-compose.test.yml run --rm test-unit
Code quality
# Format code
black src tests
# Lint
ruff check src tests
# Type checking
mypy src
Packaging and Distribution
Building the Package
# Build distribution packages
python -m build
# Or using the test script
./scripts/build_test.sh
Testing Package Installation
# Test in a virtual environment
python3 -m venv test_env
source test_env/bin/activate
pip install dist/*.whl
pxrun --version
deactivate
Publishing to PyPI
# Use the publish script (includes test PyPI option)
./scripts/publish.sh
# Or manually:
# 1. Build the package
python -m build
# 2. Check package quality
twine check dist/*
# 3. Upload to Test PyPI first (optional)
twine upload --repository testpypi dist/*
# 4. Upload to PyPI
twine upload dist/*
Docker Image
# Build Docker image
docker build -t pxrun:latest .
# Test the image
docker run --rm pxrun:latest --version
docker run --rm -v ~/.env:/home/pxrun/.env pxrun:latest list
# Push to registry
docker tag pxrun:latest yourusername/pxrun:latest
docker push yourusername/pxrun:latest
Documentation
Full documentation available at https://pxrun.readthedocs.io
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Requirements
- Python 3.11+
- Proxmox VE 9.x
- SSH access to at least one Proxmox node
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
Acknowledgments
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pxrun-0.1.1.tar.gz.
File metadata
- Download URL: pxrun-0.1.1.tar.gz
- Upload date:
- Size: 142.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68940807777f1dd2bcd339b13d293e8c4f44a2f12251e126879fc1a065ccb6ad
|
|
| MD5 |
58e586133cc1c0bc655e06db48cc69c6
|
|
| BLAKE2b-256 |
b43a6df6008a5319965292384a90c8548fac21b5d43c680c43ce174e8bc5854f
|
Provenance
The following attestation bundles were made for pxrun-0.1.1.tar.gz:
Publisher:
publish.yml on ironicbadger/pxrun
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pxrun-0.1.1.tar.gz -
Subject digest:
68940807777f1dd2bcd339b13d293e8c4f44a2f12251e126879fc1a065ccb6ad - Sigstore transparency entry: 567104326
- Sigstore integration time:
-
Permalink:
ironicbadger/pxrun@f016d5eefbaf015b64091ad50760d5c53e122550 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/ironicbadger
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f016d5eefbaf015b64091ad50760d5c53e122550 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pxrun-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pxrun-0.1.1-py3-none-any.whl
- Upload date:
- Size: 79.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb28c7d3df23ee86b0200dac37d15728620a4909e764b596d13e67397e7eaf2b
|
|
| MD5 |
0388f8c08f38a2711410e84759da6711
|
|
| BLAKE2b-256 |
36c25158b79693f63b3e69241d7118a9b0c64fb0cc6b836f2a10b291d0775a3c
|
Provenance
The following attestation bundles were made for pxrun-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on ironicbadger/pxrun
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pxrun-0.1.1-py3-none-any.whl -
Subject digest:
fb28c7d3df23ee86b0200dac37d15728620a4909e764b596d13e67397e7eaf2b - Sigstore transparency entry: 567104331
- Sigstore integration time:
-
Permalink:
ironicbadger/pxrun@f016d5eefbaf015b64091ad50760d5c53e122550 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/ironicbadger
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f016d5eefbaf015b64091ad50760d5c53e122550 -
Trigger Event:
release
-
Statement type: