process-compose Documentation

Process Compose is a simple and flexible scheduler and orchestrator to manage non-containerized applications.

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy process-compose on any server, homelab, or cloud container platform.

Technical Documentation: F1bonacc1/process-compose

โ„น๏ธ Provenance: Hybrid Fusion: F1bonacc1/process-compose + F1bonacc1/F1bonacc1.github.io ยท CodeWiki Reference ยท Recency: Active (< 180 days)

1. Project Overview & Quickstart (F1bonacc1/process-compose)

Process Compose

Process Compose is a simple and flexible scheduler and orchestrator to manage non-containerized applications.

Why? Because sometimes you just don't want to deal with docker files, volume definitions, networks and docker registries.
Since it's written in Go, Process Compose is a single binary file and has no other dependencies.

Once installed, you just need to describe your workflow using a simple YAML schema in a file called process-compose.yaml:

yaml
version: "0.5"

processes:
  hello:
    command: echo 'Hello World'
  pc:
    command: echo 'From Process Compose'
    depends_on:
      hello:
        condition: process_completed

And start it by running process-compose from your terminal.

Check the Documentation for more advanced use cases.

Features

  • Processes execution (in parallel or/and serially)
  • Processes dependencies and startup order
  • Process recovery policies
  • Manual process [re]start
  • Processes arguments bash or zsh style (or define your own shell)
  • Per process and global environment variables using envsubst
  • Per process or global (single file) logs
  • Health checks (liveness and readiness)
  • Terminal User Interface (TUI) or CLI modes
  • Forking (services or daemons) processes
  • REST API (OpenAPI a.k.a Swagger) with optional token authentication PC_API_TOKEN
  • Logs caching
  • Functions as both server and client
  • Configurable shortcuts
  • Merge Configuration Files
  • Namespaces
  • Namespace Operations (Start, Stop, Restart via CLI and TUI)
  • Run Multiple Replicas of a Process
  • Run a Foreground Process
  • Interactive Process
  • Themes Support
  • On the fly Process configuration edit
  • On the fly Project update
  • Recipes Management
  • Scheduled Processes (cron and interval-based)
  • File Watching - restart a process when its files change, optionally cascading to its dependents
  • Dependency Graph visualization (CLI, TUI, and API)
  • MCP Server integration for AI assistants โ€” expose processes as tools/resources and (optionally) the project's own control plane (start/stop/scale/list/logs)
  • Process Monitor (Push Notifications)

Get Process Compose

Installation Instructions

Documentation

Quick Start

Documentation

Video Series

Process Compose Intro is a ten part course, about 45 minutes in total. It goes from a first config through dependencies, health checks, restart policies, the TUI, templating, namespaces, the REST API and CI pipelines. Every episode has chapter markers.

How to Contribute

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

See the Contributing page for more details.

English is not my native language, so PRs correcting grammar or spelling are welcome and appreciated.

Consider supporting the project โค๏ธ

Github (preferred)

https://github.com/sponsors/F1bonacc1

Huge thanks to my amazing GitHub sponsors:

Bitcoin

3QjRfBzwQASQfypATTwa6gxwUB65CX1jfX

Thank You!

2. Official Technical Reference & Guides (F1bonacc1/F1bonacc1.github.io)

File: docs/client.md

Remote Client

REST API

Open API client and documentation is available on: http://localhost:8080

Default port is 8080. Specify your own port:

shell
process-compose -p 8080

Alternatively use PC_PORT_NUM environment variable:

shell
PC_PORT_NUM=8080 process-compose

Client Mode

Process compose can also connect to itself as a client. Available commands:

Processes List

shell
process-compose process list #lists available processes

Process Start

shell
process-compose process start [PROCESS] #starts one of the available non running processes

Process Stop

shell
process-compose process stop [PROCESS] #stops one of the running processes

Process Restart

shell
process-compose process restart [PROCESS] #restarts one of the available processes

Restart will wait process.availability.backoff_seconds seconds between stop and start of the process. If not configured the default value is 1s.

:bulb: New remote commands are added constatntly. For full list run:

shell
process-compose --help

By default, the client will try to use the default port 8080 and default address localhost to connect to the locally running instance of process-compose. You can provide deferent values:

shell
process-compose -p PORT process -a ADDRESS list

TUI Client

For situations when process-compose was started in headless mode -t=false, another process-compose instance (client) can run in a fully remote TUI mode:

bash
process-compose attach

The client can connect to a:

  • Remote server
  • Docker container
  • Headless and TUI process-compose instances

In remote mode the Process Compose logo will be replaced from ๐Ÿ”ฅ to โšกand show a remote server hostname instead of a local hostname.


File: docs/configuration.md

Configuration

Environment Variables

Per Process

yaml
process2:
  environment:
    - "I_AM_LOCAL_EV=42"

Global

yaml
environment:
  - "I_AM_GLOBAL_EV=42"
processes:
  process2:
    command: "chmod 666 /path/to/file"
  environment:
    - "I_AM_LOCAL_EV=42"

Default environment variables:

PC_PROC_NAME - Defines the process name as defined in the process-compose.yaml file.

PC_REPLICA_NUM - Defines the process replica number. Useful for port collision avoidance for processes with multiple replicas.

.env file

.env
VERSION='1.2.3'
DB_USER='USERNAME'
DB_PASSWORD='VERY_STRONG_PASSWORD'
WAIT_SEC=60

Override ${var} and $var from environment variables or .env values

yaml hl_lines="3 6"
processes:
  downloader:
    command: "python3 data_downloader_${VERSION}.py -s 'data.source.B.uri'"
    availability:
      restart: "always"
      backoff_seconds: ${WAIT_SEC}
    environment:
      - 'OUTPUT_DIR=/path/to/B/data'

Specify which configuration files to use

shell
process-compose -f "path/to/process-compose-file.yaml"

Auto discover configuration files

The following discovery order is used: compose.yml, compose.yaml, process-compose.yml, process-compose.yaml. If multiple files are present the first one will be used.

Merge 2 or more configuration files with override values

shell
process-compose -f "path/to/process-compose-file.yaml" -f "path/to/process-compose-override-file.yaml"

Using multiple process-compose files lets you customize a process-compose application for different environments or different workflows.

See the Merging Configuration for more information on merging files.

Backend

For cases where your process compose requires a non default or transferable backend definition, setting an environment variable won't do. For that, you can configure it directly in the process-compose.yaml file:

yaml
version: "0.5"
shell:
  shell_command: "python3"
  shell_argument: "-m"
processes:
  http:
    command: "server.py"

Note: please make sure that the shell.shell_command value is in your $PATH

Linux

The default backend is bash. You can define a different backend with a COMPOSE_SHELL environment variable.

Windows

The default backend is cmd. You can define a different backend with a COMPOSE_SHELL environment variable.

yaml
process1:
  command: "python -c print(str(40+2))"
  #note that the same command for bash/zsh would look like: "python -c 'print(str(40+2))'"

Using powershell backend had some funky behavior (like missing command1 && command2 functionality in older versions). If you need to run powershell scripts, use the following syntax:

yaml
process2:
  command: "powershell.exe ./test.ps1 arg1 arg2 argN"

macOS

The default backend is bash. You can define a different backend with a COMPOSE_SHELL environment variable.

Namespaces

Assigning namespaces to processes allows better grouping and sorting, especially in TUI:

yaml
processes:
  process1:
    command: "tail -f -n100 process-compose-${USER}.log"
    working_dir: "/tmp"
    namespace: debug # if not defined 'default' namespace is automatically assigned to each process

Note: By default process-compose will start process from all the configured namespaces. To start a sub set of the configured namespaces (ns1, ns2, ns3):

shell
process-compose -n ns1 -n ns3
# will start only ns1 and ns3. ns2 namespace won't run and won't be visible in the TUI

Misc

Strict Configuration Validation

To avoid minor proces-compose.yaml configuration errors and typos it is recommended to enable is_strict flag:

yaml hl_lines="2 5"
version: "0.5"
is_strict: true
processes:
  process1:
   commnad: "sleep 1" # <-- notice the typo here

The above configuration will fail the Process Compose start and exit with error code 1:

shell
unknown key commnad found in process process1

File: docs/health.md

Health Checks

Many applications running for long periods of time eventually transition to broken states, and cannot recover except by being restarted. Process Compose provides liveness and readiness probes to detect and remedy such situations.

Probes configuration and functionality are designed to work similarly to Kubernetes liveness and readiness probes.

Liveness Probe

yaml
processes:
  nginx:
    command: "docker run -d --rm -p80:80 --name nginx_test nginx"
    is_daemon: true
    shutdown:
      command: "docker stop nginx_test"
      signal: 15
      timeout_seconds: 5
    liveness_probe:
      exec:
        command: "[ $(docker inspect -f '{{.State.Running}}' nginx_test) = 'true' ]"
        working_dir: /tmp # if not specified the process working dir will be used
      initial_delay_seconds: 5
      period_seconds: 2
      timeout_seconds: 5
      success_threshold: 1
      failure_threshold: 3

Readiness Probe

yaml
processes:
  nginx:
    command: "docker run -d --rm -p80:80 --name nginx_test nginx"
    is_daemon: true
    shutdown:
      command: "docker stop nginx_test"
    readiness_probe:
      http_get:
        host: 127.0.0.1
        scheme: http
        path: "/"
        port: 80
      initial_delay_seconds: 5
      period_seconds: 10
      timeout_seconds: 5
      success_threshold: 1
      failure_threshold: 3

Each probe type (liveness_probe or readiness_probe) can be configured to use one of the 2 mutually exclusive modes:

  1. exec: Will run a configured command and based on the exit code decide if the process is in a correct state. 0 indicates success. Any other value indicates failure.
  2. http_get: For an HTTP probe, the Process Compose sends an HTTP request to the specified path and port to perform the check. Response code 200 indicates success. Any other value indicates failure.
    • host: Host name to connect to.
    • scheme: Scheme to use for connecting to the host (HTTP or HTTPS). Defaults to HTTP.
    • path: Path to access on the HTTP server. Defaults to /.
    • port: Number of port to access the process. The number must be in the range 1 to 65535.

Configure Probes

Probes have a number of fields that you can use to control the behavior of liveness and readiness checks more precisely:

  • initial_delay_seconds: Number of seconds after the container has started before liveness or readiness probes are initiated. Defaults to 0 seconds. The minimum value is 0.
  • period_seconds: How often (in seconds) to perform the probe. Defaults to 10 seconds. The minimum value is 1.
  • timeout_seconds: Number of seconds after which the probe times out. Defaults to 1 second. The minimum value is 1.
  • success_threshold: Minimum consecutive successes for the probe to be considered successful after failing. Defaults to 1. Must be 1 for liveness and startup Probes. The minimum value is 1. Note: this value is not respected and was added as a placeholder for future implementation.
  • failure_threshold: When a probe fails, Process Compose will try failure_threshold times before giving up. Giving up in case of liveness probe means restarting the process. In case of readiness probe, the Pod will be marked Unready. Defaults to 3. The minimum value is 1.

Auto Restart if not Healthy

In order to ensure that the process is restarted (and not transitioned to a completed state) in case of readiness check fail, please make sure to define the availability configuration. For background (is_daemon=true) processes, the restart policy should be always.


File: docs/index.md

Process Compose ๐Ÿ”ฅ

Process Compose is a simple and flexible scheduler and orchestrator to manage non-containerized applications.

Why was it made?

Because sometimes you just don't want to deal with docker files, volume definitions, networks and docker registries.

Features

  • Processes execution (in parallel or/and serially)
  • Processes dependencies and startup order
  • Process recovery policies
  • Manual process [re]start
  • Processes arguments bash or zsh style (or define your own shell)
  • Per process and global environment variables
  • Per process or global (single file) logs
  • Health checks (liveness and readiness)
  • Terminal User Interface (TUI) or CLI modes
  • Forking (services or daemons) processes
  • REST API (OpenAPI a.k.a Swagger)
  • Logs caching
  • Functions as both server and client
  • Configurable shortcuts
  • Merge Configuration Files
  • Namespaces
  • Run Multiple Replicas of a Process

File: docs/installation.md

Installation

Download the Binary

Go to the releases, download the package for your OS, and copy the binary to somewhere on your PATH.

Nix

If you have the Nix package manager installed with Flake support, just run:

sh
# to use the latest binary release
nix run nixpkgs/master#process-compose -- --help

# or to compile from the latest source
nix run github:F1bonacc1/process-compose -- --help

To use process-compose declaratively configured in your project flake.nix, checkout process-compose-flake.

Brew (MacOS and Linux)

shell
brew install f1bonacc1/tap/process-compose

File: docs/intro.md

Getting Started

Quick Start

Imaginary system diagram:

process-compose.yaml definitions for the system above:

yaml
version: "0.5"

environment:
  - "GLOBAL_ENV_VAR=1"
log_location: /path/to/combined/output/logfile.log
log_level: debug

processes:
  Manager:
    command: "/path/to/manager"
    availability:
      restart: "always"
    depends_on:
      ClientA:
        condition: process_started
      ClientB:
        condition: process_started

  ClientA:
    command: "/path/to/ClientA"
    availability:
      restart: "always"
    depends_on:
      Server_1A:
        condition: process_started
      Server_2A:
        condition: process_started
    environment:
      - "LOCAL_ENV_VAR=1"

  ClientB:
    command: "/path/to/ClientB -some -arg"
    availability:
      restart: "always"
    depends_on:
      Server_1B:
        condition: process_started
      Server_2B:
        condition: process_started
    environment:
      - "LOCAL_ENV_VAR=2"

  Server_1A:
    command: "/path/to/Server_1A"
    availability:
      restart: "always"

  Server_2A:
    command: "/path/to/Server_2A"
    availability:
      restart: "always"

  Server_1B:
    command: "/path/to/Server_1B"
    availability:
      restart: "always"

  Server_2B:
    command: "/path/to/Server_2B"
    availability:
      restart: "always"

Finally, run process-compose in the process-compose.yaml directory. Or give it a direct path:

shell
process-compose -f /path/to/process-compose.yaml

File: docs/launcher.md

Processes Lifetime

Start in Parallel

yaml
processes:
  process1:
    command: "sleep 3"
  process2:
    command: "sleep 3"

Start Serially

yaml
processes:
  process1:
    command: "sleep 3"
    depends_on:
      process2:
        condition: process_completed_successfully # or "process_completed" if you don't care about errors
  process2:
    command: "sleep 3"
    depends_on:
      process3:
        condition: process_completed_successfully # or "process_completed" if you don't care about errors

Multiple Replicas of a Process

You can run multiple replicas of a process by adding processes.process_name.replicas parameter (default: 1)

yaml
processes:
  process_name:
    command: "sleep 2"
    log_location: ./log_file.{PC_REPLICA_NUM}.log  # <- {PC_REPLICA_NUM} will be replaced with replica number. If more than one replica and PC_REPLICA_NUM is not specified, the replica number will be concatenated to the file end.
    replicas: 2

To scale a process on the fly CLI:

shell
process-compose process scale process_name 3

To scale a process on the fly TUI: F2 or Process Compose in client mode (process-compose attach).

:bulb: Starting multiple processes using the same port, will fail. Please use the injected PC_REPLICA_NUM environment variable to increment the used port number.

Specify a working directory

yaml
processes:
  process1:
    command: "ls -laF --color=always"
    working_dir: "/path/to/your/working/directory"

Make sure that you have the proper access permissions to the specified working_dir. If not, the command will fail with a permission denied error. The process status in TUI will be Error.

Define process dependencies

yaml
processes:
  process2:
    depends_on:
      process3:
        condition: process_completed_successfully
      process4:
        condition: process_completed_successfully

There are 4 condition types that can be used in process dependencies:

  • process_completed - is the type for waiting until a process has been completed (any exit code)
  • process_completed_successfully - is the type for waiting until a process has been completed successfully (exit code 0)
  • process_healthy - is the type for waiting until a process is healthy
  • process_started - is the type for waiting until a process has started (default)

Run only specific processes

For testing and debugging purposes, especially when your process-compose.yaml file contains many processes, you might want to specify only a subset of processes to run. For example:

yaml
#process-compose.yaml
processes:
  process1:
    command: "echo 'Hi from Process1'"
    depends_on:
      process2:
        condition: process_completed_successfully
  process2:
    command: "echo 'Hi from Process2'"
  process3:
    command: "echo 'Hi from Process3'"
bash
process-compose up # will run all the processes - equal to 'process-compose'

#output:
#Hi from Process3
#Hi from Process2
#Hi from Process1
bash
process-compose up process1 process3 # will run 'process1', 'process3' and all of their dependencies - 'process2'

#output:
#Hi from Process3
#Hi from Process2
#Hi from Process1
bash
process-compose up process1 process3 --no-deps # will run 'process1', 'process3' without any dependencies

#output:
#Hi from Process3
#Hi from Process1

Termination Parameters

yaml
processes:
  nginx:
    command: "docker run --rm --name nginx_test nginx"
    shutdown:
      command: "docker stop nginx_test"
      timeout_seconds: 10 # default 10
      signal: 15 # default 15, but only if the 'command' is not defined or empty
      parent_only: no  # default no. If yes, only signal the running process instead of its whole process group

shutdown is optional and can be omitted. The default behavior in this case: SIGTERM is issued to the process group of the running process.

In case only shutdown.signal is defined [1..31] the running process group will be terminated with its value.

If shutdown.parent_only is yes, the signal is only sent to the running process and not to the whole process group.

In case the shutdown.command is defined:

  1. The shutdown.command is executed with all the Environment Variables of the primary process
  2. Wait for shutdown.timeout_seconds for its completion (if not defined wait for 10 seconds)
  3. In case of timeout, the process group will receive the SIGKILL signal (irrespective of the shutdown.parent_only option).

Background (detached) Processes

yaml hl_lines="4"
processes:
  nginx:
    command: "docker run -d --rm --name nginx_test nginx" # note the '-d' for detached mode
    is_daemon: true # this flag is required for background processes (default false)
    shutdown:
      command: "docker stop nginx_test"
      timeout_seconds: 10 # default 10
      signal: 15 # default 15, but only if command is not defined or empty
  1. For processes that start services / daemons in the background, please use the is_daemon flag set to true.

  2. In case a process is daemon it will be considered running until stopped.

  3. Daemon processes can only be stopped with the $PROCESSNAME.shutdown.command as in the example above.

Disabled Processes

Process execution can be disabled:

yaml hl_lines="4"
processes:
  process_name:
    command: "ls -R /"
    disabled: true #default false

Even if disabled, it is still listed in the TUI and the REST client can be started manually when needed.

Auto Restart on Exit

yaml hl_lines="4"
processes:
  process2:
    availability:
      restart: on_failure # other options: "exit_on_failure", "always", "no" (default)
      backoff_seconds: 2 # default: 1
      max_restarts: 5 # default: 0 (unlimited)

Terminate Process Compose on Failure

There are cases when you might want process-compose to terminate immediately when one of the processes exits with a non 0 exit code. This can be useful when you would like to perform "pre-flight" validation checks on the environment.

To achieve that, use exit_on_failure restart policy. If defined, process-compose will gracefully shut down all the other running processes and exit with the same exit code as the failed process.

yaml hl_lines="5"
processes:
  sanitycheck:
    command: "which go"
    availability:
      restart: "exit_on_failure"

  other_proc:
    command: "go test ./..."
    depends_on:
      sanitycheck:
        condition: process_completed_successfuly

Terminate Process Compose once given process ends

There are cases when you might want process-compose to terminate immediately when one of the processes exits (regardless of the exit code). For example when running tests that depend on other processes like databases etc. You might want the processes, on which the test process depends, to start first, then run the tests, and finally terminate all processes once the test process exits, reporting the code returned by the test process.

To achieve that, set availability.exit_on_end to true, and process-compose will gracefully shut down all the other running processes and exit with the same exit code as the given process.

yaml hl_lines="7"
processes:
  tests:
    command: tests-run
    availability:
      # NOTE: `restart: exit_on_failure` is not needed since
      # exit_on_end implies it.
      exit_on_end: true
    depends_on:
      redis: process_healthy
      postgres: process_healthy

  redis:
    command: redis-start
    readiness_probe:
      exec:
        command: redis-health-check

  postgres:
    command: postgres-start
    readiness_probe:
      exec:
        command: postgres-health-check

:bulb:
setting restart: exit_on_failure together with exit_on_end: true is not needed as the latter causes termination regardless of the exit code. However, it might be sometimes useful to exit_on_end with restart: on_failure and max_restarts in case you want the process to recover from failure and only cause termination on success.

:bulb:
exit_on_end can be set on more than one process, for example when running multiple tasks in parallel and wishing to terminate as soon as any one finished.


File: docs/logging.md

Logger

Per Process Log Collection

yaml
process2:
  log_location: ./pc.process2.log #if undefined or empty no logs will be saved

Captures StdOut and StdErr output

Merge into a single file (Unified Logging)

yaml
environment:
  - "ABC=42"
log_location: ./pc.global.log #if undefined or empty, no logs will be saved (if not defined per process)
processes:
  process2:
    command: "chmod 666 /path/to/file"

Process compose console log level

yaml
log_level: info # other options: "trace", "debug", "info", "warn", "error", "fatal", "panic"
processes:
  process2:
    command: "chmod 666 /path/to/file"

This setting controls the process-compose log level. The processes log level should be defined inside the process. It is recommended to support this definition with an environment variable in process-compose.yaml

Log Rotation

yaml
# unified log
version: "0.5"
log_level: info 
log_location: /tmp/pc.log
log_configuration:
  rotation:
    max_size_mb: 1  # the max size in MB of the logfile before it's rolled
    max_age_days: 3 # the max age in days to keep a logfile
    max_backups: 3  # the max number of rolled files to keep
    compress: true  # determines if the rotated log files should be compressed using gzip. The default is false

#process level logging (same syntax)
processes:
  someProc:
    command: "some command"
    log_configuration:
      rotation:
        max_size_mb: 1  # the max size in MB of the logfile before it's rolled
        max_age_days: 3 # the max age in days to keep a logfile
        max_backups: 3  # the max number of rolled files to keep
        compress: true  # determines if the rotated log files should be compressed using gzip. The default is false

Logger Configuration

yaml
log_configuration:
  fields_order: ["time", "level", "message"] # order of logging fields. The default is time, level, message
  disable_json: true                         # output as plain text. The default is false
  timestamp_format: "06-01-02 15:04:05.000"  # timestamp format. The default is RFC3339
  no_metadata: true                          # don't log process name and replica number
  add_timestamp: true                        # add timestamp to the logger. Default is false
  no_color: true	                         # disable ANSII colors in the logger. Default is false
Parameter Name Description Depends On Default Value
fields_order Order of the logging fields. The default is time, level, message. In case one of the fields is omitted, it will be missing in the log as well. disable_json: true``add_timestamp: true for "time" ["time", "level", "message"]
disable_json Disables JSON logging format. Use Console Mode Format. false
timestamp_format Sets the format of the logger timestamp. add_timestamp: true If disable_json: true:3:04PMIf disable_json: false:"2006-01-02T15:04:05Z07:00"
no_metadata Don't log the process name and replica number. false
add_timestamp Add timestamp to the logger. Useful for processes without an internal logger. false
no_color Disable ANSII colors in the log file. disable_json: true false

Process Compose Internal Log

Default log location: /tmp/process-compose-$USER.log

:bulb: It is recommended to add the following process configuration to your process-compose.yaml:

yaml
processes:
  pc_log:
    command: "tail -f -n100 process-compose-${USER}.log"
    working_dir: "/tmp"

This will allow you to spot any issues with the processes execution, without leaving the process-compose TUI.


File: docs/merge.md

Using multiple process-compose files lets you to customize a process-compose application for different environments or different workflows.

Understanding multiple Compose files

By default, process-compose reads two files, a process-compose.yml and an optional process-compose.override.yml file. By convention, the process-compose.yml contains your base configuration. The override file, as its name implies, can contain configuration overrides for existing processes or entirely new processes.

If a process is defined in both files, process-compose merges the configurations using the rules described in Adding and overriding configuration.

To use multiple override files, or an override file with a different name, you can use the -f option to specify the list of files. process-compose merges files in the order theyโ€™re specified on the command line.

When you use multiple configuration files, you must make sure all paths in the files are relative to the base process-compose file (the first process-compose file specified with -f). This is required because override files need not be valid process-compose files. Override files can contain small fragments of configuration. Tracking which fragment of a process is relative to which path is difficult and confusing, so to keep paths easier to understand, all paths must be defined relative to the base file.

Example use case

Different environments

A common use case for multiple files is changing a development process-compose app for a production-like environment (which may be production, staging or CI). To support these differences, you can split your process-compose configuration into a few different files:

Start with a base file that defines the canonical configuration for the processes.

process-compose.yml

yaml
processes:
  web:
    command: "npm start"
    depends_on:
      db:
        condition: process_started
      cache:
        condition: process_started

  db:
    command: "pg_ctl start -l logfile"

  cache:
    command: "systemctl start redis"

In this example the development configuration adds debug flags.

process-compose.override.yml

yaml
processes:
  web:
    environment:
      - "DEBUG=true"

  db:
    command: "pg_ctl start -l logfile -d"

When you run process-compose it reads the overrides automatically.

Now, it would be nice to use this process-compose app in a production environment. So, create another override file (which might be stored in a different git repo or managed by a different team).

process-compose.prod.yml

yaml
processes:
  web:
    environment:
      - "PRODUCTION=true"

  cache:
    environment:
      - "TTL=500"

To deploy with this production process-compose file you can run

shell
$ process-compose -f process-compose.yml -f process-compose.prod.yml

This deploys all three processes using the configuration in process-compose.yml and process-compose.prod.yml (but not the dev configuration in process-compose.override.yml).

Adding and overriding configuration

process-compose copies configurations from the original process over to the local one. If a configuration option is defined in both the original process and the local process, the local value replaces or extends the original value.

For single-value options like command, working_dir or disabled, the new value replaces the old value.

original process:

yaml
processes:
  myprocess:
    # ...
    command: python app.py

local process:

yaml
processes:
  myprocess:
    # ...
    command: python otherapp.py

result:

yaml
processes:
  myprocess:
    # ...
    command: python otherapp.py

For the multi-value options environment, depends_on, process-compose merges entries together with locally-defined values taking precedence:

original process:

yaml
processes:
  myprocess:
    # ...
    environment:
      - "A=3"
      - "C=8"

local process:

yaml
processes:
  myprocess:
    # ...
    environment:
      - "A=4"
      - "B=5"

result:

yaml
processes:
  myprocess:
    # ...
    environment:
      - "A=4"
      - "B=5"
      - "C=8"

File: docs/tui.md

TUI (Terminal User Interface)

TUI Allows you to:

  • Review processes status
  • Start processes (only completed or disabled)
  • Stop processes
  • Review logs
  • Restart running processes

TUI is the default run mode, but it's possible to disable it:

shell
./process-compose -t=false

Control the UI log buffer size:

yaml
log_level: info
log_length: 1200 #default: 1000
processes:
  process2:
    command: "ls -R /"

:bulb: Using a too large buffer will put more penalty on your CPU.

By default process-compose uses the standard ANSI colors mode to display logs. However, you can disable it for each process:

yaml
processes:
  process_name:
    command: "ls -R /"
    disable_ansi_colors: true #default false

:bulb: Too long log lines (above 2^16 bytes long) can cause the log collector to hang.

Shortcuts Configuration

Default shortcuts can be changed by placing shortcuts.yaml in your $XDG_CONFIG_HOME/process-compose/ directory.
The default process-compose configuration is defined as:

yaml
# $XDG_CONFIG_HOME/process-compose/shortcuts.yaml
shortcuts:
  log_follow: # action name - don't edit
    toggle_description: # optional description for toggle buttons. Will use default if not defined
      false: Follow Off
      true: Follow On
    shortcut: F5 # shortcut to be used
  log_screen:
    toggle_description:
      false: Half Screen
      true: Full Screen
    shortcut: F4
  log_wrap:
    toggle_description:
      false: Wrap Off
      true: Wrap On
    shortcut: F6
  process_restart:
    description: Restart # optional description for a button. Will use default if not defined
    shortcut: Ctrl-R
  process_screen:
    toggle_description:
      false: Half Screen
      true: Full Screen
    shortcut: F8
  process_start:
    description: Start
    shortcut: F7
  process_stop:
    description: Stop
    shortcut: F9
  quit:
    description: Quit
    shortcut: F10

shortcuts.yaml can contain only the values you wish to change, default values will be used for the rest.
For example if you want to replace the default quit shortcut to be F3 instead of F10 and rename the process_stop to be Terminate, the configurion will be as follows:

yaml
# $XDG_CONFIG_HOME/process-compose/shortcuts.yaml
shortcuts:
  process_stop:
    description: Terminate
  quit:
    shortcut: F3

--- METRICS ---