Skip to main content

TUI and CLI tool for managing Docker Compose service upgrades on remote servers via SSH

Project description

Python Tests Coverage Security License Version Tools TUI

Biblio Uplift

biblio-uplift

TUI and CLI tool for upgrading Docker Compose-based services on remote servers via SSH.

Install

pip install .

Quick Start

# Launch the interactive TUI
biblio-uplift

# Run an upgrade from the CLI
biblio-uplift run itops-vaultwarden

# Run non-interactively (for cron/automation)
biblio-uplift run itops-vaultwarden --non-interactive

# Dry run (simulate without executing)
biblio-uplift run itops-vaultwarden --dry-run

# Run cleanup (prune docker resources, old logs)
biblio-uplift cleanup itops-vaultwarden

# Check server status
biblio-uplift status itops-vaultwarden

# Restore from a backup
biblio-uplift restore itops-vaultwarden
biblio-uplift restore itops-vaultwarden --backup 20260501-030000

# Resume an upgrade after reboot (if session was lost)
biblio-uplift resume

# Run upgrades on all projects sequentially
biblio-uplift run-all --non-interactive

# List available backups
biblio-uplift backup list itops-vaultwarden

# Update a single service (pull repo + recreate)
biblio-uplift service-update my-project haproxy

# Check/upgrade Docker Compose install method
biblio-uplift tool run itops-vaultwarden compose-version

# List available tools
biblio-uplift tool list

# Run a tool against a project
biblio-uplift tool run itops-vaultwarden pending-security-updates

# Manage configs
biblio-uplift config edit itops-vaultwarden
biblio-uplift config validate itops-vaultwarden
biblio-uplift config create my-project --host myhost.example.com --project-dir /opt/docker/my-project
biblio-uplift config delete my-project

# View history
biblio-uplift history --last 10

Screenshots

Dashboard

Dashboard

Upgrade Pipeline

Upgrade

Tools

Tools

Configuration

Project configs live in configs/ as YAML files. Each config defines a remote server and its Docker Compose project.

# List configured projects
biblio-uplift config list

# Show a project's config
biblio-uplift config show itops-vaultwarden

Config Fields

Field Default Description
name required Project identifier
ssh_host required Remote server hostname
ssh_user ansible SSH username
ssh_key ~/.ssh/id_ed25519 Path to SSH private key (must not have a passphrase, or use ssh-agent)
sudo true Prefix remote commands with sudo
project_dir required Path to the Docker Compose project on the remote server
compose_files ["docker-compose.yml"] Compose file(s) to use
compose_profile null Compose profile. Set to hostname to use $(hostname -s) on the remote
compose_command docker compose Compose binary
backup_dir /var/backups/itops Where to store backups on the remote server (local disk, not NFS)
backup_retention 5 Number of backups to keep
volumes [] Docker volume names to back up
extra_backup_paths [] Additional paths to include in file backup
healthcheck_urls [] HTTP(S) URLs to check after startup
healthcheck_timeout 120 Seconds to wait for containers to become healthy
skip_os_update false Skip OS package updates by default
skip_reboot false Skip reboot by default
ssh_port 22 SSH port
git_branch main Git branch to pull
maintenance_window null Allowed time window for runs (e.g. "Sun 02:00-06:00")
on_failure_cmd null Shell command to run on failure (e.g. Slack webhook)
on_success_cmd null Shell command to run on success
reboot_timeout 300 Seconds to wait for SSH after reboot
apt_timeout 600 Seconds to wait for apt operations
pre_upgrade_hooks [] Shell commands to run before upgrade (executed as root via sudo)
post_upgrade_hooks [] Shell commands to run after upgrade

Hooks

Pre/post upgrade hooks are arbitrary shell commands executed on the remote server. They run as root (via sudo). Use them for things like:

pre_upgrade_hooks:
  - "systemctl stop ci-runner"
  - "/opt/scripts/notify-slack.sh 'Starting upgrade'"
post_upgrade_hooks:
  - "systemctl start ci-runner"
  - "/opt/scripts/notify-slack.sh 'Upgrade complete'"

Upgrade Pipeline

The upgrade runs these steps in order:

  1. Preflight — SSH connectivity, disk space check, backup size estimation
  2. Pre-hooks — Custom pre-upgrade commands
  3. Backup files — Tar project dir + extra paths
  4. Backup volumes — Export Docker volumes via alpine container
  5. Backup cleanup — Remove old backups beyond retention count
  6. Docker downdocker compose down
  7. Git pull — Pull latest from remote
  8. Docker pull — Pull latest images
  9. OS updateapt-get update && upgrade && autoremove --purge
  10. Reboot — Reboot and wait for SSH to come back
  11. Docker updocker compose up -d
  12. Health check — Wait for containers healthy + HTTP checks
  13. Post-hooks — Custom post-upgrade commands

On failure, completed steps are rolled back in reverse order (docker down → docker up, git pull → git checkout previous commit).

Cleanup Pipeline

  1. Preflight — SSH connectivity check
  2. Docker cleanup — Prune stopped containers, dangling images, unused volumes, build cache
  3. Log cleanup — Truncate configured log files, vacuum journald

Set aggressive_prune: true in the cleanup config to remove all unused images (not just dangling) during cleanup.

TUI

Running biblio-uplift with no command launches the interactive terminal UI. It has 8 panels:

  • Dashboard — Overview of all projects and their last run status
  • Upgrade — Run upgrades interactively with live step progress
  • Cleanup — Run cleanup pipelines with live output
  • Server Status — View remote server health (disk, memory, uptime, containers)
  • Backups — Browse and restore backups
  • Config Editor — View and edit project configurations
  • History — Browse past upgrade runs with filtering
  • Tools — Security audits, log rotation, container management tools

CLI Flags

biblio-uplift [--debug] [--version] COMMAND

Global:
  --debug              Write verbose logs to logs/debug.log
  --version            Show version and exit

run PROJECT:
  --non-interactive    Skip confirmation prompts
  --skip-reboot        Skip the reboot step
  --skip-os-update     Skip OS package updates
  --skip-backup        Skip all backup steps
  --skip-git           Skip git pull
  --dry-run            Simulate without executing
  --no-hooks           Skip pre/post hooks
  --on-failure TEXT    Shell command to run on failure (overrides config)
  --start-from TEXT    Skip steps before this one (e.g. docker_pull)

cleanup PROJECT:
  --non-interactive    Skip confirmation prompts
  --dry-run            Show what would be done

restore PROJECT:
  --backup TEXT        Backup timestamp to restore (defaults to latest)
  --non-interactive    Skip confirmation prompts

resume:
  Resume an upgrade after reboot if the controlling session was lost.
  No options.

status PROJECT:
  Show current status of a project's remote server.
  No options.

backup list PROJECT:
  List available backups for a project.
  No options.

service-update PROJECT SERVICE:
  Pull repo and recreate a single service.
  --non-interactive    Skip confirmation prompts

tool list:
  List available tools by category.

tool run PROJECT TOOL_NAME:
  --dry-run            Preview what would happen
  --non-interactive    Skip confirmation prompts

run-all:
  --non-interactive    Skip confirmation prompts
  --skip-reboot        Skip the reboot step
  --skip-os-update     Skip OS package updates
  --dry-run            Simulate without executing
  --projects TEXT      Comma-separated project names (defaults to all)

config:
  config list          List all project configurations
  config show PROJECT  Show configuration details for a project
  config create NAME   Create a new project configuration
    --host TEXT          SSH hostname (required)
    --project-dir TEXT   Remote project directory (required)
    --ssh-user TEXT      SSH username
    --ssh-key TEXT       Path to SSH key
  config edit PROJECT  Open config in $EDITOR
  config validate PROJECT
                       Validate config by testing SSH, Docker, and paths
  config delete PROJECT
                       Delete a project configuration
    --non-interactive    Skip confirmation prompts

history:
  --project TEXT       Filter by project
  --last INTEGER       Show last N entries (default: 20)

Audit History

Every run is logged to logs/history.jsonl with timestamp, project, steps, outcomes, and duration. View with:

biblio-uplift history
biblio-uplift history --project my-project --last 5

Concurrent Run Protection

A file lock (/tmp/biblio-uplift-<project>.lock) prevents multiple upgrades of the same project from running simultaneously.

Exit Codes

Code Meaning
0 Success
1 Pipeline failed or error

Cron / Unattended Use

# Weekly upgrade of vaultwarden, Sundays at 3am
0 3 * * 0 cd /path/to/biblio-uplift && biblio-uplift run itops-vaultwarden --non-interactive --on-failure "curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK -d '{\"text\": \"Vaultwarden upgrade failed\"}' " >> logs/cron.log 2>&1

For unattended runs:

  • Always use --non-interactive to skip confirmation prompts
  • Set on_failure_cmd in config or use --on-failure for failure alerts
  • Set maintenance_window in config to prevent accidental runs outside hours
  • Monitor exit codes and logs/history.jsonl for audit trail

Development

pipx install --force .
biblio-uplift --debug run itops-vaultwarden --dry-run

Set ITOPS_UPGRADE_DIR to override the project root directory detection.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

biblio_uplift-0.1.0.tar.gz (95.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

biblio_uplift-0.1.0-py3-none-any.whl (86.5 kB view details)

Uploaded Python 3

File details

Details for the file biblio_uplift-0.1.0.tar.gz.

File metadata

  • Download URL: biblio_uplift-0.1.0.tar.gz
  • Upload date:
  • Size: 95.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for biblio_uplift-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f237438fa5b3a6bf57683143269015414c23067e25bc16c4646a068f12ed5fc6
MD5 9cf76f455b5a2f3b74cba038977dcbe6
BLAKE2b-256 fc47cd20047e0fa39d2bdaa1959867afc0329274a1e2814a38b0f52bda0dafff

See more details on using hashes here.

Provenance

The following attestation bundles were made for biblio_uplift-0.1.0.tar.gz:

Publisher: publish.yml on cody-bibliocommons/biblio-uplift

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file biblio_uplift-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: biblio_uplift-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 86.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for biblio_uplift-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e36ea5a832a809d491c080f9b9f64d5ac5a74b2c24851d179880f95d83eeed0b
MD5 5720221388f0fbde1a938eaee473efb4
BLAKE2b-256 d0ada2cdf96ad78e0d277c67482ab6a01773dd55eada1843131bc60f09fe13ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for biblio_uplift-0.1.0-py3-none-any.whl:

Publisher: publish.yml on cody-bibliocommons/biblio-uplift

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page