Courses/Deployment Guide
Standalone Course~30 min14 challenges

Deployment Guide: Dokploy, Orbita, VPS & Vercel

Your app works locally. Now you need to put it on the internet. In this course, you will learn four deployment methods — from the simplest one-command deploy to full PaaS setups — so you can choose the right approach for your project.


Deployment Options Overview

Grit apps can be deployed in multiple ways depending on your needs, budget, and technical comfort level. Here are the four methods you will learn:

MethodWhat It IsBest For
grit deployDirect VPS deployment via SCPQuick deploys, solo developers
DokploySelf-hosted PaaS with web UITeams, auto-deploy on push
OrbitaGrit-native deployment platformGrit projects, seamless integration
VercelManaged hosting for Next.jsNext.js frontend (API on VPS)
All four methods assume you have a VPS (Virtual Private Server) for the Go API. You can get one for $4-6/month from providers like Hetzner, DigitalOcean, or Linode. Vercel is the only method where part of your app runs on managed infrastructure.
1

Challenge: Choose Your Factors

What factors would you consider when choosing a deployment method? Think about: cost, complexity, automation, team size, frequency of deploys, and whether you want a web UI to manage your server.

Method 1: grit deploy (Direct VPS)

The simplest deployment method. One command builds your app, uploads it to your server, and configures everything automatically:

Terminal
grit deploy --host deploy@server.com --domain myapp.com

Here's what grit deploy does behind the scenes:

  • 1. Builds the Go binary — cross-compiles for Linux (your server's OS)
  • 2. Uploads via SCP — securely copies the binary to your server
  • 3. Creates a systemd service — so your app auto-restarts on crash or reboot
  • 4. Configures Caddy — reverse proxy with automatic HTTPS (Lets Encrypt)
  • 5. Starts the service — your app is live at your domain
systemd Service: A Linux background process manager. When you register your app as a systemd service, the operating system ensures it stays running — restarting it automatically if it crashes or when the server reboots. Think of it as a "keep alive" system for your app.
Caddy: A modern web server and reverse proxy that automatically manages HTTPS certificates via Lets Encrypt. It sits in front of your Go app, handles SSL termination, and forwards requests to your app on its internal port. Zero SSL configuration needed.
Before your first deploy, make sure you can SSH into your server: ssh deploy@server.com. If that works, grit deploy will work too.
2

Challenge: List the Deploy Steps

Without looking above, list the 5 steps that grit deploy performs. For each step, explain why it's necessary.

Method 2: Dokploy

Dokploy: A self-hosted Platform as a Service (PaaS) you install on your own VPS. It gives you a Heroku-like experience — connect a GitHub repo, push code, and Dokploy builds and deploys automatically. It runs Docker containers behind the scenes and provides a web dashboard for managing your apps, databases, domains, and SSL certificates. Free and open-source. Website: https://dokploy.com

While grit deploy is a one-time push, Dokploy gives you a full deployment pipeline:

  • Git push to deploy — Dokploy watches your repo and auto-deploys on push
  • Web dashboard — manage apps, view logs, set environment variables from a browser
  • Docker-based — each app runs in an isolated container
  • Auto-SSL — HTTPS certificates managed automatically
  • Database management — spin up PostgreSQL, Redis, and more from the UI

To set up Dokploy on your VPS:

Terminal (on your VPS)
# Install Dokploy (one command)
curl -sSL https://dokploy.com/install.sh | sh

After installation, access the Dokploy dashboard at https://your-server-ip:3000. From there, connect your GitHub account, select your repository, and Dokploy handles the rest.

3

Challenge: Explore Dokploy

Visit dokploy.com. What features does it offer? How does it compare to Heroku or Railway? What databases can it manage?

Dokploy Configuration

Dokploy uses Docker to build and run your app. Grit scaffolds a production-ready Dockerfile that uses multi-stage builds to keep the final image small:

Dockerfile
# Stage 1: Build the Go binary
FROM golang:1.24 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server ./cmd/server

# Stage 2: Create a minimal runtime image
FROM alpine:latest
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]
Multi-Stage Build: A Docker technique that uses multiple FROM statements in a single Dockerfile. The first stage (builder) has all the build tools — Go compiler, source code, dependencies. The final stage only contains the compiled binary. This dramatically reduces the image size: the builder stage might be 1 GB, but the final image is only 15-20 MB.

For the full stack (API + database + Redis), use the production Docker Compose file:

docker-compose.prod.yml
version: '3.8'
services:
  api:
    build: .
    ports:
      - "8080:8080"
    env_file: .env
    depends_on:
      - db
      - redis
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: myapp
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
  redis:
    image: redis:7-alpine
    volumes:
      - redisdata:/data
volumes:
  pgdata:
  redisdata:

In Dokploy, you can configure environment variables through the web UI instead of managing.env files on the server. Set your database credentials, JWT secret, API keys, and other sensitive values securely through the dashboard.

4

Challenge: Read the Dockerfile

Look at the Dockerfile above. What's the difference between the builder stage and the final stage? Why does the final stage use alpine:latest instead of golang:1.24? What would happen to the image size if you used only one stage?

Method 3: Orbita

Orbita: A deployment and server management platform created by the same developer who built Grit (MUKE-coder). It's designed to work seamlessly with Grit projects — understanding the project structure, environment variables, and deployment patterns out of the box. Open-source and self-hosted. GitHub: https://github.com/MUKE-coder/orbita

Orbita is purpose-built for Grit's ecosystem. While Dokploy is a general-purpose PaaS, Orbita understands Grit conventions:

  • One-click deploy — connect your server, select a Grit project, deploy
  • Auto-SSL — HTTPS certificates managed automatically via Lets Encrypt
  • Environment management — configure production .env through the UI
  • Log viewing — stream application logs from the dashboard
  • Server management — manage multiple servers and apps from one place

The deployment flow with Orbita:

  • 1. Install Orbita on your VPS (or use a separate management server)
  • 2. Add your server's SSH credentials in the Orbita dashboard
  • 3. Connect your GitHub repository
  • 4. Configure environment variables and domain
  • 5. Click Deploy — Orbita builds and ships your app
5

Challenge: Explore Orbita

Visit the Orbita GitHub repo at https://github.com/MUKE-coder/orbita. What deployment features does it support? How does the setup process compare to Dokploy?

Orbita vs Dokploy

Both are self-hosted PaaS tools, but they serve slightly different purposes:

FeatureOrbitaDokploy
Grit integrationNative — built for GritGeneric — works with any Docker app
EcosystemSame creator as GritIndependent project
Use caseGrit-first deploymentAny Docker-based app
Web UIYesYes
Auto-SSLYesYes
Database managementYesYes (more options)
If you're deploying only Grit apps and want the tightest integration, use Orbita. If you're managing multiple projects (some non-Grit) on the same server, Dokploy's broader compatibility may be more useful.
6

Challenge: Compare the Two

You have 3 apps to deploy: a Grit SaaS, a Python Flask API, and a static marketing site. Which deployment tool (Orbita or Dokploy) would you use for each, and why?

Method 4: Vercel (Frontend Only)

For Triple or Double architecture projects with a Next.js frontend, you can deploy the frontend to Vercel while keeping the Go API on your VPS. This gives you the best of both worlds — Vercel's CDN and edge network for the frontend, your own server for the API.

Terminal
# Step 1: Deploy the Go API to your VPS
grit deploy --host deploy@server.com --domain api.myapp.com

# Step 2: Deploy the Next.js frontend to Vercel
cd apps/web && vercel

The critical configuration step: tell the Vercel-hosted frontend where to find your API. In Vercel's dashboard, set this environment variable:

Vercel Environment Variables
NEXT_PUBLIC_API_URL=https://api.myapp.com
This split deployment only works with Next.js frontends. If you're using TanStack Router (Vite), the frontend is embedded in the Go binary via go:embed and served by the Go server directly. There's nothing to deploy to Vercel.

Advantages of the Vercel + VPS split:

  • Global CDN — frontend served from edge nodes closest to the user
  • Automatic previews — every PR gets a preview deployment URL
  • Zero-config — Vercel auto-detects Next.js and configures everything
  • Free tier — generous free plan for personal projects
7

Challenge: The Connection Point

What environment variable connects the Vercel frontend to your API? Why does the variable name start with NEXT_PUBLIC_? What would happen if you forgot to set it?

DNS Configuration

DNS (Domain Name System): The system that translates human-readable domain names (like myapp.com) into IP addresses (like 167.99.100.50) that computers use to find each other on the internet. When you type a URL in your browser, DNS looks up the IP address for that domain and connects you to the right server.

After buying a domain, you need to point it at your server by creating DNS records in your domain registrar's dashboard (Namecheap, Cloudflare, GoDaddy, etc.):

TypeNameValuePurpose
A@167.99.100.50Root domain (myapp.com)
Aapi167.99.100.50API subdomain (api.myapp.com)
CNAMEwwwmyapp.comwww subdomain redirects to root
DNS changes can take up to 48 hours to propagate worldwide, but usually take 5-30 minutes. You can check propagation status at dnschecker.org.
8

Challenge: Plan Your DNS Records

If your server IP is 167.99.100.50 and your domain is myapp.com, what DNS records would you create for: (1) the main site at myapp.com, (2) the API at api.myapp.com, (3) www.myapp.com redirecting to myapp.com?

Production Environment Variables

Your development .env file has placeholder values that are not safe for production. Before deploying, you need to update several critical variables:

.env (production)
# App
APP_ENV=production
APP_PORT=8080

# Database
DB_DRIVER=postgres
DB_HOST=localhost
DB_PORT=5432
DB_USER=myapp
DB_PASSWORD=<strong-random-password>
DB_NAME=myapp_production

# Auth
JWT_SECRET=<64-character-random-string>

# Storage
STORAGE_DRIVER=s3
S3_BUCKET=myapp-uploads
S3_REGION=us-east-1
S3_ACCESS_KEY=<your-access-key>
S3_SECRET_KEY=<your-secret-key>

# Email
RESEND_API_KEY=re_<your-real-key>
EMAIL_FROM=noreply@myapp.com

# Redis
REDIS_URL=redis://localhost:6379

Critical changes from development to production:

  • APP_ENV — set to production (disables debug logging, enables security headers)
  • JWT_SECRET — must be a long, random string (not "secret" or "changeme")
  • DB_PASSWORD — a strong, unique password (not "password")
  • STORAGE_DRIVER — switch from local to S3, R2, or B2 for persistent file storage
  • RESEND_API_KEY — your real Resend API key (development uses Mailhog)
Generate strong random strings for JWT_SECRET and passwords using: openssl rand -hex 32
9

Challenge: Write a Production .env

Write a complete production .env file for your app. Use placeholder values (not real secrets), but make sure every required variable is present. How many variables changed from your development .env?

SSL/TLS Certificates

SSL/TLS Certificate: A digital certificate that encrypts the connection between a user's browser and your server. It's what makes the padlock icon appear in the browser's address bar and enables HTTPS (instead of HTTP). Without SSL, data (including passwords) is transmitted in plain text and can be intercepted.

The good news: you almost never need to manage SSL certificates manually. Each deployment method handles it automatically:

  • grit deploy — Caddy auto-provisions Lets Encrypt certificates
  • Dokploy — built-in Lets Encrypt support through the dashboard
  • Orbita — automatic SSL certificate management
  • Vercel — SSL included automatically for all deployments
Lets Encrypt: A free, automated certificate authority that provides SSL/TLS certificates at no cost. Before Lets Encrypt (launched 2015), SSL certificates cost $50-200/year. Now, tools like Caddy and Dokploy automatically request, install, and renew certificates from Lets Encrypt with zero configuration.
10

Challenge: Check Your SSL

After deploying your app, visit https://www.ssllabs.com/ssltest/ and enter your domain. What grade does your site receive? An A or A+ is expected with Caddy's default configuration.

Monitoring After Deployment

Deploying your app is only half the job. You also need to know when something goes wrong. There are two types of monitoring:

Application Monitoring: Internal monitoring that tracks your app's performance and errors from the inside. Metrics like response times, error rates, database query speed, and memory usage. Grit's Pulse feature provides this — it's a built-in dashboard that shows your app's health.
Uptime Monitoring: External monitoring that checks whether your app is reachable from the outside. A service pings your app's URL every few minutes and alerts you (via email, SMS, or Slack) if it's down. Think of it as a friend who checks your website every minute and calls you if it's broken.

Recommended monitoring setup:

  • Pulse — built into Grit, shows response times, error rates, and active connections
  • UptimeRobot (free) — pings your health endpoint every 5 minutes, alerts on downtime
  • Better Stack (free tier) — uptime monitoring + incident management + status pages

Every Grit app has a health endpoint at /api/health that returns the app's status. Point your uptime monitor at this endpoint.

11

Challenge: Set Up Uptime Monitoring

Create a free account at uptimerobot.com. Add a monitor for your deployed API's health endpoint (https://api.myapp.com/api/health). Set the check interval to 5 minutes. What alerts did you configure?

What You Learned

  • Four deployment methods: grit deploy, Dokploy, Orbita, and Vercel
  • How grit deploy builds, uploads, and configures your app in one command
  • Dokploy as a self-hosted PaaS with Docker and auto-deploy
  • Orbita as a Grit-native deployment platform
  • Splitting frontend (Vercel) and API (VPS) deployment
  • DNS configuration for domains and subdomains
  • Production environment variables and security
  • Automatic SSL with Lets Encrypt
  • Monitoring with Pulse and uptime services
12

Challenge: Deploy End-to-End

Choose ONE deployment method and deploy a Grit app from start to finish:

  1. Scaffold a project with grit new deploy-test --double --next
  2. Generate at least one resource
  3. Deploy using your chosen method
  4. Configure DNS for your domain
  5. Verify HTTPS works
  6. Set up uptime monitoring
  7. Document every step you took
13

Challenge: Compare Two Methods

Deploy the same app using two different methods (e.g., grit deploy and Dokploy). Compare the experience: setup time, ease of re-deployment, log access, and environment variable management. Which do you prefer and why?

14

Challenge: Production Checklist

Create a deployment checklist for your team. Include: environment variables to change, DNS records to create, SSL verification, uptime monitoring setup, and a rollback plan. Would this checklist change depending on the deployment method?