Why Docker + Next.js?
Every ViceForge project runs in Docker. It gives us reproducible environments, easy deployment, and consistent behavior across dev/staging/prod. But Next.js 16 with Turbopack introduced some surprises.
Lesson 1: Turbopack is Now Default
Next.js 16 uses Turbopack by default. There’s no --no-turbopack flag. If your Docker setup relied on Webpack-specific behaviors, you’ll need to adapt.
Lesson 2: WATCHPACK_POLLING Can Break Things
In Docker on Linux, file watching doesn’t work the same as macOS. The old advice was to set WATCHPACK_POLLING=true. With Turbopack, this can cause SyntaxErrors on startup. Remove it.
Lesson 3: Alpine + node_modules
Using node:22-alpine keeps images small (~180MB vs ~1GB for full Node). But some native modules need apk add for build tools. Always test your full dependency tree.
Lesson 4: Volume Mounts for Dev
Mount src/ and public/ as volumes for hot reload in dev. Don’t mount node_modules/ — let the container use its own copy to avoid architecture mismatches.
Lesson 5: Standalone Output for Production
For production, use output: 'standalone' in next.config.ts. This creates a minimal server bundle that doesn’t need the full node_modules.
Our Docker Setup
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
Simple, effective, battle-tested across 5 production projects.