Fix: Coolify Not Working — Deployment Failing, SSL Not Working, or Containers Not Starting
Quick Answer
How to fix Coolify self-hosted PaaS issues — server setup, application deployment, Docker and Nixpacks builds, environment variables, SSL certificates, database provisioning, and GitHub integration.
The Problem
Deployment starts but the build fails:
Build failed: Error during build — exit code 1Or the app deploys but isn’t accessible:
502 Bad Gateway — or — connection refusedOr SSL certificates don’t work:
NET::ERR_CERT_AUTHORITY_INVALID — or —
Let's Encrypt verification failedOr the database service won’t start:
Container 'postgres' is restarting — health check failingWhy This Happens
Coolify is a self-hosted alternative to Vercel/Netlify/Railway. It runs on your own server and manages deployments, databases, and SSL:
- The server needs Docker and sufficient resources — Coolify runs applications in Docker containers. A server with less than 2GB RAM or full disk space causes builds and containers to fail.
- Build packs detect your framework automatically — Coolify uses Nixpacks (like Railway) or Dockerfile to build. If auto-detection fails, you get a wrong build configuration.
- Ports must be configured correctly — Coolify’s reverse proxy (Traefik or Caddy) routes traffic to containers. If the app listens on a different port than configured, you get 502 errors.
- DNS must point to your server — SSL certificates from Let’s Encrypt require DNS A records pointing to the Coolify server’s IP. Without correct DNS, certificate verification fails.
Fix 1: Server Setup
# Install Coolify on a fresh VPS (Ubuntu 22.04+)
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
# Requirements:
# - Ubuntu 22.04+ or Debian 12+
# - 2GB+ RAM (4GB recommended)
# - 30GB+ disk space
# - Ports 80, 443, 8000 open
# After install, access the dashboard:
# http://your-server-ip:8000Initial configuration steps:
- Create an admin account at
http://your-server-ip:8000 - Add your server (localhost is auto-detected)
- Validate the server connection
- Configure a wildcard domain or individual domains
- Set up Git source (GitHub/GitLab/Bitbucket)
Fix 2: Deploy a Next.js / Node.js Application
Through the UI:
- New Resource → Application
- Select Git source → choose repository
- Coolify auto-detects the framework (Nixpacks)
- Configure:
- Build pack: Nixpacks (auto) or Dockerfile
- Port: 3000 (Next.js default)
- Domain:
myapp.example.com - Environment variables: Add from the UI
Or with a Dockerfile:
# Dockerfile — for full control over the build
FROM node:20-slim AS base
WORKDIR /app
FROM base AS deps
COPY package*.json ./
RUN npm ci
FROM base AS builder
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM base AS runner
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]// next.config.mjs — required for standalone Docker builds
const nextConfig = {
output: 'standalone', // Generates a minimal server
};
export default nextConfig;Fix 3: Fix Build Failures
# Common Nixpacks build issues:
# 1. Node.js version mismatch
# Create .node-version or .nvmrc in project root
echo "20" > .node-version
# 2. Build command not found
# Coolify reads package.json scripts
# Ensure "build" script exists:
# "build": "next build"
# "start": "next start"
# 3. Memory issues during build
# Add to environment variables in Coolify:
# NODE_OPTIONS=--max-old-space-size=4096
# 4. Private npm packages
# Add NPM_TOKEN as environment variable in Coolify
# Create .npmrc: //registry.npmjs.org/:_authToken=${NPM_TOKEN}Custom Nixpacks configuration:
# nixpacks.toml — customize the build
[phases.setup]
nixPkgs = ["nodejs_20", "npm"]
[phases.install]
cmds = ["npm ci"]
[phases.build]
cmds = ["npm run build"]
[start]
cmd = "npm start"Fix 4: Environment Variables and Secrets
# In Coolify dashboard: Application → Environment Variables
# Build-time variables (available during npm run build)
NEXT_PUBLIC_API_URL=https://api.myapp.com
NEXT_PUBLIC_SITE_URL=https://myapp.com
# Runtime variables (available when app runs)
DATABASE_URL=postgresql://user:pass@db:5432/mydb
REDIS_URL=redis://redis:6379
API_SECRET=your-secret-key
# Shared variables — reuse across services
# Create in Environment → Shared Variables
# Reference with {{SHARED.DATABASE_URL}}Connect to Coolify-managed databases:
# Coolify provisions databases as Docker containers
# Connection URLs use Docker internal network hostnames
# PostgreSQL provisioned by Coolify:
DATABASE_URL=postgresql://postgres:generated-password@app-name-db:5432/postgres
# Redis:
REDIS_URL=redis://app-name-redis:6379
# The hostname is the container name on Coolify's internal Docker networkFix 5: SSL and Domains
# Step 1: Point DNS to your Coolify server
# A record: myapp.example.com → your-server-ip
# Or wildcard: *.example.com → your-server-ip
# Step 2: Configure domain in Coolify
# Application → Settings → Domains
# Add: myapp.example.com
# Step 3: SSL is automatic with Let's Encrypt
# Coolify's proxy (Traefik/Caddy) handles cert provisioning
# If SSL fails:
# - Check DNS propagation: dig myapp.example.com
# - Ensure ports 80 and 443 are open
# - Check Traefik/Caddy logs in Coolify dashboard
# - Rate limits: Let's Encrypt allows 50 certs per domain per weekCustom SSL certificate (if Let’s Encrypt doesn’t work):
Upload your certificate in Coolify → Settings → SSL → Custom Certificate.
Fix 6: Database and Service Provisioning
# Coolify can provision databases as Docker services
# PostgreSQL
# New Resource → Database → PostgreSQL
# Coolify creates the container and generates credentials
# Redis
# New Resource → Database → Redis
# MySQL / MariaDB / MongoDB — same pattern
# Connect from your app using the internal hostname
# The hostname is shown in the database resource settingsDocker Compose for complex setups:
# docker-compose.yml — deploy as a Docker Compose resource in Coolify
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/mydb
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
worker:
build: .
command: npm run worker
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/mydb
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
volumes:
pgdata:Still Not Working?
502 Bad Gateway after deployment — the app container started but the port doesn’t match. Check what port your app listens on (Next.js: 3000, Vite: 5173, custom: whatever PORT env says). Set the correct port in Coolify’s application settings. Also check container logs for startup errors.
Build succeeds but container keeps restarting — the start command is wrong or the app crashes on startup. Check the container logs in Coolify dashboard. Common causes: missing environment variables, database not reachable, or wrong start command in package.json.
Let’s Encrypt SSL fails — DNS must point to your server before requesting a certificate. Let’s Encrypt verifies domain ownership via HTTP challenge on port 80. Ensure: DNS A record is correct, port 80 is open, and no firewall blocks the verification request.
Database connection refused from app — use the Docker internal hostname (container name), not localhost. Coolify’s databases and apps run in the same Docker network. The hostname is shown in the database resource’s connection details.
For related deployment issues, see Fix: Wrangler Not Working and Fix: Docker Secrets Not Working.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Docker Secrets Not Working — BuildKit --secret Not Mounting, Compose Secrets Undefined, or Secret Leaking into Image
How to fix Docker secrets — BuildKit secret mounts in Dockerfile, docker-compose secrets config, runtime vs build-time secrets, environment variable alternatives, and verifying secrets don't leak into image layers.
Fix: Docker Compose Healthcheck Not Working — depends_on Not Waiting or Always Unhealthy
How to fix Docker Compose healthcheck issues — depends_on condition service_healthy, healthcheck command syntax, start_period, custom health scripts, and debugging unhealthy containers.
Fix: Docker Multi-Platform Build Not Working — buildx Fails, Wrong Architecture, or QEMU Error
How to fix Docker multi-platform build issues — buildx setup, QEMU registration, --platform flag usage, architecture-specific dependencies, and pushing multi-arch manifests to a registry.
Fix: docker-compose.override.yml Not Working — Override File Ignored or Not Merged
How to fix docker-compose.override.yml not being applied — file naming, merge behavior, explicit file flags, environment-specific configs, and common override pitfalls.