One feature, start to finish
One feature followed through a team's lifecycle, branch to hotfix, and where Fadebox fits at each step: the PR copy, review, QA, release, support.
Let’s follow one feature through a normal team’s lifecycle and see where Fadebox shows up. The
team runs an online shop: a web frontend, an api, PostgreSQL, Keycloak, a search service.
The feature is discount codes on checkout, ticket SHOP-1842, and the person building it is a
developer we’ll call Jana. Nothing below is special to this feature; it’s the shape of most
weeks.
One assumption up front: somebody on the team has already described the shop as an environment in Fadebox, once. Each service is a template (Compose YAML, the same kind you’d write anyway), and the environment says which ones make up the stack and in what order. That’s the one-time part. The PetClinic post does it step by step. Everything after that is the loop.

The environment is composed once. Every copy after that comes from it.
1. The branch
Jana starts feature/SHOP-1842. For the first day she doesn’t need Fadebox at all; the code
runs on her laptop against whatever she has there. The moment she does need it is the moment she
needs the real neighbours: the actual Keycloak realm, the search index with data in it, the API
at the version everyone else has. That used to mean “is staging free?” and it usually wasn’t.
Now she asks for a copy:
fadebox instance up shop-1842 --wait --tag web=feature-shop-1842 --purpose "SHOP-1842 discount codes"
Ninety seconds later there’s a full shop at shop-1842-web.envs.example.com, with every service
at the environment’s known version except web, which runs the image her branch just built.
That --tag works because whoever maintains the environment opened the web service for tags;
she can set that one thing on her own copy and nothing else, and she never sees anyone’s
credentials. Postgres, Keycloak and the rest came up exactly as they would for anyone.
She pushes again an hour later. A redeploy restarts only web; the database keeps its data and
the search index keeps its index. The copy has a seven-day lifetime that every deploy resets,
so as long as she’s working on it, it stays.
2. The pull request
Jana opens the PR. From here the pipeline does what she did by hand, on every push: build the
image, bring pr-42 up with that image, put the URL on the pull request, run the end-to-end
suite against it, and write the result on the instance.

What the pull request’s copy looks like from Fadebox’s side: why it exists, what’s different about it, what the suite found.
The pipeline is about ten lines; the
CI post has the full GitHub Actions and GitLab
versions. The part that matters here is what lands on the instance: a purpose line and a link
back to the PR, and the checks, e2e passed, 84 of 84, perf queued, each linking to the
run. A second push replaces them with fresh ones.
3. Review
The reviewer reads the diff, as always. But now there’s also a URL, and the reviewer opens it
and actually buys something with a discount code. That’s a different kind of review from
reading applyDiscount() and imagining it.
The product owner does the same thing without reading any code. She opens the URL, tries the three discount tiers, and records a verdict on the instance: approved, or rejected with a note. “The 10% code applies twice on the second tier” goes next to the thing it’s about, not into a chat thread that has scrolled away by the time Jana reads it.
Jana fixes it and pushes. The new deploy starts with no checks and no verdict, because those were about the previous build; the previous attempt keeps them. When someone later says “but it was approved”, the instance’s history shows which build was, and what changed between that one and this one.

Every push is a row. The rejected one is still there, with its note.
4. Merge
The PR merges. The pipeline’s close job stops and deletes pr-42; if it didn’t, expiry would
stop it in a week anyway.
The team keeps a main copy of the shop running for whoever wants to see the current state of
things. Its web tag isn’t typed into Fadebox by anyone. The environment’s tag is a
reference into the team’s values file in git, the same file
their deployment tooling reads, so when the merge bumps the version there, the next redeploy of
main picks it up and the record says which commit it read. Nobody logs into Fadebox to release
anything.
5. QA and the release candidate
Two weeks later the team cuts release 1.4. QA needs a stack that doesn’t move while they run
the regression pass. The environment maintainer clones dev into release-1.4, pins its
versions, and marks it protected, so a developer’s afternoon edit to dev can’t change what’s
being tested. QA deploys uat from it and extends it when the lifetime runs low.
Halfway through, a test wrecks its own data. That’s fine; that’s what the test was for. Reset throws away the instance’s containers, network and volumes and deploys it again from scratch, same versions, known state, in a couple of minutes. Nobody had to ask anyone.
QA finds a real bug in the discount flow at the release candidate. They record it as a check on
the uat instance, regression failed, with the run linked, and reject the build with a note.
The developer who picks it up deploys the exact same versions on a copy of their own, reproduces
it, fixes it on a branch, and the loop from step 2 runs again for the fix.
6. Release, and the demo
1.4.0 ships. Sales wants to show discount codes to a prospect on Thursday. They don’t borrow
uat; they make a copy from the team’s demo blueprint, an environment kept for cloning and
never deployed itself, with the prospect’s branding and a seeded dataset, and it expires next
week on its own. Three prospects, three copies, none of them anybody’s problem afterwards.
7. The bug from production
A month on, a customer on 1.3.2 reports that a discount code shows the wrong total. Support
doesn’t ask a developer for a 1.3.2 environment. They bring up a copy with web pinned to
1.3.2, link the ticket, reproduce the bug in ten minutes, and paste the instance URL into the
ticket. The developer opens the same URL, sees the same thing, and starts a hotfix branch.
The hotfix goes through steps 1 to 3 like any other branch, gets released as 1.3.3, and the support copy expires when nobody deploys to it for a week.
What changed, and what didn’t
Nothing in the team’s actual process changed. Branches, pull requests, review, QA, releases, support tickets: the same steps, in the same order, with the same people. What changed is that “is staging free?” stopped being a question, because every step that needed a running stack got its own. The developer’s branch, the pull request, the product owner’s check, QA’s regression run, the demo, the support reproduction, each ran on a copy that existed for exactly that reason and left when the reason did.
The stack definition stayed one thing that the developers keep honest. The copies were cheap enough to be disposable, on hosts the team already had, without a cluster and without a SaaS in the middle. And the facts that used to live in chat, which build was checked, who approved it, what changed since Tuesday, ended up on the instance, where the next person looks.