An environment that knows your repo.

Runs start on a universal image that installs whatever toolchain versions your repo pins. Add a .ryph/Dockerfile, and Ryph bakes your repo’s own environment with dependencies installed and the build warm, so runs get straight to work.1

acme/web main
  • .nvmrc 22
  • .ryph/Dockerfile
  • .ryph/setup.yml
  • .ryph/services.yml
Environment build nothing to build
Universal image default
  • Machine Rust, Node, Python, Go…
  • Dependencies each run
  • Build cold
Run 7f3a installing Node 22
Run 91c2 working, own Postgres
Run b04e previous image

With no setup, a run starts on the universal image. The Node version acme/web pins in .nvmrc installs on first use.

Ready before the agent starts

With a baked image, setup happens when your environment changes, not on every run.

Works with no setup

The universal image carries Rust, Node, Python, Go, Deno and Bun, and installs the versions your repo pins on first use.

Baked from main

Ryph builds your repo’s image from the default branch and rebuilds when .ryph/ changes. Until a new build is ready, runs use the last one.

Branches bring their own

A branch that changes the Dockerfile gets its own image, so the change is tried out before it merges.

An agent can set it up

Ask an agent to set up a repo’s environment. It reads your CI and lockfiles, and works through build results until the image builds.

Sized for the job

Admins pick a machine size for each repo or workspace.

  1. Environment builds are on by default for the binary and Docker Compose; on Kubernetes, an operator enables them. Without an environment image, pinned toolchains install on every run and need their download hosts on the internet allowlist. A .ryph/Dockerfile needs a glibc base with bash, git and ssh-keygen. The setup agent’s loop ends when the image builds, not when your checks pass. Machine sizes are fully applied on Kubernetes; Docker applies CPU and memory.

Real tests need real services.

Give your agents the databases and services your code depends on. Declare them once in your repo, and each run gets its own instances.2

.ryph/services.yml Same declaration. Separate instances.
Fix a query
Run 7f3a preparing services
PostgreSQL starting
Redis starting
Fix cache invalidation
Run 91c2 preparing services
PostgreSQL starting
Redis starting

Declare the services your code needs in .ryph/services.yml. Ryph provisions a separate set for each run.

Defined with your code

Services live in .ryph/services.yml, alongside the code that needs them.

Ready before work begins

Ryph waits for the declared service ports before setup starts, and tells the agent how to reach each service.

A growing catalogue

PostgreSQL, MySQL, Redis, MongoDB and Meilisearch, with more to come. Each run gets its own instances.

  1. Service containers must be enabled by the operator, which allows the whole catalogue; other images must match an operator-set allowlist. They need a connected repo. On Docker, a run’s services sit on a separate network but aren’t firewalled from other runs. Readiness currently checks TCP connectivity; a service such as MySQL may need an additional application-level check in repo setup.

More of Ryph

Try it on your own machine.

One binary with the web app and database built in.

Get started