Skip to main content

Promenade

A local development process manager with a web UI. Run all your services with one command and see their status, logs, and health in a unified dashboard.

Promenade web UI

Installation

pip install promenade

Quick Start

  1. Create a promenade.yaml in your project root:
services:
  api:
    command: flask run --port 5001
    directory: ./backend
    port: 5001
    ready_check:
      type: http
      path: /health

  frontend:
    command: npm run dev
    directory: ./frontend
    port: 3000
    depends_on:
      - api
  1. Start everything:
promenade start
  1. Open http://localhost:7766 to see the web UI.

Features

  • Process supervision - Start, stop, and restart services with automatic dependency ordering
  • Health checks - HTTP and TCP health checks with configurable timeouts
  • Log aggregation - Unified log viewer with per-service filtering
  • Web UI - Real-time dashboard showing service status, health, and logs
  • Hot reload - Automatically detects config changes and restarts affected services
  • Restart policies - Configure never, once, or always restart behavior

CLI Commands

promenade start              # Start all services (with web UI on port 7766)
promenade start --no-ui      # Start services without the web UI
promenade start --daemon     # Run in background
promenade stop               # Stop all services
promenade status             # Show service status
promenade restart [service]  # Restart a service (or all if no name given)
promenade logs [service]     # View logs
promenade logs -f            # Follow logs in real-time
promenade reload             # Reload config and restart changed services
promenade config check       # Validate your config file

Configuration

Promenade looks for config in this order:

  1. --config flag
  2. ./promenade.yaml
  3. ~/.config/promenade/promenade.yaml

Full Example

manager:
  port: 7766
  host: 127.0.0.1
  log_buffer_lines: 1000

defaults:
  restart_policy: once
  env:
    NODE_ENV: development

services:
  api:
    command: flask run --port 5001
    directory: ./backend
    port: 5001
    env:
      FLASK_DEBUG: "1"
    ready_check:
      type: http
      path: /health
      timeout: 30
      interval: 2

  frontend:
    command: npm run dev
    directory: ./frontend
    port: 3000
    depends_on:
      - api
    ready_check:
      type: tcp
      timeout: 30

  worker:
    command: python worker.py
    directory: ./backend
    restart_policy: always

Service Options

Option Description
command Command to run (required)
directory Working directory
port Port the service listens on
env Environment variables
env_file Path to .env file
depends_on Services that must start first
restart_policy never, once, or always
ready_check Health check configuration

Health Checks

ready_check:
  type: http          # or "tcp"
  path: /health       # HTTP only
  timeout: 30         # Seconds to wait for healthy
  interval: 2         # Seconds between checks

Running as a Daemon

For services you always want running, you can set up promenade to start automatically on login.

macOS (launchd)

Create ~/Library/LaunchAgents/com.promenade.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.promenade</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/promenade</string>
        <string>start</string>
        <string>--no-ui</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/tmp/promenade.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/promenade.log</string>
</dict>
</plist>

Then load it:

launchctl load ~/Library/LaunchAgents/com.promenade.plist

Find the path to promenade with which promenade.

Linux (systemd)

Create ~/.config/systemd/user/promenade.service:

[Unit]
Description=Promenade Dev Services

[Service]
ExecStart=/path/to/promenade start --no-ui
Restart=always

[Install]
WantedBy=default.target

Then enable it:

systemctl --user enable --now promenade

REST API

The manager exposes a REST API at the same port as the web UI:

  • GET /api/status - All services status
  • GET /api/services/{name} - Single service status
  • POST /api/services/{name}/start - Start a service
  • POST /api/services/{name}/stop - Stop a service
  • POST /api/services/{name}/restart - Restart a service
  • GET /api/services/{name}/logs - Get service logs
  • POST /api/reload - Reload configuration
  • WS /api/logs/stream - WebSocket for real-time logs

License

MIT

Metadata

Release files for promenade 0.1.1

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

Source distribution (sdist)

Source distribution for promenade 0.1.1
File Size Uploaded Provenance Actions
promenade-0.1.1.tar.gz 152.8 kB Without provenance Details for promenade-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for promenade 0.1.1
File Interpreter ABI Platform Actions
promenade-0.1.1-py3-none-any.whl Python 3 none any Details for promenade-0.1.1-py3-none-any.whl

Total release size: 227.6 kB

Release files / promenade-0.1.1.tar.gz

Download URL promenade-0.1.1.tar.gz
Size 152.8 kB
Tags Source
SHA-256 checksum
How to use checksums
bccd9056ec5702ce76fd9a4848096ae72492e147903ee54381724a98b5eb1ff6
BLAKE2b-256 checksum
How to use checksums
36e3e773f058444aa50fc8453ef8aa1a777136c2ad15c6fa3e5bb60310b6abbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.3

Release files / promenade-0.1.1-py3-none-any.whl

Download URL promenade-0.1.1-py3-none-any.whl
Size 74.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
491eebe70f75f11e2bcd0631276121687f8d298e50e5cbfcc0a6ed757f2f03c4
BLAKE2b-256 checksum
How to use checksums
a46a2a12a17f6c3f66b148ddaf03012fbc79157268fa0e7e5dd60c03a1125547
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.3

Security for promenade 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

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