Skip to content

Moving from Vercel to Hetzner with Coolify - A Complete Migration Guide

Posted on:September 29, 2025 at 04:00 PM

Intro

The time to migrate has come? This thing has been sitting on my to-do list for months as I keep stalling and procrastinating with more important work. I have started migrating some stuff, not everything yet, this blog still remains but I will do it in the upcoming period. I wanted more control over my infrastructure and to learn the ins and outs of self-hosting. After some research and a weekend of tinkering, I found my answer: Hetzner for the infrastructure and Coolify as the self-hosted deployment platform.

In this guide, I’ll walk you through exactly how I made the migration, the gotchas I encountered, and everything you need to know to make the switch yourself

The Stack

Here’s what we’ll be working with:

Step 1: Setting Up Your Hetzner Server

First things first, we need a server to work with.

Creating a Hetzner Account

Head over to hetzner.com and create an account. You’ll need to verify your identity (usually with a credit card or PayPal), but the process is straightforward.

Launching Your First Server

Once you’re in the Hetzner Cloud Console:

  1. Click “New Project” and give it a name
  2. Click “Add Server”
  3. Choose your location (I went with Nuremberg for EU, but pick what’s closest to your users)
  4. Select Ubuntu 22.04 as your image
  5. For server type, I recommend starting with CPX21 (3 vCPU, 4GB RAM, 80GB disk) which costs around €8/month
  6. Add your SSH key (we’ll need this for secure access)

Generating an SSH Key (if you don’t have one):

On your local machine, open terminal and run:

ssh-keygen -t ed25519 -C "[email protected]"

Press Enter to accept the default location, and optionally set a passphrase. Then display your public key:

cat ~/.ssh/id_ed25519.pub

Copy this and paste it into Hetzner’s SSH key field.

  1. Leave the other options as default and click “Create & Buy Now”

Your server will be ready in about a minute. Note down the IP address that appears.

Initial Server Setup

First, let’s connect to our new server:

ssh root@your_server_ip

Update the system packages:

apt update && apt upgrade -y

Create a new user (never run everything as root):

adduser yourusername
usermod -aG sudo yourusername

Copy your SSH key to the new user:

rsync --archive --chown=yourusername:yourusername ~/.ssh /home/yourusername

Now exit and reconnect as your new user:

exit
ssh yourusername@your_server_ip

Step 2: Installing Coolify

This is where the magic happens. Coolify makes self-hosting feel almost as easy as Vercel.

Prerequisites Check

Coolify requires a clean Ubuntu server with at least 2GB RAM. Make sure your server meets these requirements:

free -h  # Check RAM
df -h    # Check disk space

Installation

The installation is surprisingly simple. Run this single command:

curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash

This script will:

The installation takes about 5-10 minutes. Grab a coffee while it runs.

Once complete, you’ll see a message with your Coolify URL:

Coolify is now available at http://your_server_ip:8000

First-Time Coolify Setup

Open your browser and navigate to http://your_server_ip:8000.

  1. You’ll be greeted with a registration screen
  2. Create your admin account (save these credentials somewhere safe)
  3. You’ll land on the dashboard

The first thing Coolify will ask you to do is set up your SSH key for deployments. It will generate one automatically, which is fine for most use cases.

Step 3: Configuring Your Domain

Before deploying anything, let’s set up a proper domain with SSL.

DNS Configuration

Head to your domain registrar (or Cloudflare if you’re using them for DNS) and add these records:

A Record:

Wildcard A Record (optional but recommended):

This wildcard record lets you easily create subdomains for different projects.

Wait a few minutes for DNS propagation (usually 5-15 minutes).

SSL Setup in Coolify

Coolify uses Let’s Encrypt for automatic SSL certificates, but we need to configure it first.

  1. In Coolify, go to Settings → Configuration
  2. Find “Instance Settings”
  3. Update your Coolify URL to use your domain: https://coolify.yourdomain.com
  4. Enable “Automatic SSL” (this uses Let’s Encrypt)
  5. Save settings

Coolify will automatically obtain and renew SSL certificates for all your deployments.

Step 4: Deploying Your First Application

Let’s deploy a Next.js app (since that’s what most people are migrating from Vercel).

Preparing Your Repository

Make sure your Next.js project has these files:

Dockerfile (if not already present):

FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json* ./
RUN npm ci

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN npm run build

# Production image
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000

CMD ["node", "server.js"]

next.config.js (add this if using standalone output):

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
}

module.exports = nextConfig

Push these changes to your Git repository.

Creating the Application in Coolify

  1. In Coolify dashboard, click ”+ New Resource”
  2. Select “Application”
  3. Choose “Public Repository” (or connect your GitHub/GitLab account)
  4. Paste your repository URL
  5. Select the branch you want to deploy (usually main or master)
  6. Coolify will auto-detect it’s a Next.js app

Configure the deployment:

Build Settings:

Domain Settings:

Environment Variables:

Click “Deploy” and watch the magic happen in the deployment logs.

Monitoring the Deployment

Coolify provides real-time logs during deployment. You’ll see:

First deployment usually takes 3-5 minutes. Subsequent deployments are faster due to caching.

Step 5: Setting Up Automatic Deployments

Just like Vercel, we want deployments to trigger automatically when we push to our repository.

GitHub Integration

  1. In Coolify, go to your application settings
  2. Find “Webhooks” section
  3. Copy the webhook URL provided
  4. Go to your GitHub repository → Settings → Webhooks
  5. Click “Add webhook”
  6. Paste the Coolify webhook URL
  7. Select “Just the push event”
  8. Make sure “Active” is checked
  9. Click “Add webhook”

Now every time you push to your repository, Coolify will automatically deploy the changes.

GitLab/Bitbucket

The process is similar:

GitLab:

Bitbucket:

Step 6: Database Setup

If your application needs a database, Coolify makes this incredibly easy.

PostgreSQL Example

  1. In Coolify, click ”+ New Resource”
  2. Select “Database”
  3. Choose “PostgreSQL”
  4. Configure:
    • Name: myapp-db
    • PostgreSQL version: 15 (or your preferred version)
    • Database name, username, and password
  5. Click “Deploy”

Coolify will:

Connecting Your App to the Database

In your application’s environment variables, add:

DATABASE_URL=postgresql://username:password@myapp-db:5432/database_name

Note that myapp-db is the internal Docker network name. Coolify handles the networking automatically.

Other Databases

Coolify supports:

The setup process is identical for all of them.

Step 7: Advanced Configuration

Environment-Specific Settings

You can create multiple environments for the same project:

  1. Clone your production application in Coolify
  2. Point it to a different branch (e.g., staging)
  3. Use a different domain (e.g., staging.yourdomain.com)
  4. Configure different environment variables

Custom Build Commands

If your project has special build requirements:

  1. Go to application settings
  2. Find “Build & Deploy” section
  3. Add custom commands:
    • Pre-build commands
    • Build commands
    • Post-build commands
    • Start commands

Example for a monorepo:

# Pre-build
cd packages/frontend

# Build
npm run build

# Start
npm start

Health Checks

Set up health checks to ensure your application is running properly:

  1. Application settings → Health Checks
  2. Configure:
    • Health check path: /api/health (or your health endpoint)
    • Interval: 30 seconds
    • Timeout: 10 seconds
    • Retries: 3

Coolify will automatically restart your container if health checks fail.

Resource Limits

Control how much CPU and memory your application can use:

  1. Application settings → Resources
  2. Set:
    • Memory limit: 512MB, 1GB, 2GB, etc.
    • CPU limit: 0.5, 1, 2 cores, etc.

This prevents one application from consuming all server resources.

Common Issues and Solutions

During my migration, I encountered a few hiccups. Here’s how I solved them:

Issue 1: Build Fails with “Out of Memory”

Solution: Increase the memory limit for your application, or upgrade your server. Build processes (especially for large Next.js apps) can be memory-intensive.

Temporary fix during build:

# In Coolify, add this to pre-build commands
export NODE_OPTIONS="--max-old-space-size=2048"

Issue 2: Application Not Accessible After Deployment

Solution: Check these in order:

  1. Verify DNS records are pointing to the correct IP
  2. Check if the container is actually running: docker ps
  3. Review deployment logs in Coolify
  4. Ensure the correct port is exposed in your Dockerfile
  5. Check firewall rules: sudo ufw status

Issue 3: SSL Certificate Not Generating

Solution:

  1. Make sure DNS is fully propagated (wait 15-30 minutes)
  2. Verify port 80 and 443 are open
  3. Check Let’s Encrypt rate limits (you might have hit them)
  4. Try regenerating the certificate manually in Coolify settings

Issue 4: Slow Build Times

Solution:

  1. Use Docker layer caching effectively
  2. Optimize your Dockerfile (copy package files first, then source code)
  3. Consider using Coolify’s build cache settings
  4. For very large projects, upgrade to a server with more CPU

Issue 5: Environment Variables Not Working

Solution:

  1. Ensure you’re not committing .env files to Git
  2. Double-check variable names (they’re case-sensitive)
  3. Rebuild the application after adding variables
  4. For Next.js, remember NEXT_PUBLIC_ prefix for client-side variables

Backups and Maintenance

Don’t forget about backups! This is crucial when self-hosting.

Database Backups

Coolify has built-in backup functionality:

  1. Go to your database resource
  2. Find “Backups” section
  3. Configure:
    • Backup frequency: Daily, weekly, etc.
    • Retention: How many backups to keep
    • S3 bucket for remote storage (recommended)

Server Snapshots

In Hetzner Cloud Console:

  1. Select your server
  2. Click “Create Snapshot”
  3. Give it a descriptive name

Schedule regular snapshots (weekly or monthly) as a safety net.

Updating Coolify

Coolify releases updates regularly. To update:

ssh into your server
sudo coolify upgrade

Or use the UI: Settings → Updates → Check for Updates

Performance Tips

Using Cloudflare CDN

Even though you’re self-hosting, you can still leverage Cloudflare’s free CDN:

  1. Transfer your domain to Cloudflare (or just use their nameservers)
  2. In Cloudflare dashboard, enable the orange cloud for your DNS records
  3. Configure caching rules and page rules as needed

This gives you edge caching, DDoS protection, and faster global performance.

Multiple Projects on One Server

The CPX21 server can easily handle 3-5 small to medium projects. To optimize:

  1. Use resource limits to prevent one app from hogging resources
  2. Consider using Redis for caching shared data
  3. Monitor resource usage: Settings → Server → Metrics

When you outgrow one server, you can either:

Optimizing Docker Images

Keep your Docker images small:

# Use alpine variants
FROM node:18-alpine

# Multi-stage builds
# Only copy what's needed for production

# Clean up after installing dependencies
RUN npm ci && npm cache clean --force

Monitoring and Logs

Built-in Monitoring

Coolify provides basic monitoring:

Access it at: Settings → Server → Metrics

Application Logs

View real-time logs for any application:

  1. Click on your application
  2. Go to “Logs” tab
  3. Choose:
    • Build logs
    • Application logs
    • Container logs

You can also SSH into your server and use Docker commands:

docker logs -f container_name

External Monitoring

For production applications, consider setting up:

Cost Breakdown

Here’s what you can expect to pay monthly:

Hetzner Server (CPX21):

Domain:

Optional:

Total: About $10-15/month for most setups

Is This Migration Right for You?

You should make the move if:

Conclusion

Moving from Vercel to Hetzner with Coolify was one of the best technical decisions I made this year. Not only did it give me more control and flexibility, but it also deepened my understanding of how modern deployment pipelines work.

The initial setup took me about 3-4 hours (including troubleshooting), but now deployments are just as smooth as they were on Vercel. I’m hosting 6 different projects on a single server, all with automatic deployments, SSL certificates, and proper domain management.

Is it for everyone? I think yes. It helps to be a person that enjoys understanding how things work under the hood and wants more bang for your buck, but I highly recommend everyone giving it a shot.

Feel free to reach out if you run into any issues during your migration. Happy self-hosting!