Skip to content

WorkDeveloper tooling

Internal developer CLI

A developer CLI for the campaign platform: a thin orchestration layer around Docker Compose that understands the application’s topology.

System and tool names have been generalised.

Stack as evidence

Bash · Docker Compose · Laravel · Redis · PHPStan · Rector

Principle

Build the missing abstraction, not the entire ecosystem.

dev · zsh

$ ./dev --help

$

01The problem

Container orchestration was solved. Understanding the application was not.

Docker Compose already started the containers. What it could not do was know which service Artisan should run in, which database a migration targets under the tenancy model, or that a test run and a static-analysis run want different environments. Every engineer carried that knowledge in their shell history, slightly differently.

02The constraints

What could not simply be changed.

  • Zero ceremony

    A single executable in the repository root. No install step, no runtime beyond what a developer machine already has.

  • Compose stays the engine

    The CLI wraps Docker Compose instead of replacing it, so nothing it does is hidden from someone who prefers the raw commands.

03The architecture

The CLI is a small shell program that maps intent to topology. A verb such as start, test, art, composer, redis, phpstan or rector is resolved to the right container, working directory and environment, then delegated to Docker Compose. Everything after the verb is passed through untouched, which is why `./dev art migrate` is just Artisan with the plumbing removed.

04Engineering decisions

  1. 01

    Wrap, don’t replace

    Re-implementing what Compose already does well would have created a second system to maintain. The value was entirely in the layer Compose lacked: knowledge of this application.

  2. 02

    One interface for every workflow

    Application, tests, tooling and infrastructure all sit behind the same verb style, so onboarding is reading one help screen rather than several READMEs.

05The trade-offs

What complexity I introduced, on purpose.

  • A shell script has a ceiling. It is the right tool at this size and the wrong one if it ever needs real argument parsing or plugins.
  • Another thing to keep in step with the Compose file when the topology changes.

06The outcome

  • A consistent interface to the development environment that encodes how the application, tenancy model, databases and supporting infrastructure fit together.

07The lesson

Developer platforms rarely need new infrastructure. They need the abstraction that turns existing infrastructure into something that understands your system.