xupisco

A startup studio on open source

One file becomes a company.

xupisco runs its products on a platform built entirely from open-source software, on one Kubernetes cluster we operate ourselves. Commit a short YAML file and a new product gets its repository, CI, database, sign-in, secrets, queues, email, CRM and preview environments.

1 cluster ~75 resources per product 0 license fees 0 paid load balancers
projects/wiseresume.yamlgit push → Flux
apiVersion: platform.xupisco.com/v1alpha1kind: Projectmetadata:  name: wiseresumespec:  tenancy: b2c  payments:    provider: creem  campaigns:    enabled: true
Crossplane composes each piece from the file above. Click one to jump to it.

Why open source

Own the stack instead of renting it.

A startup usually pays a monthly fee per product for auth, email, CRM, logging, CI and queues, and those bills grow with every user and every seat. xupisco runs the open-source version of each one, once, and every product shares it.

The price doesn't grow with users

Open-source tools charge nothing per seat, per event or per monthly active user. The cost is the servers they run on, and a new product adds almost nothing to that.

A fifth product gets the same sign-in, email, queues and CRM as the first, at no extra license cost.

When something is missing, we fix it

With the source code available, a limit or a missing feature doesn't have to wait for a vendor's roadmap. We change the code and run our own build.

Twenty (CRM) and Plunk (campaigns) run as our own patched builds, with the AGPL source published on our Git server.

The data stays with us

Customer records, events, logs and files live in databases we run. Nothing leaves for a third party unless it has to, such as outgoing email.

Backups go to our own object storage first, then to an off-site bucket with a 30-day write lock.

The stack, in boot order

Every pick, and why we made it.

Flux starts the cluster in eight waves. Each wave waits for the one before it, because later waves use what earlier ones install. This list matches what is deployed today.

UNDER THE WAVES

The cluster

What runs everything else.

Rackspace Spot

Servers

Managed Kubernetes on servers rented at auction from spare data-center capacity. They are older Xeon machines, cheap and good enough for everything we run.

instead of on-demand cloud VMs

Flux

GitOps

Applies whatever is in Git, wave by wave, and waits for each wave to be healthy before starting the next. It also bumps image tags after each build and creates one environment per open pull request.

instead of deploy scripts and clicks

WAVE 1

Edge

How the internet reaches us.

Cloudflare Tunnel

Ingress

The cluster has no public IP and no load balancer. It opens an outbound tunnel to Cloudflare, which handles DNS, TLS at the edge and access checks for admin tools.

instead of paid cloud load balancers

Envoy Gateway

Routing

Routes each hostname to the right service using the Kubernetes Gateway API. It also adds single sign-on in front of tools that have none of their own.

instead of a hosted API gateway

cert-manager

TLS

Issues and renews every certificate inside the cluster. Nobody copies certificate files around.

instead of manual certificate renewals

WAVE 2

Data

Where each product keeps its state.

PostgreSQL · CloudNativePG

Database

Each product gets its own Postgres cluster, and each preview gets its own copy. The operator handles failover, point-in-time backups and restores.

instead of managed RDS or Supabase

WAVE 3

Secrets

One source of truth for keys.

SOPS + age

Secrets in Git

The few platform secrets that live in the repo are encrypted file by file, so the Git history never contains a readable key.

instead of keys pasted into CI settings

ExternalDNS

DNS

A new route publishes its own Cloudflare DNS record. It starts in wave 3 because it needs the Cloudflare token from Infisical.

instead of editing DNS by hand

Backblaze B2

Off-site backup

Database backups, Git data and the secrets key are copied off the cluster to B2. The bucket uses Object Lock, so the key that writes backups cannot delete them.

chosen over R2, which lacks S3 Object Lock

WAVE 4

Observability

Seeing what every request did.

WAVE 5

Identity & composition

Sign-in, and the engine that builds products.

Keycloak

Authentication

One Keycloak serves everything. The team signs in once to every internal tool. Each product gets its own realm for its customers, with passkeys, a branded login page, and B2B workspaces when a product needs them.

instead of Auth0 or Clerk, priced per active user

Separate preview realm

Safety

Preview environments sign in against their own realm, so a test build can never read or change real customer accounts.

instead of test users inside production

Crossplane

Composition

Turns one Project file into about 75 resources across every tool on this page: realms, databases, buckets, topics, secrets, CRM, campaigns. It also drives the AWS side of email (SES, SNS, IAM). Deleting the file cleans everything up.

instead of a setup checklist

Platform Postgres

Shared database

One CloudNativePG cluster for the platform's own tools, with a database each for Keycloak, Twenty, Plunk and others. Products never use it; they get their own.

instead of a managed database per tool

WAVE 6

Delivery

From commit to running code.

Renovate

Updates

Opens a pull request for every new version each Monday. Small tools update themselves after checks pass. Databases and control-plane parts wait for a human.

instead of forgotten upgrades

WAVE 7

Portal & events

What every product talks to.

Novu

Notifications

Transactional email and an in-app inbox, on its own MongoDB replica set. Notification designs live in the product's code as React Email templates. Previews send to a test inbox, so a test never emails a real person.

instead of Knock or Courier

Leaves of wave 7: they start last, and nothing waits for them. If the CRM or the campaign tool fails, products keep shipping.

Twenty

CRM

One Twenty for the whole platform, one workspace per product at crm-<slug>.xupisco.com, plus a -dev workspace for previews. Our build lifts the open-source edition's limit of five workspaces, and that source is public on our Git server.

instead of HubSpot or Salesforce seats

Plunk + Amazon SES

Campaigns

One Plunk for the whole platform, one campaign space per product, sending from <slug>.news.xupisco.com. Sequences live in the product's code, with double opt-in and one-click unsubscribe. SES delivers. A watch on bounces and complaints pauses sending if they rise. Our fork adds Keycloak sign-in, and its source is public.

instead of Mailchimp or Loops

WAVE 8

Projects

The products themselves.

Project API

Schema

Defines what a Project file may say (name, B2C or B2B, payments, campaigns) and how Crossplane builds it. The cluster rejects a file that breaks the rules before anything is created.

instead of tribal knowledge

How it moves

From a pull request to production.

Every change is proven in an isolated copy of the product before it merges. Production data and real customers are never involved.

Preview a pull request

Opening a pull request creates a full environment with its own database, cache, bucket and topics. Closing it removes everything.

1Open PRon Forgejo
2EnvironmentFlux creates <slug>-pr-<n>
3BuildTekton builds pr-<n> images
4End-to-endtests run against the live preview
5Commentresult and link posted on the PR

Ship to production

Merging to main is the deploy. Nobody runs a command against the cluster.

1Mergepush to main
2Test & buildTekton: test → build → e2e
3SignChains signs the image
4Tag bumpFlux commits the new tag
5LiveFlux applies deploy/ to prod

The bill

Why it costs so little to run.

The savings don't come from one trick. Each paid line item a startup usually carries is either shared across products or gone.

1

Auction-priced servers

Rackspace Spot rents idle capacity at market price, well below on-demand VMs. Stateful services stay on a stable pool, and interruptible work runs on cheaper nodes.

2

No load balancers, no public IPs

All traffic arrives through one outbound Cloudflare tunnel, so we pay nothing for load balancers or static IPs.

3

No per-seat or per-user pricing

Auth, CRM, notifications, CI and monitoring are open source. Adding a customer or a teammate adds no license fee.

4

One platform, many products

Every product shares the same Keycloak, Novu, Redpanda and Grafana. The tenth product costs about what its own database and pods need.

5

Previews that clean up after themselves

A preview lives only while its pull request is open, with a cap per product, so test environments don't pile up.

6

Pay-per-use only where it's cheaper

Where a service is cheaper than running our own, such as SES for bulk email or B2 for backups, we pay per use and nothing more.

Every tool on this page is open source. Put together, they let one small team run many products.