TL;DR: CapRover simplifies deployment. Build a Docker image, add a captain-definition file, push to your VPS, and deploy via CLI. Your Astro site runs behind Nginx with automatic HTTPS in minutes. Perfect alternative to Vercel if you prefer self-hosted control.

What is CapRover?

CapRover is a Platform-as-a-Service (PaaS) platform you run on your own VPS. It handles:

  • Docker container orchestration
  • Automatic SSL/TLS with Let’s Encrypt
  • Automatic Nginx reverse proxy
  • Simple deployment via Git push or CLI
  • Persistent volumes and environment variables
  • One-click app deployment

Think of it as “Heroku on your VPS.” You get the convenience of Vercel/Netlify but with full control and lower cost (just VPS fees, no per-app costs).

Prerequisites

Before you start, you need:

  1. A VPS running a supported OS (Ubuntu 20.04+ recommended)

    • DigitalOcean, Linode, AWS EC2, etc.
    • SSH access to root or sudo user
    • At least 2GB RAM, 10GB disk minimum
  2. A domain name (if you want a custom domain)

  3. Docker knowledge (basic understanding of images and containers)

  4. Git installed locally

Step 1: Install CapRover on Your VPS

SSH into your VPS:

ssh deploy@your-vps-ip

Install CapRover (as root or with sudo):

# Download and run the installation script
curl -fsSL https://raw.githubusercontent.com/caprover/caprover/master/scripts/install.sh | sudo /bin/bash

# Wait for installation to complete (5-10 minutes)

After installation, CapRover tells you the login URL:

CapRover is installed successfully!
CapRover is running at http://your-vps-ip:3000
Default password: captain42

Step 2: Access CapRover Dashboard and Configure

Open http://your-vps-ip:3000 in your browser.

First login:

  • Username: captain
  • Password: captain42 (change this immediately in Settings)

Configure your domain:

  1. Go to Settings (⚙️ icon)
  2. Enter your root domain: example.com
  3. CapRover will configure automatic HTTPS via Let’s Encrypt

Create an API token for CLI:

  1. Settings → API Tokens
  2. Create a new token
  3. Copy the token (you’ll use it in CLI)

Step 3: Prepare Your Astro Project for CapRover

Create a captain-definition file in your project root. This tells CapRover how to build and run your app:

{
  "schemaVersion": 2,
  "containerName": "personal-blog",
  "imageName": "personal-blog:latest",
  "dockerfileLines": [
    "FROM node:18-alpine AS builder",
    "WORKDIR /app",
    "COPY package*.json ./",
    "RUN npm ci",
    "COPY . .",
    "RUN npm run build",
    "",
    "FROM node:18-alpine",
    "WORKDIR /app",
    "RUN npm install -g serve",
    "COPY --from=builder /app/dist ./dist",
    "EXPOSE 3000",
    "HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\",
    "  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1",
    "CMD [\"serve\", \"-s\", \"dist\", \"-l\", \"3000\"]"
  ]
}

Alternative: If you already have a Dockerfile, reference it instead:

{
  "schemaVersion": 2,
  "containerName": "personal-blog",
  "imageName": "personal-blog:latest",
  "dockerfilePath": "./Dockerfile"
}

Commit this file to Git:

git add captain-definition
git commit -m "Add CapRover deployment config"
git push origin main

Step 4: Install CapRover CLI

On your local machine:

npm install -g caprover

Log in to your CapRover instance:

caprover login

When prompted:

  • Hostname: your-vps-ip or captain.example.com
  • API Token: Paste the token from Step 2

CapRover saves credentials locally.

Step 5: Create an App in CapRover

In the CapRover dashboard:

  1. Click “New App”
  2. Enter app name: blog (becomes blog.example.com)
  3. Click “Create New App”
  4. In app settings:
    • Enable HTTPS: Yes
    • Set domain: blog.example.com or your preferred subdomain

Step 6: Deploy via CLI

From your project root (where captain-definition is):

# Deploy the app
caprover deploy

# When prompted:
# - Select the app: blog
# - Confirm deployment: yes

CapRover will:

  1. Build the Docker image
  2. Push to the in-VPS registry
  3. Run the container
  4. Configure Nginx
  5. Deploy HTTPS certificate

Watch the logs in the dashboard or CLI. Deployment usually takes 2-3 minutes.

After success, visit https://blog.example.com—your site is live.

Step 7: Configure App Settings (Optional)

In CapRover dashboard, app settings:

Enable “Persistent Directories” (if you need persistent storage):

  • Path: /app/data
  • Mount point: Optional

Environment Variables:

  • No env vars needed for a static Astro site, but you can add them for:
    • Build arguments
    • Future backend integrations

SSL/HTTPS:

  • Auto-generated via Let’s Encrypt
  • Renews automatically

Step 8: Automate Deployments with GitHub Actions

Create .github/workflows/deploy-caprover.yml:

name: Deploy to CapRover

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Install CapRover CLI
        run: npm install -g caprover

      - name: Deploy to CapRover
        run: |
          caprover deploy \
            --caproverUrl "https://captain.example.com" \
            --caproverPassword "${{ secrets.CAPROVER_PASSWORD }}" \
            --appName "blog" \
            --imageName "personal-blog:latest"
        env:
          CAPROVER_URL: "https://captain.example.com"

Set GitHub Secret:

  1. Repository → Settings → Secrets and variables → Actions
  2. New Repository Secret:
    • Name: CAPROVER_PASSWORD
    • Value: Your CapRover API token

Now every push to main automatically deploys.

Step 9: Set Up Custom Domain

If you have a domain (example.com), point it to your VPS:

Update DNS records:

A record: example.com → your-vps-ip
A record: *.example.com → your-vps-ip  (wildcard for subdomains)

Wait for DNS to propagate (can take minutes to hours).

In CapRover app settings, update HTTP domain to blog.example.com.

Monitoring and Maintenance

Check app logs:

  • Dashboard: App page → View Logs

Monitor resources:

  • Dashboard: Monitoring tab (CPU, memory, disk)

Backup:

  • CapRover doesn’t backup databases (you don’t have any for a static site)
  • Backup your code in Git (you already do)
  • Backup VPS files periodically (manual SSH or automated rsync)

Update CapRover:

  • Dashboard: Settings → Update CapRover
  • Usually safe; test on staging first if critical

Troubleshooting

App won’t start:

  • Check logs in dashboard
  • Common cause: port not exposed in Dockerfile
  • Ensure EXPOSE 3000 is in Dockerfile

Certificate errors:

  • Wait 5 minutes for Let’s Encrypt to issue
  • Check domain DNS resolves to VPS IP

Slow deploys:

  • First deploy builds image from scratch (slow)
  • Subsequent deploys re-use cache (faster)
  • Building takes 2-3 minutes, expected

App exits immediately:

  • Often a startup error
  • Check logs: Dashboard → App → View Logs
  • Common: missing dependencies (ensure npm ci runs in Dockerfile)

Cost Comparison

CapRover (self-hosted):

  • VPS: $5-20/month (DigitalOcean, Linode, etc.)
  • Total: $5-20/month for unlimited apps

Vercel/Netlify:

  • Free tier: OK for small projects
  • Pro: $20/month per account
  • Team: $35+ per team member

For a personal blog, CapRover is cheaper. For multiple projects, it’s significantly better value.

Summary: Deploy from Git Push

Once set up, your workflow is simple:

# Make changes
echo "New post" >> content.md

# Push to main
git add content.md
git commit -m "Add new post"
git push origin main

# GitHub Actions triggers automatically
# Your blog updates live in 3-5 minutes

No manual deployments, no secrets in your code, full control of your infrastructure.

Next Steps

  • Backup strategy: Set up automated VPS snapshots
  • Multiple apps: Deploy other projects to same CapRover instance
  • Custom Nginx config: CapRover allows per-app Nginx rules
  • Email alerts: Set up monitoring for app downtime

CapRover is powerful enough for production but simple enough to use daily. It’s a solid choice for engineers who want control without the overhead of manual Docker/Kubernetes management.