How I Run All My Apps on One Server

Every site and app I've built runs on a single Linux server - one box, seven projects, a shared Postgres and Redis, deployed straight from GitHub. Here's how the whole thing fits together.

Every project on this site — the blog you're reading, ClaveFlux, TailorSwan, Amma Studio, all of it — runs on one Linux server. Not one server each. One server, total.

What is it?

It's my own little cloud — a single Linux VPS that hosts every app and site I build, managed through Dokploy, an open-source, self-hosted deployment platform. Think of it as a personal Heroku that I run myself.

Right now it holds 7 projects and about a dozen containers, all on one machine: a blog, an agent platform, a resume tool, an AI studio, a finance app, a robot's relay, and one shared "services" project that the rest lean on.

What does it do?

It runs and serves all my live products from one place, each on its own domain:

I push code to GitHub, and the server builds it and puts it live. That's the whole loop.

How does it work?

Under the hood it's a few well-worn pieces fitted together.

One box, many containers. The server runs Dokploy on a single-node Docker Swarm. Every project is just a set of Docker containers — an api, a web, a worker — sitting on the same machine.

Traefik routes the traffic. A reverse proxy called Traefik sits in front of everything. It terminates HTTPS (with auto-renewing Let's Encrypt certificates) and routes each domain to the right container — claveflux.com to the ClaveFlux web container, tailorswan.me to TailorSwan's, and so on.

GitHub is the deploy button. Every app deploys from its GitHub repo. Push to the branch, Dokploy builds a fresh Docker image and rolls it out — no manual SSH, no copying files around.

Shared resources are the trick. Instead of every app running its own database, there's a single shared-services project with one Postgres and one Redis that the apps connect to. Six apps, one database server. (The one exception is this blog: it runs on Ghost, which brings its own built-in MySQL, so it sits slightly apart from the shared stack.)

Here's the whole thing in one picture:

flowchart TD
    DNS([Domains<br/>snehithkumar.com · amma/spend/play.snehithkumar.com<br/>claveflux.com · tailorswan.me]) --> TR
    GH[GitHub repos] -->|git push → build & deploy| DOK[Dokploy<br/>self-hosted PaaS]

    subgraph VPS[One DigitalOcean droplet — Docker Swarm node · 2 vCPU · 3.8 GB RAM]
      DOK --> TR[Traefik<br/>reverse proxy + TLS]
      TR --> BLOG[portfolio-blog<br/>Ghost]
      TR --> RELAY[dave-the-robot<br/>relay]
      TR --> SPEND[spend-analysis<br/>web + api]
      TR --> AMMA[amma-studio<br/>web + api]
      TR --> CLAVE[claveflux<br/>web + api + workers]
      TR --> TAIL[tailorswan<br/>web + api]

      BLOG --> MYSQL[(Ghost's own MySQL)]
      RELAY --> PG[(Shared Postgres)]
      SPEND --> PG
      AMMA --> PG
      CLAVE --> PG
      TAIL --> PG
      CLAVE --> REDIS[(Shared Redis)]
    end

    style PG fill:#e0ecff,stroke:#2563eb,stroke-width:2px,color:#0f172a
    style REDIS fill:#e0ecff,stroke:#2563eb,stroke-width:2px,color:#0f172a
    style MYSQL fill:#fde4e4,stroke:#c2410c,stroke-width:2px,color:#0f172a

What does it solve?

Cost and sprawl. The easy way to host six apps is six managed services — a host for each frontend, each backend, and a separate database for each. That's a lot of monthly bills and a lot of dashboards.

Putting everything on one VPS with a shared database collapses all of that into a single machine I control. No per-app database bill, no cold starts from sleeping free tiers, and one place to look when something breaks instead of six.

It also keeps things tidy: every project follows the same shape (web + api, deploy from GitHub, talk to shared Postgres), so adding the next one is the same five steps every time.

What can it do?

More than I expected for one small box.

The dashboard at deploy.snehithkumar.com manages all of my projects and services, along with live server monitoring and more.

What tech does it use?

The whole stack, kept deliberately boring:

Piece What it is
Dokploy Self-hosted deployment platform (the dashboard + glue)
Docker + Docker Swarm Runs every app as a container on a single node
Traefik Reverse proxy — HTTPS, certificates, and domain routing
GitHub Source of every deploy (push → build → live)
Shared Postgres (postgres:18) + Redis One database and one cache, shared across the apps
Ghost (+ its own MySQL) Powers this blog at snehithkumar.com
DigitalOcean droplet A single 2-core / ~4 GB Linux machine running all of the above

That's the whole thing. One server, every project — and adding the next one is just one more push to GitHub.

Why own the box?

We're all building faster than ever right now — AI makes it easy to spin up a whole new app in a weekend. But every one of those apps still has to live somewhere, and the default path — Vercel for the frontend, another service for the backend, a hosted database for each — turns "I built a thing" into a pile of monthly bills and dashboards before it has a single user. For someone shipping projects this quickly, that overhead adds up fast.

So I flipped the default. New projects deploy to my own server first. It costs the same whether it's serving ten requests or ten thousand, there's no platform to get locked into, and everything lives in one place I can actually see. If a project earns real traffic, scaling is a known, deliberate move — a bigger droplet (scale up) or another node in the Swarm (scale out) — not a surprise invoice. Own the box first; pay for scale only when the scale is real.

In a world where building is cheap and getting cheaper, the leverage is in owning where your work runs.