Build Methods
Kuploy supports multiple methods for building your application into a deployable container image. Choose the method that best fits your project.
Overview
| Method | Best For | Configuration |
|---|---|---|
| Nixpacks | Most applications | Zero config (auto-detect) |
| Dockerfile | Custom requirements | You provide the Dockerfile |
| Buildpacks | Heroku-like experience | Minimal config |
| Static | HTML/CSS/JS sites | Zero config |
Nixpacks (Recommended)
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
- Nixpacks analyzes your repository
- Detects the language and framework (e.g., Next.js, Django, Rails)
- Generates an optimized build plan
- Builds and caches dependencies
- 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
- Select Dockerfile as the build method in your application settings
- Specify the Dockerfile path (default:
Dockerfile) - 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 /app/dist ./dist
COPY /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
- Select Buildpacks as the build method
- 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/
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.
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
.dockerignoreto 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
| Symptom | Likely Cause | Fix |
|---|---|---|
| Build starts slowly | Large build context | Add .dockerignore to exclude node_modules, .git, etc. |
| Build times out | Complex build or large image push | Simplify Dockerfile, use multi-stage builds, check your network |
| "Dockerfile not found" | Wrong path configured | Check Dockerfile Path in application settings |
| Build succeeds but app won't start | Wrong start command or port | Check CMD/ENTRYPOINT and port configuration |
| Nixpacks picks wrong language | Ambiguous project structure | Add a nixpacks.toml with explicit configuration |