Skip to main content

Compose Manager

Compose Manager includes a pip-installable terminal dashboard and an open-source web UI for managing Docker Compose stacks on a remote server over SSH. It discovers compose projects, shows their status and ports, and lets you bring services up, down, or inspect logs from a clean browser interface.

Terminal dashboard (Python package)

Requires Python 3.10+, the ssh executable on your local machine, and Docker Compose v2 on the remote host. The SSH user must have permission to run Docker. No Node.js, browser, or local Docker installation is required for the terminal UI.

Install from this checkout (the new Python package has not been published to PyPI):

python3 -m venv .venv
source .venv/bin/activate
pip install .
compose-manager

For development, use pip install -e '.[dev]' instead. You can also install this checkout with pipx install . if you use pipx for terminal applications.

On first launch, fill in the connection form:

  • Profile name and host: IP address, DNS name, or existing SSH alias.
  • SSH username: leave blank to use SSH defaults.
  • SSH port: leave blank to use SSH configuration (otherwise the SSH default is 22).
  • Key path: optional; leave blank to use ssh-agent or default SSH keys.
  • Project directories: comma-separated absolute remote paths, searched four levels deep.
  • Refresh interval: at least two seconds.
  • Use jump host: optional; enabling it reveals jump host, username, port, and a separate optional jump key path. Both hops must be able to authenticate.

A private IP does not automatically enable a jump host. Direct SSH works when the host is reachable through your VPN or local network. Use a jump host when that is the route needed to reach the target.

Profiles are saved to ~/.config/compose-manager/profiles.json (or under XDG_CONFIG_HOME) with file permissions 0600. Only settings and key paths are saved, never private key contents. Use Add host and Edit to manage connections. Existing ~/.ssh/config and SSH agent settings are used by OpenSSH.

Before first use, connect with normal SSH to verify and accept the host key, and load passphrase-protected keys into your agent (ssh-add /path/to/key). Background commands use batch mode: they do not prompt for passwords, passphrases, or unknown host keys. For a jump connection, verify both hosts with your normal SSH workflow. If your public key is already authorized on the server, the corresponding private key must still be available on the machine running Compose Manager or its agent.

Select a host, then select a container row with the mouse or keyboard:

Control Behavior
Up stack Runs docker compose up -d for the selected Compose file.
Stop Stops the selected service; for an empty stack row, stops the stack.
Down stack Confirms, then removes stack containers and networks; does not pass --volumes.
Restart Restarts the selected service, or the stack for an empty row.
Logs Shows the latest 100 log lines for the service or stack.
Refresh / r Rediscovers Compose files and updates container status.
Test SSH Checks SSH authentication and remote Compose availability.
Add host / n Opens a new connection form.
q Quits.

The table shows running and stopped containers, health, and published ports. Stacks without containers appear as down rows and can be brought up. Scheduled refreshes update status without repeating discovery; Refresh discovers new stacks. Command output streams into the bottom panel, and failed commands report failure. Mouse clicks require a terminal with mouse support; keyboard navigation is also available. Port-conflict analysis remains available in the existing web UI.

Python development and releases

pip install -e '.[dev]'
pytest -q
python -m build

The build produces a wheel and source distribution under dist/. The Python CI workflow tests supported Python versions and builds both artifacts.

Publish through GitHub Actions and the PyPI web UI

.github/workflows/pypi-publish.yml uses PyPI Trusted Publishing. No API token or GitHub repository secret is needed.

  1. Commit and push the package and workflows to samirkoirala/compose-manager on GitHub's main branch.

  2. In GitHub repository Settings → Environments, create an environment named pypi. You may add required reviewers if you want a release approval step.

  3. Sign in to PyPI and open Publishing. For the first release, add a pending publisher with these exact values:

    PyPI field Value
    PyPI project name compose-manager
    Owner samirkoirala
    Repository name compose-manager
    Workflow name pypi-publish.yml
    Environment name pypi

    The workflow field is the filename, not the workflow's display name or full path. If the project already belongs to your PyPI account, add the same publisher under the project's Manage → Publishing page instead.

  4. In GitHub Actions → Publish Python package to PyPI → Run workflow, select main. This publishes the current package version after tests, a build, and strict metadata validation pass. Approve the environment if reviewers were configured. The first successful upload creates the PyPI project.

  5. After publishing, users can run pip install compose-manager or pipx install compose-manager, then compose-manager.

For subsequent releases, update the version in both pyproject.toml and src/compose_manager/__init__.py, commit and push, then either run the workflow manually on main or publish a GitHub release with tag python-vX.Y.Z (for example, python-v0.1.0 for the first version). The release tag must match the package version. Re-uploading an already published version fails; increment it first. Docker's integer vN tags do not trigger Python publishing. Tests and builds run without publishing credentials; only the separate publishing job has OIDC access.

See the official PyPI Trusted Publishing setup guide and publishing guide.

Features

  • Discover docker-compose.yml, docker-compose.yaml, compose.yml, and compose.yaml files on remote servers.
  • Manage multiple VMs or a single host from one dashboard.
  • View running status, service counts, published ports, and port conflicts.
  • Start and stop stacks with streaming terminal output.
  • Inspect the last 50 log lines for any project.
  • Run as a Docker container with a simple docker compose up workflow.

Docker Hub Image

The published image name is:

samirkoirala/compose-manager

Versioning is automated by GitHub Actions:

  • Each merge to main builds and pushes a new image.
  • The workflow auto-increments the latest vN tag and publishes the next release as vN+1.
  • The same release is also pushed as latest and as a commit-specific sha-... tag.

If the repository has no prior release tags, the workflow starts from the next integer version. With the existing v1 Docker Hub tag, the next release will be v2.

Quick Start

  1. Create a .env file in the project root.
  2. Configure your SSH credentials and target server.
  3. Start the app.
docker compose up -d --build

Open http://localhost:3000 in your browser.

Configuration

All runtime configuration is loaded from .env.

Server Connection

Variable Example Description
VM_SERVERS 10.x.x.x,10.x.x.x Optional comma-separated list of VMs shown in the dropdown.
SERVER_IP 10.xx.xx.xx Fallback target server if VM_SERVERS is not set.
SERVER_SSH_PORT 22 Target SSH port.
SERVER_USERNAME ubuntu SSH username on the target server.
PORT 3000 Local web port for the app container.

Jump Host

Variable Example Description
JUMP_HOST_IP 2x.xx.xxx.x Optional jump host IP or hostname. Leave empty for direct SSH.
JUMP_HOST_USER ubuntu SSH username for the jump host.
JUMP_HOST_KEY_PATH /keys/jump.pem Optional separate private key for the jump host.
JUMP_HOST_PORT 2345 SSH port for the jump host.

Project Discovery

Variable Example Description
PROJECTS_BASE_DIRS /home/ubuntu/projects,/srv/projects Comma-separated directories searched on the remote host.

SSH Key Options

Set SSH_KEY_PATH to use a custom key path in the web container. Alternatively, mount a default key or supply key contents below. If no explicit/default key file is present, the backend can use SSH_AUTH_SOCK; using a host agent in Docker also requires mounting its socket into the container.

You can provide the SSH private key in either of these ways:

Option A: Mount a file

volumes:
  - ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro

Option B: Use an environment variable

Set SSH_PRIVATE_KEY in .env with either raw key contents or a base64-encoded key.

Local Development

docker compose up --build

The backend serves the frontend from frontend/public, so there is no separate build step for the UI.

Use the published Docker image directly

You can run the published Docker image from Docker Hub without building locally. This is useful for quick deployments or using the image inside orchestration systems.

Run with docker run (example):

docker run --rm -p 3000:3000 \
  -e SERVER_IP=10.0.0.10 \
  -e SERVER_USERNAME=ubuntu \
  -e PROJECTS_BASE_DIRS=/home/ubuntu/projects \
  -v ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro \
  samirkoirala/compose-manager:latest

Or reference it from your own docker-compose.yml:

services:
  compose-manager:
    image: samirkoirala/compose-manager:latest # or a specific tag like v2
    container_name: compose-manager
    env_file: .env
    ports:
      - "3000:3000"
    volumes:
      - ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro
    restart: unless-stopped

Notes:

  • Put your runtime variables (SSH user, server IP(s), jump host, and PROJECTS_BASE_DIRS) into the .env file referenced by env_file above.
  • If you prefer not to mount a private key, set SSH_PRIVATE_KEY in .env with the raw key contents (or base64-encoded) — the container writes it to a secure temp file at runtime.

Repository Structure

.
├── backend/
│   ├── package.json
│   └── server.js
├── frontend/
│   └── public/
│       └── index.html
├── Dockerfile
├── docker-compose.yml
├── LICENSE
└── README.md

Release Workflow

The GitHub Actions workflow in .github/workflows/docker-publish.yml is responsible for:

  • Building the Docker image.
  • Pushing the image to Docker Hub.
  • Publishing versioned tags such as v2, v3, and so on.
  • Updating latest to always point at the newest release.

To enable publishing, add these repository secrets in GitHub:

  • DOCKERHUB_USERNAME
  • DOCKERHUB_TOKEN

Contributing

Pull requests and issues are welcome. Please keep changes focused and include enough detail for maintainers to review behavior changes quickly.

License

This project is licensed under the MIT License. See LICENSE for details.

Metadata

Release files for compose-manager 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for compose-manager 0.1.0
File Size Uploaded
compose_manager-0.1.0.tar.gz 28.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for compose-manager 0.1.0
File Interpreter ABI Platform
compose_manager-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 42.2 kB

Release files / compose_manager-0.1.0.tar.gz

Download URL compose_manager-0.1.0.tar.gz
Size 28.3 kB
Tags Source
SHA-256 checksum
How to use checksums
b6b97f1b6e3f312f40f57f6630fb2cbc4caf49e2ef75e14b3923da6a9796f689
BLAKE2b-256 checksum
How to use checksums
8317f4d2acf01db6012f40caacbac166b6b99da8a6ce70553395c9b5c93cab29
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / compose_manager-0.1.0-py3-none-any.whl

Download URL compose_manager-0.1.0-py3-none-any.whl
Size 14.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
772de550e567d972a139da360161ab1fcdee8d7f5c0c405d85abab0ef5d1c432
BLAKE2b-256 checksum
How to use checksums
f9fc911886dc8e10f6e2f4468ebd0b69e0c7f64c2530ba3098aecce208314c2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page