How to Deploy Next.js on Coolify v4 Using a Custom Dockerfile

#deploy #nextjs #coolify #Docker #github #selfhost

Coolify has emerged as a premier self-hosted alternative to Vercel and Netlify. While its default Nixpacks builder is excellent for zero-configuration deployments, developers often require granular control over the build environment.

This guide demonstrates how to deploy a Next.js application on Coolify v4 (specifically tested on v4.0.0-beta.460) using a multi-stage Dockerfile. This method ensures a highly optimized, production-ready image.

Prerequisites

Step 1: Optimize Next.js for Docker

The most critical step before configuring the container is setting up Next.js to create a standalone build. This feature automatically traces your import dependencies and creates a smaller deployment folder, eliminating the need to copy the entire node_modules directory into your final image.

Open your next.config.js file and add the output: 'standalone' configuration:

next.config.js

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

module.exports = nextConfig;

Step 2: Create the Multi-Stage Dockerfile

Create a file named Dockerfile in the root of your project. We will use a multi-stage build strategy to keep the final image lightweight. This process splits the build into three stages: 1. Deps: Installs dependencies (cached for speed). 2. Builder: Compiles the Next.js application. 3. Runner: The final, minimal production image.

Copy the following code into your Dockerfile:

Dockerfile

# Stage 1: Install dependencies
FROM node:18-alpine AS deps
WORKDIR /app
# Install libc6-compat (needed for some native dependencies)
RUN apk add --no-cache libc6-compat
COPY package.json package-lock.json* ./
RUN npm ci

# Stage 2: Build the application
FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Disable Next.js telemetry during build
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build

# Stage 3: Production runner
FROM node:18-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

# Create a system user for security
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Copy the standalone build and static assets
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"]

Note: Create a .dockerignore file in your root directory and add node_modules and .next to it. This prevents local build files from slowing down the Docker build context.

Step 3: Configure the Project in Coolify

  1. Log in to your Coolify dashboard.
  2. Click + New Resource and select Public Repository (or Private Repository if you have configured GitHub App access).
  3. Paste your repository URL and select the branch you wish to deploy (usually main).
  4. Under Build Pack, select Dockerfile.
    • Coolify defaults to Nixpacks, so this manual selection is crucial.
  5. Click Continue.

Step 4: Define Environment Variables

If your Next.js application relies on environment variables (like DATABASE_URL or API_KEY), you must define them in Coolify before deploying.

  1. Navigate to the Environment Variables tab in your project view.
  2. Add your keys and values.
  3. Ensure you do not commit a .env file to your Git repository; managing them inside Coolify is more secure.

Step 5: Deploy

  1. Go back to the Configuration tab.
  2. Verify the Ports Exposes setting is set to 3000 (matching the EXPOSE instruction in our Dockerfile).
  3. Click Deploy in the top right corner.

Coolify will now pull your code, build the Docker image using the stages defined in Step 2, and start the container. You can view the build logs in real-time to monitor the progress. Once the status changes to Running, your optimized Next.js application is live.

Thanks for reading! If you found this helpful: