Shipping Web Apps to a VPS Should Be This Simple

Published: (May 2, 2026 at 08:12 PM EDT)
4 min read
Source: Dev.to

Source: Dev.to

Why deploying to a VPS still feels complicated

I like servers—not in a “let me spend Saturday hand‑tuning nginx” way, but in a “this $6 VPS could probably run half my side projects” way.
For many small and medium web apps, the app itself isn’t the hard part; the surrounding chores are:

  • building the app
  • getting it onto the server
  • starting it without dropping requests
  • setting up HTTPS
  • keeping secrets out of random .env files
  • seeing logs without SSH archaeology
  • making local dev resemble production so cookies and OAuth stop being weird

None of this is impossible; it’s just a stack of little tasks. That stack is why I started working on Tako.

Introducing Tako

Tako aims to make deployment feel as simple as:

tako init
tako deploy

Not because two commands are magical, but because most apps don’t need a custom infrastructure thesis before they can serve HTTP.

Tako is a CLI plus a tiny server runtime. You install the server once on your VPS, add that server locally, then deploy from your project directory.

Deploy flow

The flow is intentionally plain:

  1. Build locally
  2. Package the output
  3. Upload it over SSH/SFTP
  4. Unpack it on the server
  5. Start the new version
  6. Roll traffic over without dropping the old version first

No registry. No image push. No Kubernetes object graph. No “where did this container layer come from?” moment at 1 AM.

Runtime and proxy model

Tako runs your app as a normal process. For JavaScript and TypeScript apps there’s a small tako.sh SDK. Your app tells Tako when it’s ready by reporting the port it bound to, after which the server proxy can safely route traffic to it.

In production:

  • App instances bind to 127.0.0.1 on an assigned port.
  • Tako’s proxy sits in front, handles the public route, and forwards requests only to healthy instances.

Benefits

  • Rolling deploys can start a new instance before removing the old one.
  • Low‑traffic apps can opt into scale‑to‑zero.
  • Logs and status are attached to the process Tako actually started.
  • The app doesn’t need to know the public port or hostname.

Configuration

The config is meant to stay boring too:

name = "my-app"
runtime = "bun"
preset = "tanstack-start"

[build]
run = "bun run build"

[envs.production]
route = "my-app.example.com"
servers = ["main"]

More options are available when you need them (multiple environments, servers, build stages, release commands, secrets, scale settings), but the basic shape is just “here is my app, here is where it should run.”

Local development

Most deploy tools stop at production, leaving you with a mess of ports:

  • http://localhost:3000
  • http://localhost:5173
  • http://localhost:8787

When you need secure cookies, OAuth callbacks, service workers, a second app, or a webhook tunnel, your local setup suddenly gets its own personality.

tako dev tries to make local apps feel like real apps:

tako dev

It gives your app a .test domain with HTTPS, DNS, and a local proxy. Instead of remembering a port, you open something like:

https://my-app.test/

The goal isn’t to be fancy; it’s to remove the tiny paper cuts that make local dev drift away from production.

When Docker makes more sense

  • If your app needs heavy OS‑level isolation, containers might be the better answer.
  • If your team already has a container pipeline that works, you probably shouldn’t throw it away for fun.
  • If you’re running a bunch of unrelated stacks with weird system packages, Docker is a reasonable boundary.

Tako is more opinionated: it focuses on common web‑app runtimes like Bun, Node, and Go, then tries to make that path fast and calm. That trade‑off is the whole point.

Getting started

The project is open source. Docs are here:

Quick install

curl -fsSL https://tako.sh/install.sh | sh
tako init
tako dev

Deploy to a server

sudo sh -c "$(curl -fsSL https://tako.sh/install-server.sh)"
tako servers add 
tako deploy
0 views
Back to Blog

Related posts

Read more »