Skip to main content

Overview

Dokploy supports multiple build methods to transform your source code into Docker images. Each method is optimized for different languages, frameworks, and use cases.

Build Methods

Dokploy provides six build methods:

Nixpacks

Auto-detect framework and generate optimized builds

Dockerfile

Full control with custom Docker builds

Heroku Buildpacks

Heroku-compatible buildpacks

Paketo Buildpacks

Cloud Native Buildpacks standard

Railpack

Optimized Ruby on Rails builds

Static

Static site generation with nginx
Nixpacks automatically detects your application’s framework and generates an optimized build configuration.

Supported Frameworks

Nixpacks supports 20+ languages and frameworks:
  • Node.js - package.json with scripts
  • Next.js - Automatic optimization
  • React - CRA, Vite, or custom
  • Vue.js - Vue CLI or Vite
  • Angular - Angular CLI
  • Svelte - SvelteKit or Vite
  • Nuxt - SSR or static
  • Remix - Full-stack framework
Detection:
// package.json
{
  "scripts": {
    "build": "next build",
    "start": "next start"
  }
}
  • Django - Web framework
  • Flask - Microframework
  • FastAPI - Modern async framework
  • Streamlit - Data apps
Detection:
# requirements.txt, Pipfile, or pyproject.toml
django>=4.0
gunicorn>=20.0
  • Standard Go - go.mod projects
  • Gin - Web framework
  • Echo - High performance
  • Fiber - Express-inspired
Detection:
// go.mod
module github.com/user/app
go 1.21
  • Ruby on Rails - Full-stack framework
  • Sinatra - Lightweight framework
  • Hanami - Modern framework
Detection:
# Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 7.0'
  • Laravel - Web framework
  • Symfony - Enterprise framework
  • WordPress - CMS
Detection:
// composer.json
{
  "require": {
    "laravel/framework": "^10.0"
  }
}
  • Cargo projects - Standard Rust apps
  • Actix Web - High performance
  • Rocket - Web framework
Detection:
# Cargo.toml
[package]
name = "myapp"
version = "1.0.0"
  • Spring Boot - Enterprise framework
  • Maven - Project management
  • Gradle - Build automation
Detection:
<!-- pom.xml or build.gradle -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Configuration

{
  "buildType": "nixpacks",
  "buildPath": "/",           // Root directory
  "dockerContextPath": null,   // Not used for Nixpacks
  "dockerfile": null           // Not used for Nixpacks
}

How Nixpacks Works

1

Detection Phase

Nixpacks scans your repository for:
  • Package manager files (package.json, requirements.txt, etc.)
  • Framework-specific files (next.config.js, Cargo.toml, etc.)
  • Lock files (package-lock.json, Cargo.lock, etc.)
2

Plan Generation

Based on detection, Nixpacks generates:
  • Install commands (npm install, pip install, etc.)
  • Build commands (npm run build, cargo build, etc.)
  • Start commands (npm start, python app.py, etc.)
3

Build Execution

Nixpacks executes the plan:
# Example for Node.js
npm ci
npm run build
# Image created with start command: npm start
Nixpacks requires no configuration for most applications. It “just works” out of the box.

Dockerfile

Use custom Dockerfiles for full control over the build process.

Configuration

{
  "buildType": "dockerfile",
  "dockerfile": "Dockerfile",                  // Path to Dockerfile
  "dockerContextPath": ".",                    // Build context
  "dockerBuildStage": "production",           // Multi-stage target (optional)
  "buildPath": "/"
}

Basic Dockerfile

FROM node:20-alpine AS builder

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy source
COPY . .

# Build application
RUN npm run build

# Production stage
FROM node:20-alpine

WORKDIR /app

# Copy built files
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./

EXPOSE 3000

CMD ["node", "dist/index.js"]

Multi-Stage Builds

Specify which stage to use as the final image:
# Build stage
FROM node:20-alpine AS development
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]

# Production build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# Production stage
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
Configure in Dokploy:
{
  "buildType": "dockerfile",
  "dockerfile": "Dockerfile",
  "dockerBuildStage": "production"  // Target this stage
}

Build Arguments

Pass build-time variables to Docker build:
ARG NODE_ENV=production
ARG API_URL

ENV NODE_ENV=${NODE_ENV}
ENV NEXT_PUBLIC_API_URL=${API_URL}

RUN npm run build
Configure in Dokploy:
{
  "buildArgs": "NODE_ENV=production\nAPI_URL=https://api.example.com"
}
Build arguments are available during build but not in the final container. Use environment variables for runtime configuration.

Docker Context

Set the build context directory:
{
  "dockerfile": "docker/Dockerfile",    // Dockerfile location
  "dockerContextPath": "."             // Context root
}
Directory structure:
repo/
├── docker/
   └── Dockerfile        # dockerfile: docker/Dockerfile
├── src/
   └── app.js
└── package.json

# dockerContextPath: . (repo root)
# Files accessed with: COPY src/ /app/src/

Heroku Buildpacks

Use Heroku-compatible buildpacks for zero-configuration builds.

Configuration

{
  "buildType": "heroku_buildpacks",
  "herokuVersion": "24",  // Heroku stack version
  "buildPath": "/"
}

Supported Languages

Heroku buildpacks automatically detect:
  • Node.js (package.json)
  • Python (requirements.txt, Pipfile)
  • Ruby (Gemfile)
  • PHP (composer.json)
  • Java (pom.xml, build.gradle)
  • Go (go.mod)
  • Scala (build.sbt)

How It Works

Heroku buildpacks follow conventions:
  1. Detect - Check for framework files
  2. Compile - Install dependencies and build
  3. Release - Generate start command
Example for Node.js:
// package.json
{
  "scripts": {
    "build": "next build",
    "start": "next start"  // Used as start command
  }
}

Paketo Buildpacks

Cloud Native Buildpacks compliant with OCI standards.

Configuration

{
  "buildType": "paketo_buildpacks",
  "buildPath": "/"
}

Advantages

  • No Dockerfile - Auto-detect and build
  • Rebasing - Update base image without rebuild
  • BOM - Software Bill of Materials
  • Security - Minimal attack surface

Supported Stacks

  • Java (Spring Boot, Maven, Gradle)
  • Node.js (npm, yarn, pnpm)
  • Go (Go modules)
  • .NET (ASP.NET Core)
  • PHP (Composer)
  • Ruby (Bundler)
  • Python (pip, poetry)

Railpack

Optimized builds for Ruby on Rails applications.

Configuration

{
  "buildType": "railpack",
  "railpackVersion": "0.15.4",  // Railpack version
  "buildPath": "/"
}

Features

  • Asset Precompilation - Automatic asset:precompile
  • Database Migration - Optional db:migrate
  • Yarn/npm - JavaScript dependency management
  • Ruby Version - Automatic detection from .ruby-version

Requirements

# Gemfile
source 'https://rubygems.org'

gem 'rails', '~> 7.0'
gem 'puma', '~> 6.0'

Static Sites

Serve static websites with nginx.

Configuration

{
  "buildType": "static",
  "publishDirectory": "dist",        // Build output directory
  "isStaticSpa": true,               // Enable SPA routing
  "buildPath": "/"
}

Build Process

1

Install Dependencies

npm install
2

Build Static Files

npm run build
# Outputs to dist/, build/, or public/
3

Serve with Nginx

server {
  listen 80;
  root /app/dist;
  index index.html;
  
  # SPA fallback
  location / {
    try_files $uri $uri/ /index.html;
  }
}

SPA Mode

Enable for single-page applications:
{
  "isStaticSpa": true  // Enables try_files fallback
}
This configures nginx to serve index.html for all routes, allowing client-side routing to work.

Publish Directory

Specify where build output is located:
// React (Create React App)
{"publishDirectory": "build"}

// Vue CLI
{"publishDirectory": "dist"}

// Next.js (static export)
{"publishDirectory": "out"}

// Vite
{"publishDirectory": "dist"}

// Angular
{"publishDirectory": "dist/myapp"}

Build Secrets

Pass sensitive values during build without exposing them in the final image.

Configuration

{
  "buildSecrets": "NPM_TOKEN=npm_xxxxx\nGITHUB_TOKEN=ghp_xxxxx"
}

Usage in Dockerfile

# syntax=docker/dockerfile:1.4

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./

# Mount secrets during build
RUN --mount=type=secret,id=NPM_TOKEN \
    echo "//registry.npmjs.org/:_authToken=$(cat /run/secrets/NPM_TOKEN)" > ~/.npmrc && \
    npm ci && \
    rm ~/.npmrc

COPY . .
RUN npm run build

CMD ["npm", "start"]
Build secrets are not available in the final image or at runtime. Use environment variables for runtime secrets.

Build Optimization

Layer Caching

Order Dockerfile instructions for optimal caching:
# 1. Install system dependencies (rarely changes)
RUN apk add --no-cache git

# 2. Copy dependency files (changes occasionally)
COPY package*.json ./

# 3. Install dependencies (cached if package.json unchanged)
RUN npm ci

# 4. Copy source code (changes frequently)
COPY . .

# 5. Build application
RUN npm run build

.dockerignore

Exclude unnecessary files from build context:
# .dockerignore
node_modules
.git
.env
*.log
dist
build
coverage
.DS_Store
README.md
.github
.vscode

Multi-Stage Benefits

# Builder stage includes build tools
FROM node:20 AS builder  # 300MB
RUN npm install  # Includes devDependencies
RUN npm run build

# Production stage is minimal
FROM node:20-alpine  # 40MB
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
# Final image: ~150MB vs 800MB without multi-stage

Clean Cache

Force rebuild without using cache:
{
  "cleanCache": true  // Next deployment ignores build cache
}
Cache is automatically cleaned after the build. Enable cleanCache only when needed.

Troubleshooting

Symptoms: Module not found, package not installedSolutions:
  1. Verify dependency files are committed:
    git status package-lock.json
    
  2. Use appropriate install command:
    # Node.js - use ci for reproducible builds
    RUN npm ci
    
    # Python - specify versions
    RUN pip install -r requirements.txt
    
  3. Enable clean cache:
    {"cleanCache": true}
    
Symptoms: Container exits immediately after startingSolutions:
  1. Check Dockerfile CMD/ENTRYPOINT:
    # Ensure command is correct
    CMD ["node", "dist/index.js"]
    
  2. Verify build output location:
    // For static sites
    {"publishDirectory": "build"}  // Must match actual output
    
  3. Check application logs:
    docker service logs myapp
    
Symptoms: Builds take 10+ minutesSolutions:
  1. Optimize Dockerfile layer order
  2. Add .dockerignore file
  3. Use multi-stage builds
  4. Enable build cache:
    {"cleanCache": false}
    
  5. Use smaller base images:
    FROM node:20-alpine  # vs node:20
    
Symptoms: No space left on deviceSolutions:
  1. Clean old images:
    docker image prune -a
    
  2. Remove build cache:
    docker builder prune -a
    
  3. Check disk usage:
    df -h
    docker system df
    

Next Steps

Environment Variables

Configure runtime environment

Git Integration

Automate builds from Git

Docker Registry

Push built images to registries

Deployments Overview

Learn about deployment workflows

Build docs developers (and LLMs) love