Patet

Publish to the internet

Your app runs locally — now make it reachable. This guide helps you pick the right hosting, deploy your code, and get HTTPS working.

Your app runs great on localhost, but nobody else can reach it yet. To go live, the single most important decision is how you host it. Get that right and the rest is smooth; get it wrong and you'll burn time on ops you didn't need.

Let's make the three paths clear, walk the easiest one end to end, and then cover deploying your code, HTTPS, and the pitfalls that trip people up.

Three ways to go live

Almost every project fits into one of these three buckets. Find yours first, then read on.

ApproachBest forEffortCostScaling
Static hosting (Cloudflare Pages, Vercel, Netlify, GitHub Pages)Static pages, SPAs, SSG (Vite, Next.js static export, Astro, Hugo)Lowest — connect Git and goEffectively free (generous free tiers)Handled for you, global CDN
Serverless / PaaS (Vercel, Railway, Render, Fly.io)Apps with a backend but no server you want to manage (APIs, SSR, full-stack with a DB)Low — just set a build commandFree tier for trying, a few dollars/month in productionManaged; scale up or add instances with a click
Your own server (a VPS)Full control: custom runtimes, long-running processes, special ports, cost-sensitive always-on workloadsHigh — install everything, set up a reverse proxy, harden itFrom ~$4–6/month, fixed and predictableYou add machines and load balancers yourself

A quick way to decide:

  • No backend (pages, tools, docs, marketing) → use static hosting. It's the easiest.
  • A backend but you don't want to touch a server (full-stack apps, APIs) → use Serverless / PaaS.
  • You want full control, or to minimize long-term cost → run your own VPS. See Buy a server and Cheap cloud servers.

The simplest path: static sites

If your project builds into a folder of static files (HTML / CSS / JS), congratulations — going live takes minutes. Here's Cloudflare Pages (Vercel and Netlify are nearly identical).

Push your code to Git

Push your project to GitHub (or GitLab). The platform deploys by connecting to your repo, so the code has to live on a remote first.

git init
git add .
git commit -m "first deploy"
git remote add origin git@github.com:your-username/your-project.git
git push -u origin main

Connect the repo

Log into the Cloudflare Dashboard, go to Workers & Pages → Create → Pages → Connect to Git, authorize, and pick your repo.

Set the build command and output directory

This is the step people get wrong most often, so get it right:

  • Build command: npm run build (or pnpm build / bun run build, depending on your package manager)
  • Build output directory: the folder your framework puts the built static files in. Common values:
FrameworkOutput directory
Vitedist
Astrodist
Next.js (static export)out
Hugopublic
Create React Appbuild

Deploy

Click Save and Deploy. The platform pulls your code, runs the build, and publishes the output to a global CDN. When the green check appears, you get a *.pages.dev URL you can open right away.

Every push deploys automatically

Once it's set up, every git push to your main branch rebuilds and ships automatically. Edit, push, done — no manual steps after this.

Vercel and Netlify feel almost the same: connect Git → set build command and output directory → deploy. They'll often auto-detect common frameworks and guess the settings for you.

Apps with a backend

If your app needs a long-running process (handling API requests, talking to a database, running background jobs), static hosting alone won't cut it. You have two paths:

PaaS (Railway / Render / Fly.io) — try this first

  • You just write code; the platform runs the container, gives you a domain, sets up HTTPS, and shows you logs.
  • Connect a Git repo and deploy — as low-effort as static hosting.
  • Best for: full-stack apps, Node/Python/Go backends, projects that need a database.
  • Railway and Render can spin up a managed database (Postgres / Redis) alongside your app, so you don't install one yourself.
  • Downside: per-unit cost is higher than a VPS at scale, and there's some platform lock-in.

Your own VPS — when you want control or savings

  • You get a clean Linux box and do everything yourself: install the runtime, configure an Nginx reverse proxy, harden it.
  • Best for: running special software, long-term low-cost always-on workloads, or just learning ops.
  • For buying and setting one up, see Buy a server and Cheap cloud servers.

Which to choose

First time shipping and in a hurry? Use PaaS — you'll be live in minutes. Once you have a real sense of your traffic and costs, or you want full control, you can migrate to a VPS later.

Getting your code deployed

Whether you go PaaS or VPS, modern deployment follows the same core idea: Git-based deploys.

  1. Build command: after the platform pulls your code, it runs this to produce a runnable artifact.
  2. Output folder (dist / output): for static sites this is the built folder; for backend apps the platform runs your start command instead.
  3. Environment variables: secrets, database connection strings, third-party API keys — these must never be hardcoded. Set them in the platform dashboard.

A typical build + start flow looks like this:

# install dependencies (use the lockfile for reproducible versions)
npm ci

# build
npm run build

# start (backend apps; static sites skip this)
npm start

Never commit secrets to Git

Database passwords, API keys, JWT secrets — always go through environment variables, set in the platform dashboard. Don't write them into code or commit a .env file. Add .env to .gitignore. Once a secret lands in Git history, deleting it later doesn't help — it's effectively public.

On PaaS, open your project's Settings → Variables / Environment to add them. Read them in code via process.env.DATABASE_URL; use a local .env in development and platform variables in production — they don't interfere with each other.

HTTPS & custom domains

Good news: most platforms give you free HTTPS automatically. Cloudflare Pages, Vercel, Netlify, Railway, and Render all issue and renew certificates for you — you do nothing, and the site loads over https://.

Attaching a custom domain is easy too:

  1. Add your domain under the platform's Custom domains section.
  2. Add the CNAME (or A) record it tells you to in your DNS, pointing at the platform.
  3. Wait for the certificate to issue automatically (usually minutes), and your domain is live.

Common pitfalls

When a deploy breaks, check these first

  • Wrong output directory: deploy succeeds but you get a blank page / 404 — usually the output directory is wrong (e.g. build where it should be dist).
  • Missing env vars: you have a local .env but never set them in production, so the app crashes on startup when it can't read a secret. Re-check each platform variable.
  • Listening on the wrong port / host: in production, listen on the platform-injected process.env.PORT and bind to 0.0.0.0 (not localhost / 127.0.0.1), or nothing outside can connect.
  • Forgetting NODE_ENV=production: hurts performance and can surface bugs that only appear in production mode.
  • Builds locally but fails in CI: usually the lockfile isn't committed (use npm ci instead of npm install), or the Node version differs (pin it with .nvmrc or the engines field in package.json).

The right way to bind the port and host (Node example):

const port = process.env.PORT || 3000;
app.listen(port, "0.0.0.0", () => {
  console.log(`listening on ${port}`);
});

Checklist for this step

  • Decided on a path: static hosting / serverless·PaaS / your own VPS
  • Code pushed to Git, with the correct build command and output directory
  • All secrets set via environment variables — nothing hardcoded
  • App listens on process.env.PORT and binds to 0.0.0.0
  • Confirmed the site loads over https:// and your custom domain works

See the full launch checklist.

On this page