# How to Configure Docker for Development vs Production Builds in the AI Website Cloner Template

> Master Docker for AI Website Cloner Template. Learn to configure distinct development and production builds for optimized deployments and efficient workflows using docker-compose.

- Repository: [JCodesMore/ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
- Tags: how-to-guide
- Published: 2026-07-01

---

**The JCodesMore/ai-website-cloner-template repository ships with a multi-stage production Dockerfile and a lightweight development variant, orchestrated through [`docker-compose.yml`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docker-compose.yml) to enable secure, optimized production deployments alongside fast-feedback development workflows.**

Configuring Docker correctly ensures your Next.js application runs efficiently in production while remaining flexible during active development. The JCodesMore/ai-website-cloner-template provides distinct containerization strategies for each environment through specialized Dockerfiles and a unified compose configuration. This guide explains how to leverage these files to configure Docker for development vs production builds using the exact implementation found in the source code.

## Understanding the Dockerfile Architecture

### Production Multi-Stage Build (`Dockerfile`)

The production configuration uses a multi-stage build process defined in `Dockerfile` at the repository root. This file implements three distinct stages: **dependencies**, **builder**, and **runner**. The final `runner` stage copies only compiled assets from `.next/standalone` and `.next/static` alongside the `public` directory, resulting in a minimal attack surface and reduced image size.

### Development Single-Stage Build (`Dockerfile.dev`)

For development workflows, the repository includes `Dockerfile.dev`, which uses a single stage based on `node:24-alpine`. This configuration installs dependencies from [`package.json`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/package.json) and [`package-lock.json`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/package-lock.json) but does not compile the application at build time. Instead, it executes `npm run dev` to enable Next.js hot-reload functionality.

## Key Configuration Differences

Production and development builds differ significantly in their architecture and runtime behavior:

- **Build Targets**: Production uses `target: runner` in [`docker-compose.yml`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docker-compose.yml), while development builds the entire `Dockerfile.dev` without a specific target.
- **Source Code Handling**: Production copies source code into the image during build (`COPY . .`), whereas development mounts the repository as a volume (`volumes: - .:/app`) for instant reflection of code changes.
- **Environment Variables**: Production sets `NODE_ENV=production` and exposes port `3000`, while development uses `NODE_ENV=development` and maps `${DEV_PORT:-3001}:3000`.
- **User Permissions**: The production container runs as the non-root `node` user (`USER node`), while the development container runs as root to simplify volume permissions.
- **Caching Strategy**: Production leverages Docker layer caching and build-cache mounts for `node_modules`, while development relies on the host's `node_modules` directory via bind-mount.
- **Health Monitoring**: Both configurations include healthchecks using `wget -qO- http://localhost:3000/`, though the development configuration allows a longer start-up period to accommodate hot-reload initialization.

## Building and Running the Production Environment

To create an optimized production image that includes only the compiled application:

```bash

# Build the production image targeting the runner stage

docker compose build app

# Start the production container in detached mode

docker compose up -d app

```

The `app` service in [`docker-compose.yml`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docker-compose.yml) automatically targets the `runner` stage and exposes port `3000`. You can customize the Node.js version by passing a build argument:

```bash
docker compose build --build-arg NODE_VERSION=22.10.0-slim app

```

The default Node version is defined in the first line of `Dockerfile` as `ARG NODE_VERSION=24.14.1-slim`.

## Building and Running the Development Environment

For active development with hot-reload capabilities:

```bash

# Build the development image

docker compose build dev

# Start the development container with volume mounting

docker compose up -d dev

```

The `dev` service mounts your local repository to `/app` inside the container, allowing Next.js to detect file changes immediately without requiring image rebuilds. Rebuild only when modifying [`package.json`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/package.json) or lock files to install new dependencies.

## Switching Between Environments

The [`docker-compose.yml`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docker-compose.yml) defines both `app` and `dev` services, enabling seamless environment switching:

```bash

# Run production environment

docker compose up -d app

# Run development environment

docker compose up -d dev

```

Override default ports using environment variables before running compose commands:

```bash
export PORT=8080      # Production port mapping

export DEV_PORT=8081  # Development port mapping

docker compose up -d app

```

Both services read environment variables from `.env` or `.env.local` if present, following the template structure shown in `.env.example`.

## Why Multi-Stage Builds Matter for Production

The three-stage production design in `Dockerfile` serves specific optimization purposes:

- **Dependencies stage**: Installs all node modules once and caches them using `--mount=type=cache` directives to accelerate subsequent builds.
- **Builder stage**: Compiles the Next.js application while keeping build tools and source code separate from the final runtime artifacts.
- **Runner stage**: Contains only the compiled application and runtime dependencies, running as a non-root user to minimize security vulnerabilities and image size.

This architecture significantly reduces the final image size compared to including build tools and source code, while the restricted user permissions enhance container security according to the repository's implementation.

## Summary

- The repository provides `Dockerfile` for production and `Dockerfile.dev` for development, coordinated through [`docker-compose.yml`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docker-compose.yml).
- Production builds use a multi-stage process targeting the `runner` stage, resulting in lean, secure images running as the `node` user with only `.next/standalone` and `public` assets.
- Development builds mount source code as volumes to enable instant hot-reload without image rebuilds, using `npm run dev`.
- Switch environments by specifying either the `app` or `dev` service in your docker compose commands.
- Customize Node.js versions using `--build-arg NODE_VERSION` when building images, with `24.14.1-slim` as the default.

## Frequently Asked Questions

### How do I change the Node.js version in the Docker containers?

Pass the `NODE_VERSION` build argument when building either service. For example: `docker compose build --build-arg NODE_VERSION=22.10.0-slim app`. The default is specified in `Dockerfile` as `ARG NODE_VERSION=24.14.1-slim`.

### Why does the development container run as root while production uses a non-root user?

The development container runs as root to simplify permissions when bind-mounting the host's source code directory, preventing read/write access issues during hot-reload. The production container uses the `node` user (`USER node`) as a security best practice since it doesn't need to write to the filesystem and only serves the pre-built application from `.next/standalone`.

### Do I need to rebuild the development container after every code change?

No. The `dev` service mounts your local repository as a volume (`volumes: - .:/app`), so changes reflect immediately via Next.js hot-reload. You only need to rebuild when modifying [`package.json`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/package.json) or [`package-lock.json`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/package-lock.json) to install new dependencies.

### Can I run the production build without docker-compose?

Yes. Use `docker build` with the `--target runner` flag to build only the final stage: `docker build --target runner -t ai-website-cloner:prod .` Then run the container: `docker run -p 3000:3000 -e NODE_ENV=production ai-website-cloner:prod`.