Fundaia Case Study: A Deployment Platform Built From Scratch
Every managed hosting bill has a line nobody looks at: the services that were running all month and answered nobody. A staging environment, an internal tool, a demo for a client who stopped clicking in March. They cost the same as production because a managed platform charges for a container that exists, not for one that works. Fundaia is the deployment platform we built to stop paying that line, and it now runs our own API in production.
You Are Paying for Silence
The usual choice when you need to deploy something has two options and both are bad. You rent a managed platform, and the convenience is real: you connect a repository and a domain answers. But the bill grows with every service you leave running, the configuration lives in a dashboard you do not own, and the day you want to leave you discover that what deploys there deploys nowhere else.
Or you wire a server by hand. It is cheap and it is yours, and it stays that way for exactly as long as one person remembers how it was built. Then somebody needs a database next to an API, a certificate expires, a deploy needs a reverse proxy reloaded, and the thing that was going to take an afternoon becomes the reason nothing gets deployed on Fridays.
That is the gap Fundaia was built for: the first experience of a managed platform, on a machine whose cost, configuration and exit are yours.
From a Repository to a Domain, Without Writing Any of It
Fundaia is a deployment platform. You connect GitHub and pick a repository; the platform reads the project, works out how it should be built, writes the Containerfile, builds the image, starts a rootless container, waits for it to answer a health check and publishes the address. Databases come from a template and connect themselves, because a variable points at another service by reference rather than by value and the platform resolves it at deploy time. And a service nobody is calling goes to sleep: the gateway starts it again on the next request, so an idle environment stops costing money without stopping working.
One Deployment, Six Steps on Screen
A deployment is not a spinner and a result. It is six named stages, each able to fail on its own and say so:
- 1. Queued: The deployment is admitted and takes its turn. Two deployments of the same service never run at once, so a push while a build is running queues instead of racing it.
- 2. Fetching the code: The repository is cloned at the commit being deployed. The build context stays at the checkout root, so a lockfile or a sibling package above the application still resolves.
- 3. Building the image: The platform detects the stack and writes the Containerfile, declaring a build argument for every public variable so the values reach the build. If you edited that file by hand, it is never overwritten.
- 4. Starting the container: The container starts rootless and publishes on loopback only, on a port the platform assigns. Nothing it exposes is reachable from the network except through the tunnel.
- 5. Checking that it answers: The deployment is not live because the process started. It is live when it answers, which is the difference between a service that deployed and a service that works.
- 6. Live: The address starts serving and the previous container is retired, freeing its name and its port. The image it ran is kept, because that is the only way back that is not a rebuild.
Built for a Machine That Runs Unattended
The flow reads simply. What makes it dependable is the set of problems that only appear once real traffic and real disks are involved:
- Publishing a domain is a database write, not a config reload: The edge proxy is configured once, with a single wildcard rule that forwards anything no explicit host claims. Publishing a service is then an insert: no file rewritten, no reload, no elevated permissions and no waiting for anything to converge.
- Scale to zero that survives twenty simultaneous visitors: The obvious way to wake a sleeping service, a lock around the wake up, serialises the requests and each one still reads a stale state and starts it again. Requests are deduplicated instead, so twenty visitors share one start and nineteen wait on its result.
- A disk that does not fill itself: One image per deployment is a whole filesystem, and a multi stage build leaves untagged layers no cleanup can name. Left alone, that reached 172 GB of a 221 GB disk with fourteen images actually in use. A reaper keeps the two newest images of every service, so a rollback still has somewhere to go, and prunes intermediate layers past a cutoff so a build in flight is never killed.
- No port open on the router: A tunnel dials out from the machine, so there is nothing to port forward and the dynamic home IP never matters. TLS terminates at the edge and traffic arrives over loopback.
- The platform credential never reaches a deployed service: The session cookie is written for the parent domain, so the browser offers it to every service published underneath it. The gateway strips it before forwarding: one line, and a deployed service never sees the credential that administers the platform it runs on.
- A documented way out: Data lives in volumes with an automatic daily backup that can be restored and downloaded, and the generated Containerfile stays written and editable. What deploys here deploys anywhere that runs containers.
The Same Platform, Operated Four Ways
The interesting decision was not building the web interface. It was refusing to build the other three on top of it. The rules live once in the services, and each surface is a translation of them rather than a layer over the last:
- The web, for the work that is visual: Projects, services drawn as a graph with the variables that connect them, deployment logs by stage, metrics and billing per service and per day.
- A command line, for the work that is repetitive: A Rust binary that talks to any instance, not just one, with a JSON contract for scripting. A terminal cannot present a passkey, so it gets a credential of its own through a device flow: the platform prints a code, you approve it in the browser, and the terminal picks up its token.
- A REST API, for the work that belongs to your systems: Everything the interface does is an endpoint, authenticated per project, so a deployment can be triggered from your own pipeline instead of from a dashboard somebody has to open.
- An MCP server, for the work you want to delegate to an agent: The platform speaks the Model Context Protocol, so an agent can create a project, connect a database and deploy a service. It reaches exactly what the person whose token it carries reaches, every write lands in that project's history under their name, and no tool it can call ever reveals a secret.
What the Platform Delivers
- A GitHub repository running on a live domain, with the Containerfile written for you and yours to edit
- Databases from a template, connected by reference so no address or credential is ever copied by hand
- Idle services asleep and awake on the next request, so an environment nobody uses stops costing money
- Memory, CPU, volume and egress metered by the second, shown per service and per day, with a spending ceiling that suspends instead of surprising
- Daily backups that can be restored and downloaded, and a rollback to the previous image without a rebuild
- The same capability from the web, a terminal, an API and an agent, with no port open on the router
The Numbers Behind It
A platform that loses somebody's deployment is worse than no platform, so the engineering bar is where it needs to be:
- React 19 and Tailwind CSS 4 for every screen, with the product films written as React components so there is no video file to serve
- Bun as runtime, bundler and test runner, with TypeScript 7 pinned to an exact version because a type checker is what decides whether the code is correct
- Podman for rootless containers, one image per deployment, with a reaper that owns which ones survive
- A Cloudflare Tunnel to the outside and a local proxy routing by host name, with service containers on loopback only
- A command line of its own in Rust, released and versioned separately so a CLI that fails to compile never holds up a server deploy
- More than 320 automated test suites across the monorepo, and a deploy that is a push to main: CI verifies the commit and the machine installs it by asking, so no credential to the machine exists in GitHub
What Is Your Infrastructure Costing You in Things You Cannot Change?
Add up the services running for nobody, the configuration that lives in somebody else's dashboard, and the migration you keep postponing because you do not know what it would take. That is the real cost, and none of it shows up as a line item. Fundaia is what we mean by building infrastructure rather than renting it: a platform designed around one operational flow, taken to production standards, and hosting our own API today. If you are deciding between a bill that grows on its own and a server nobody wants to maintain, tell us what you are running. We will tell you what it would take to own it.
- Explore our custom software development services
- Read the Almacén-Pro goods receiving case study
- Tell us what you are running today