Command Palette

Search for a command to run...

Blog
PreviousNext

Self-Hosting Next.js with Contabo VPS and Dokploy: A Step-by-Step Guide

Learn how to self-host your Next.js applications on Contabo VPS using Dokploy. A cost-effective, high-performance alternative to Vercel with push-to-deploy, automatic SSL, and multi-app support.

Self-Hosting Next.js Apps with Contabo VPS and Dokploy

Self-hosting your Next.js applications doesn't have to be complicated or expensive. In this guide, we'll walk through setting up a professional-grade deployment pipeline using Contabo VPS and Dokploy.

[!NOTE] This setup provides a Vercel-like experience (push-to-deploy, automatic SSL, dashboard) at a fraction of the cost, giving you full control over your infrastructure.


📋 Table of Contents

  1. Why This Setup?
  2. Contabo VPS vs. Alternatives
  3. Contabo VPS Plans
  4. Prerequisites
  5. Step 1: Setting Up Your Contabo VPS
  6. Step 2: Installing Dokploy
  7. Step 3: Connecting GitHub to Dokploy
  8. Step 4: Deploying Your Next.js App
  9. Step 5: Custom Domains and SSL
  10. Step 6: Add Analytics with Umami
  11. Step 7: Hosting a Database
  12. Troubleshooting
  13. Scaling Your Setup

What You'll Get

By the end of this guide, you'll have:

  • ✅ A Contabo VPS server running Ubuntu
  • Dokploy managing your deployments with a clean dashboard
  • Automatic deployments triggered by GitHub pushes
  • SSL certificates via Traefik + Let's Encrypt
  • Multiple apps running on a single VPS
  • Cost: ~$5–$8/month vs $20–$100+ on managed platforms

🚀 Why This Setup?

BenefitDescription
💰 Cost EffectiveContabo offers high specs (up to 6 vCPU & 12 GB RAM) starting at ~$8/month.
🎓 EducationalGain deep understanding of server management and DevOps.
📦 ScalableEasily host multiple apps, databases, and services on a single node.
🔓 No Lock-inFull root access gives you total control over your deployment environment.

📊 Contabo VPS vs. Alternatives

FeatureContabo + DokployVercelRailway
Monthly Cost~$8$20+ (Pro)$5–$20+
Multiple Apps✅ Unlimited⚠️ Limited⚠️ Limited
Automatic SSL✅ Included✅ Included✅ Included
Push-to-Deploy✅ GitHub✅ GitHub✅ GitHub
Database Hosting✅ Same server❌ Separate✅ Add-on
Full Root Access✅ Yes❌ No❌ No
TrafficUnlimitedLimitedLimited

📑 Contabo VPS Plans

PlanvCPURAMStoragePrice/mo
Cloud VPS 103 vCPU8 GB75 GB NVMe~$5
Cloud VPS 20 ★6 vCPU12 GB200 GB NVMe~$8
Cloud VPS 308 vCPU24 GB300 GB NVMe~$15

[!TIP] > Cloud VPS 20 is the sweet spot. It provides enough power to run 5+ Next.js apps, a PostgreSQL instance, and analytics without breaking a sweat.


Prerequisites

  • Basic terminal / command line knowledge
  • A GitHub account with your Next.js project
  • A domain name (optional but required for SSL)
  • A credit card for Contabo (~$5–$8/month)

Step 1: Setting Up Your Contabo VPS

1.1 Create a Contabo Account

  1. Visit contabo.com/en/vps
  2. Click "Get Started" under your chosen plan
  3. Create an account and verify your email
  4. Add a payment method (credit card or PayPal)
  5. Complete the order — Contabo will email you your server credentials within minutes

Note: Contabo sends your root password via email after provisioning. Keep it safe.


1.2 Generate an SSH Key

Before connecting to your server, generate a secure SSH key on your local machine.

On Mac / Linux:

ssh-keygen -b 4096 -t rsa -C "your-email@example.com"

Get your public key:

cat ~/.ssh/id_rsa.pub

Copy the entire output — you'll need it shortly.

On Windows (PowerShell):

ssh-keygen -b 4096 -t rsa
type $env:USERPROFILE\.ssh\id_rsa.pub

1.3 Access Your Server for the First Time

Contabo will email you:

  • IP address of your server
  • Root password

SSH into the server using the password:

ssh root@YOUR_SERVER_IP

Accept the fingerprint prompt by typing yes. You'll be asked to change your root password on first login — do it immediately.


Once logged in, add your SSH public key so you can log in without a password:

mkdir -p ~/.ssh
echo "YOUR_PUBLIC_KEY_HERE" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Now you can log in with just:

ssh root@YOUR_SERVER_IP

1.5 Update Your Server

Always update your packages after first login:

apt update && apt upgrade -y

Step 2: Installing Dokploy

2.1 Run the Dokploy Installer

While still SSH'd into your server, run the official Dokploy install script:

curl -fsSL https://dokploy.com/install.sh | sh

This installer will:

  • Install Docker and Docker Compose
  • Set up Traefik as a reverse proxy (handles SSL automatically)
  • Configure the Dokploy dashboard
  • Take approximately 1–3 minutes

2.2 Access the Dokploy Dashboard

Once the install completes, you'll see a URL in the terminal output.

  1. Open your browser and visit:
http://YOUR_SERVER_IP:3000
  1. You'll be prompted to create your admin account:
    • Choose a strong username
    • Set a secure password
    • This is your main Dokploy admin account

2.3 Enable Two-Factor Authentication

  1. Go to Settings in the Dokploy dashboard.
  2. Navigate to Security.
  3. Enable 2FA using an authenticator app (Google Authenticator, Authy, etc.).

[!IMPORTANT] Always enable 2FA on any dashboard exposed to the public internet to prevent unauthorized access.


Step 3: Connect GitHub to Dokploy

3.1 Create a GitHub App

  1. In the Dokploy dashboard, navigate to Settings → Git
  2. Click "Connect GitHub"
  3. Click "Create GitHub App"
  4. Choose a unique app name, e.g.:
dokploy-yourusername-2024

GitHub app names must be globally unique — add random digits if needed.


3.2 Install the GitHub App

  1. After creating the app, click "Install"
  2. Select the GitHub account / organization
  3. Choose:
    • All repositories — for full access, or
    • Select repositories — for specific repos only
  4. Complete the authorization

3.3 Verify the Connection

Go back to Dokploy. Your GitHub repositories should now be visible in dropdowns throughout the dashboard. If they don't appear immediately, wait 30 seconds and refresh.


Step 4: Deploy Your Next.js Application

4.1 Prepare Your Next.js Project

If you don't have a project yet, create one:

pnpm create next-app@latest my-dokploy-app
cd my-dokploy-app

Push it to GitHub:

git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/yourusername/my-dokploy-app.git
git push -u origin main

4.2 Create a Project in Dokploy

  1. In the Dokploy dashboard, click "Create Project"
  2. Enter a name: my-nextjs-app
  3. Click "Create"

4.3 Add an Application Service

  1. Inside your project, click "Add a Service"
  2. Select "Application" (not Template or Database)
  3. Name it: next-frontend
  4. Click "Create"

4.4 Configure the Application

Repository Settings:

FieldValue
RepositorySelect your GitHub repo
Branchmain
Build Path/ (root)
Build PackNext
Port3000

Domain:

  • Click "Generate" for a random test subdomain, or
  • Enter your own: https://myapp.yourdomain.com

⚠️ HTTPS / SSL only works with a proper domain name, not with an IP address.

Environment Variables (if needed):

NEXT_PUBLIC_API_URL=https://api.yourdomain.com
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
NODE_ENV=production

4.5 Deploy the Application

  1. Click "Save" to store your configuration
  2. Click "Deploy"
  3. Watch the build logs in real time
  4. Wait for the "Deployment successful" message (typically 1–3 minutes)

4.6 Test Auto-Deployment (Push-to-Deploy)

Make a small change and push to GitHub:

# App Router
cat > app/page.tsx << 'EOF'
export default function Home() {
  return <h1>Hello from Contabo + Dokploy! 🚀</h1>;
}
EOF
 
git add .
git commit -m "Test auto-deploy"
git push origin main

Dokploy will automatically detect the GitHub push via webhook and trigger a new deployment. Check the "Deployments" tab — it should show as "webhook" initiated.


Step 5: Configure a Custom Domain and SSL

5.1 Point Your Domain to the Server

In your DNS provider (Cloudflare, Namecheap, etc.), add the following A records:

RecordHostValue
A@YOUR_SERVER_IP
A*YOUR_SERVER_IP
AwwwYOUR_SERVER_IP

DNS propagation can take 5–60 minutes.


  1. Add your domain to Cloudflare
  2. Update your domain's nameservers to Cloudflare's
  3. Add your server IP as an A record
  4. Enable "Proxied" (orange cloud) for DDoS protection

5.3 Set Custom Domain in Dokploy

  1. Go to your application in Dokploy
  2. Under "Domains", replace the generated subdomain with your real domain:
https://myapp.yourdomain.com
  1. Save the settings
  2. Dokploy + Traefik will automatically generate an SSL certificate via Let's Encrypt

✅ Your app is now live at https://myapp.yourdomain.com with a valid SSL certificate.


Step 6: Add Analytics with Umami (Optional)

6.1 Deploy Umami from a Dokploy Template

  1. Inside your project, click "Add a Service"
  2. Select "Template"
  3. Find and select "Umami"
  4. Name it: analytics
  5. Set a domain: analytics.yourdomain.com
  6. Click "Deploy"

6.2 Configure Umami

  1. Visit your Umami URL after deployment
  2. Log in with default credentials:
    • Username: admin
    • Password: umami
  3. ⚠️ Change the password immediately under Settings → Profile

6.3 Add Your Website to Umami

  1. In Umami → Settings → Websites
  2. Click "Add Website"
  3. Enter:
    • Name: Your app name
    • Domain: https://myapp.yourdomain.com
  4. Go to the Tracking Code tab and copy the script

6.4 Integrate Umami into Your Next.js App

App Router (app/layout.tsx):

import Script from "next/script";
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        <Script
          async
          src="https://analytics.yourdomain.com/script.js"
          data-website-id="YOUR_WEBSITE_ID"
          strategy="afterInteractive"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

Pages Router (pages/_app.tsx):

import Script from "next/script";
import type { AppProps } from "next/app";
 
export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Script
        async
        src="https://analytics.yourdomain.com/script.js"
        data-website-id="YOUR_WEBSITE_ID"
        strategy="afterInteractive"
      />
      <Component {...pageProps} />
    </>
  );
}

Commit and push — Dokploy will auto-deploy with analytics enabled.


Step 7: Hosting a Database (PostgreSQL / MySQL)

7.1 Add a Database Service in Dokploy

  1. Inside your project, click "Add a Service"
  2. Select "Database"
  3. Choose PostgreSQL (or MySQL / MongoDB)
  4. Set a name: postgres-db
  5. Configure:
    • Database name
    • Username
    • Password (use a strong password)
  6. Click "Create"

7.2 Connect Your Next.js App to the Database

Dokploy will show you the internal connection string. Add it to your app's environment variables:

DATABASE_URL=postgresql://username:password@postgres-db:5432/mydb

Internal service names (e.g., postgres-db) are used instead of localhost when connecting between Dokploy services on the same server.


Step 8: Monitor Your Server

8.1 Dokploy Built-in Monitoring

Dokploy provides a built-in monitoring panel showing:

  • CPU usage per container
  • Memory consumption
  • Disk I/O
  • Network traffic

Access it via the "Monitoring" tab in your dashboard.


8.2 SSH-Based Monitoring

SSH into your server for real-time resource inspection:

ssh root@YOUR_SERVER_IP
 
# Real-time CPU and memory
htop
 
# Disk space
df -h
 
# Docker containers
docker ps
 
# Container logs
docker logs <container_id>
 
# Resource usage per container
docker stats

Troubleshooting

SSL Certificate Not Generating

Symptom: HTTPS shows an error or certificate is not valid
  • Make sure your DNS A record is pointing to the correct server IP
  • Wait for DNS propagation (can take up to 1 hour)
  • Ensure port 80 and 443 are open on your server
  • Check Traefik logs: docker logs traefik

Deployment Failing

Symptom: Build errors in the Dokploy logs
  • Check the exact error in Deployment Logs
  • Verify your package.json has a valid build script:
{
  "scripts": {
    "build": "next build",
    "start": "next start"
  }
}
  • Ensure all required environment variables are set in Dokploy

GitHub Webhook Not Triggering

Symptom: Pushing to GitHub doesn't trigger a new deployment
  • Verify the GitHub App has access to the repository
  • In Dokploy, go to Settings → Webhooks and check the webhook URL
  • Try a manual deploy first to confirm the configuration works
  • Re-install the GitHub App if the webhook URL has changed

High Memory / CPU Usage

Symptom: Server is slow or containers are crashing
# Check resource usage
htop
 
# Check which containers are using the most resources
docker stats --no-stream
 
# Restart a specific service
docker restart <container_name>

Consider upgrading to Cloud VPS 30 if you're running many services.


Port Already in Use

Symptom: Container fails to start, port conflict error
# Find what's using the port
lsof -i :3000
 
# Kill the process if needed
kill -9 <PID>

Cost Breakdown

Monthly Costs with Contabo

ItemCost
Contabo Cloud VPS 20~$7.99/month
Domain name (optional)$1/month ($12/year)
Total~$9/month

Compared to Managed Platforms

PlatformMonthly Cost
Contabo + Dokploy~$8–9/month
Vercel Pro$20/month + usage
Railway$5–20+/month
Render$7–25+/month
DigitalOcean App Platform$12–25+/month

💡 Savings: 60–80% cost reduction while maintaining identical functionality — push-to-deploy, SSL, custom domains, and analytics.


Scaling Your Setup

Multiple Applications on One VPS

Each app gets its own subdomain automatically. On a Cloud VPS 20 (6 vCPU, 12 GB RAM), you can comfortably run:

  • 3–5 production Next.js apps
  • 1–2 databases (PostgreSQL, MySQL)
  • Analytics (Umami)
  • Background services (Redis, queues)

When to Upgrade

SignalAction
CPU consistently > 70%Upgrade to Cloud VPS 30
RAM > 80% usageUpgrade or optimize containers
Disk > 80%Expand storage or add a volume
> 5 apps runningUpgrade to Cloud VPS 30 or add a second server

Advanced Dokploy Features

  • Docker Swarm — container orchestration for high availability
  • Multi-server management — manage multiple VPS instances from one dashboard
  • Load balancer — distribute traffic across servers
  • Database clustering — redundant database setups

Quick Reference

Useful Commands

# SSH into server
ssh root@YOUR_SERVER_IP
 
# View all running containers
docker ps
 
# View Dokploy logs
docker logs dokploy
 
# Restart Dokploy
docker restart dokploy
 
# View Traefik (reverse proxy) logs
docker logs traefik
 
# Check disk usage
df -h
 
# Check memory
free -h
 
# Update server packages
apt update && apt upgrade -y

Dokploy Dashboard URLs

PagePath
Dashboardhttp://YOUR_SERVER_IP:3000
Projects/dashboard/projects
Settings/dashboard/settings
Monitoring/dashboard/monitoring

Next Steps

After completing this guide, consider:

  1. Set up a staging environment — deploy a staging branch to a separate subdomain
  2. Configure backups — use Contabo's snapshot feature or a backup script for your database
  3. Set up alerts — configure uptime monitoring via UptimeRobot or Betterstack (both have free tiers)
  4. Harden your server — configure UFW firewall, disable root password login, use fail2ban
  5. Add Redis — deploy a Redis instance in Dokploy for caching and session storage
  6. Explore Dokploy templates — one-click deploys for Ghost, WordPress, Plausible, n8n, and more

Conclusion

You now have a production-ready Next.js deployment pipeline that rivals managed platforms at a fraction of the cost. The combination of Contabo's affordable, high-spec VPS and Dokploy's developer-friendly interface gives you everything you need:

  • 🚀 Push-to-deploy from GitHub
  • 🔒 Automatic SSL certificates
  • 📊 Self-hosted analytics
  • 🗄️ Integrated database hosting
  • 💰 80% cost savings vs. managed platforms

Self-hosting gives you full control over your infrastructure, eliminates vendor lock-in, and — most importantly — teaches you skills that make you a significantly better developer.


Built with ❤️ — Adapted from the original Hetzner + Dokploy guide. Updated for Contabo VPS.