Skip to main content

Build Methods

Kuploy supports multiple methods for building your application into a deployable container image. Choose the method that best fits your project.

Overview

MethodBest ForConfiguration
NixpacksMost applicationsZero config (auto-detect)
DockerfileCustom requirementsYou provide the Dockerfile
BuildpacksHeroku-like experienceMinimal config
StaticHTML/CSS/JS sitesZero config

Nixpacks automatically detects your language and framework, installs dependencies, and builds an optimized container image — with zero configuration for most projects.

Supported Languages

  • Node.js / JavaScript / TypeScript
  • Python
  • Go
  • Rust
  • Ruby
  • PHP
  • Java / Kotlin / Scala
  • .NET / C# / F#
  • Elixir
  • Haskell
  • Swift
  • Zig
  • And more

How It Works

  1. Nixpacks analyzes your repository
  2. Detects the language and framework (e.g., Next.js, Django, Rails)
  3. Generates an optimized build plan
  4. Builds and caches dependencies
  5. Produces a minimal container image

Customization

You can customize the build with a nixpacks.toml file:

[phases.setup]
nixPkgs = ["...", "ffmpeg"] # Add system packages

[phases.build]
cmds = ["npm run build"] # Custom build command

[start]
cmd = "npm start" # Custom start command

Or use environment variables:

NIXPACKS_BUILD_CMD=npm run build
NIXPACKS_START_CMD=npm start
NIXPACKS_PKGS=ffmpeg,imagemagick

When to Use

  • Standard web applications in any supported language
  • Projects that follow conventional directory structures
  • When you want the fastest path from code to container

Dockerfile

Use your own Dockerfile when you need full control over the build process.

Setup

  1. Select Dockerfile as the build method in your application settings
  2. Specify the Dockerfile path (default: Dockerfile)
  3. Optionally set the build context directory

Example: Node.js

FROM node:20-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

EXPOSE 3000
CMD ["npm", "start"]

Example: Python

FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

EXPOSE 8000
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]

Multi-Stage Builds

Use multi-stage builds to reduce image size:

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

# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]

When to Use

  • You need specific system dependencies
  • You're using multi-stage builds
  • You need precise control over the container environment
  • Your project has an unconventional structure

Buildpacks

Cloud Native Buildpacks provide a Heroku-like build experience.

Setup

  1. Select Buildpacks as the build method
  2. Choose a buildpack provider:
    • Heroku — Most compatible with existing Heroku apps
    • Paketo — Modern, actively maintained
    • Google — GCP-oriented buildpacks

Procfile

Buildpacks use a Procfile to define the start command:

web: npm start
worker: node worker.js

When to Use

  • Migrating from Heroku
  • You're already using a Procfile-based workflow
  • You want automated builds without Nixpacks

Static Sites

For static HTML/CSS/JS sites, Kuploy serves files directly with no build step.

Select Static as the build method and specify:

  • Publish directory — The folder containing your static files (e.g., dist, build, public)

Framework Builds

For frameworks that generate static output (Vite, Next.js static export, Hugo, etc.), use Nixpacks or Dockerfile to build, then serve the output.

Build Tips

Keep Your Build Context Small

Your build context is the set of files sent to the build system. Smaller contexts mean faster builds and less build minute usage.

Use a .dockerignore file in your repository root to exclude files that aren't needed during the build:

# Dependencies (reinstalled during build)
node_modules/
vendor/
.venv/
__pycache__/

# Build output (regenerated during build)
.next/
dist/
build/
out/

# Development files
.git/
.env
.env.*
*.md
LICENSE
.vscode/
.idea/

# Test and CI
coverage/
.nyc_output/
__tests__/
*.test.*
*.spec.*
.github/
tip

Nixpacks builds automatically exclude common directories like node_modules, .next, dist, .cache, and vendor even without a .dockerignore. For Dockerfile builds, you should always create one.

warning

Builds with very large contexts (many large files, checked-in binaries, etc.) will be slower to start and may time out. If your repository contains large assets, exclude them via .dockerignore or store them externally (e.g., object storage).

Build Minutes

Build time counts against your plan's build minutes. To minimize build time:

  • Use .dockerignore to exclude unnecessary files (see above)
  • Leverage layer caching — put dependency install steps (npm ci, pip install) before copying application code
  • Use multi-stage builds to reduce final image size
  • Pre-built Docker images (using an existing image tag) don't consume build minutes

Build Environment Variables

Variables marked as Available at build time are injected during the build. See Environment Variables.

Troubleshooting Builds

SymptomLikely CauseFix
Build starts slowlyLarge build contextAdd .dockerignore to exclude node_modules, .git, etc.
Build times outComplex build or large image pushSimplify Dockerfile, use multi-stage builds, check your network
"Dockerfile not found"Wrong path configuredCheck Dockerfile Path in application settings
Build succeeds but app won't startWrong start command or portCheck CMD/ENTRYPOINT and port configuration
Nixpacks picks wrong languageAmbiguous project structureAdd a nixpacks.toml with explicit configuration