Runp is a process orchestration tool that extends beyond container management. In addition to running containers, Runp orchestrates host processes and SSH tunnels, enabling comprehensive development environment setup and management.
Designed to streamline the complete setup of development environments with a unified configuration approach.
Define your system configuration in a Runpfile:
name: Example
description: |
Sample Runpfile to show runp functionalities
units:
web:
description: Web app
# this process is running on host machine
host:
command: node app.js
workdir: backend
env:
# inherit PATH from host system to find needed tools (e.g. node)
PATH: $PATH
await:
# wait for the DB being available
resource: tcp4://localhost:5432/
timeout: 0h0m10s
mail:
description: Test mail server
# this process is running in a container
container:
image: docker.io/mailhog/mailhog
ports:
- "8025:8025"
- "1025:1025"
db:
description: Corporate DB
# This process is reachable through SSH port forwarding
ssh_tunnel:
user: user
auth:
identity_file: ~/.ssh/id_rsa
local:
port: 5432
jump:
host: dev.host
port: 22
target:
host: corporate.db
port: 5432Execute Runp:
runp up -f /path/to/Runpfile
For additional examples, see the examples directory.
For comprehensive documentation, visit the official documentation.
Large projects can split their configuration across multiple files and compose them with the include: key.
Each entry is a path relative to the directory of the file that declares it.
All units from included files are merged into the root Runpfile before startup, together with their vars (the including file wins when the same var is declared twice).
# Runpfile (project root)
name: My Project
include:
- infra/Runpfile # defines units: db, redis
- services/Runpfile # defines units: api, worker
units:
proxy:
host:
command: nginx -g "daemon off;"# infra/Runpfile
units:
db:
container:
image: postgres:15
ports: ["5432:5432"]
redis:
container:
image: redis:7
ports: ["6379:6379"]After loading, runp up starts all five units (db, redis, api, worker, proxy) as if they were defined in a single file.
Duplicate unit names across any two files are an error — loading fails immediately with:
duplicate unit identifier: <name>
Rename the conflicting unit in one of the files before proceeding.
Circular includes are detected and reported with the full import chain, for example:
circular dependency detected: a.yml -> b.yml -> c.yml -> b.yml
Including the same file through two different branches is not a cycle, but it defines its units twice and is reported as a duplicate unit.
Includes can be nested to any depth as long as there are no cycles and no duplicate unit names.
When running Podman in rootless mode, --volumes-from can fail with a "container not found" error if the source container has not finished its startup sequence before the dependent container starts. This is a timing issue specific to rootless Podman; Docker is not affected.
Workaround: make the dependent unit depends_on the source unit, and give the source unit a ready: condition, so that runp starts the dependent container only once the source container is up.
units:
data:
ready:
# ready when the container accepts connections...
cmd: "nc -z localhost 8080"
# ...or, if it exposes no port, after a short fixed delay:
# delay: 5s
container:
image: myapp/data:latest
ports: ["8080:8080"]
app:
depends_on:
- data
container:
image: myapp/app:latest
volumes_from:
- data # resolved to runp-data at runtimeWithout a ready: condition, app would start only after the data container exits. For a data-only
container that exits immediately, set skip_rm: true on it instead, so that the stopped container (and its
volumes) is still available to --volumes-from.
Note that await: on the source unit would delay the start of the source unit itself, not of app.
Clone or download the repository.
Build the project (binaries will be created in bin/):
./.sdlc/build
or
.sdlc\build.cmd
Run code quality checks and tests:
./.sdlc/check
or
.sdlc\check.cmd
Apache 2.0 - see LICENSE file.
Copyright 2020-TODAY runp contributors