DEV Community

Jedsadakorn Suma
Jedsadakorn Suma

Posted on

I built a deploy template pack for vibe-coded apps — here's what's inside and how I made it

I kept repeating the same painful cycle: build something in Cursor, then spend 2-3 hours copy-pasting Dockerfiles,
debugging nginx SSL configs, and fixing GitHub Actions YAML before I could actually ship.

So I packaged everything into Vibe Deploy Kit.

## What I built

3 deployment template packs, each covering a different stack:

  • next-production-kit → Next.js 14+ to Vercel or self-hosted VPS
  • fastapi-deploy-kit → FastAPI + Python to Railway (free tier)
  • react-supabase-kit → React + Vite + Supabase to Vercel

## How I built it

Started by listing every file I was copy-pasting project to project. Turned out it was always the same ~5 files:

  1. Dockerfile (multi-stage, non-root user, Alpine base)
  2. docker-compose.yml (app + nginx services, healthcheck)
  3. nginx.conf (rate limiting, SSL, security headers, gzip)
  4. GitHub Actions workflow (preview on PR, prod on push to main)
  5. .env.example (every required variable documented)

## next-production-kit — the Dockerfile

Multi-stage build keeps the final image small. Non-root user for security:

  FROM node:20-alpine AS deps
  WORKDIR /app
  COPY package.json package-lock.json* pnpm-lock.yaml* yarn.lock* ./
  RUN \
    if [ -f package-lock.json ]; then npm ci; \
    elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
    else npm i; fi

  FROM node:20-alpine AS runner
  RUN addgroup --system --gid 1001 nodejs \
    && adduser --system --uid 1001 nextjs
  COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
  USER nextjs
  CMD ["node", "server.js"]
Enter fullscreen mode Exit fullscreen mode

Requires output: 'standalone' in next.config.js.

## fastapi-deploy-kit — rate limiting

The FastAPI kit uses slowapi so you don't get hammered on Railway's free tier:

  from slowapi import Limiter
  from slowapi.util import get_remote_address

  limiter = Limiter(key_func=get_remote_address)

  @app.get("/api/hello")
  @limiter.limit("30/minute")
  async def hello(request: Request):
      return {"message": "Hello"}
Enter fullscreen mode Exit fullscreen mode

## react-supabase-kit — the client setup

One thing vibe-coded apps almost never have is a proper ErrorBoundary. The kit includes one, plus a Supabase client
with auto-refresh:

  export const supabase = createClient(url, anonKey, {
    auth: {
      autoRefreshToken: true,
      persistSession: true,
      detectSessionInUrl: true,
    },
  });
Enter fullscreen mode Exit fullscreen mode

## nginx WebSocket config

If you're self-hosting Next.js, you need this or hot reload breaks:

  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
Enter fullscreen mode Exit fullscreen mode

## Tools used

  • Docker + nginx for self-hosted path
  • Vercel + Railway + Supabase for zero-cost cloud path
  • GitHub Actions for CI/CD
  • Gumroad for distribution

## Result

A ZIP you drop into any project. Fill in .env, push to main → deployed.

Available for $9: peachjed.gumroad.com/l/frosbp

Top comments (0)