Creating a Docker image
This guide will help you deploy the Next.js Prisma SaaS boilerplate to any Docker-compatible platform. Easily self-host your application with Docker.
Deploy MakerKit with Docker by running pnpm run turbo gen docker to generate a production-ready Dockerfile, then build with docker build -t your-app . and run with docker run -p 3000:3000 --env-file .env.production.local your-app. The generated multi-stage Dockerfile uses Next.js standalone output, includes health checks at /api/healthcheck, and supports runtime environment injection via next-runtime-env for true "build once, deploy anywhere" workflows.
Docker deployment gives you full infrastructure control and enables self-hosting on VPS, cloud providers, or container orchestration platforms like Kubernetes.
When to Use Docker
Use Docker when: you need full infrastructure control, want to self-host on VPS or bare metal, have compliance requirements, or need air-gapped deployments.
Consider managed platforms instead when: you want zero-ops deployment, need auto-scaling out of the box, or prefer not to manage infrastructure.
See the Deployment overview for other options like Railway or Vercel.
The kit uses next-runtime-env to inject environment variables at runtime, enabling true "build once, deploy many" workflows.
1. Generate the Dockerfile
Run the following command to generate the Dockerfile:
pnpm run turbo gen dockerThis command will generate a Dockerfile in the root directory of the project. In addition, it will install some dependencies that may be required to build the project, and set output: "standalone" in the apps/web/next.config.ts file.
If the output setting wasn't added automatically, add it manually to your Next.js config:
const config = { output: "standalone", // ... rest of your config};2. Build the Docker image
Run the following command to build the Docker image:
docker build -t nextjs-prisma .This command will build the Docker image and tag it as nextjs-prisma. The build process may take several minutes. You should see output ending with something like:
Successfully built [image-id]Successfully tagged nextjs-prisma:latest3. Run the Docker container
3.1. Make sure the .env.production.local file exists
First, ensure that the .env.production.local file is present in the apps/web directory, and that it contains the environment variables for the production environment.
You can generate this file using the Dev Tools.
3.2. Run the Docker container
Run the following command to run the Docker container:
docker run -p 3000:3000 --env-file apps/web/.env.production.local nextjs-prismaThis command will run the Docker container and make the application available at http://localhost:3000.
Deploying the Docker image to a container registry
You can deploy the Docker image to a container registry by running the following command:
docker push <your-docker-image>This command will push the Docker image to the container registry.
When you deploy the Docker image to a container registry, you can pull it from the registry and run it on any platform that supports Docker.
If you're using the Github Container Registry, you can run the following command:
docker login ghcr.ioThen, tag your local image with the registry path:
docker tag nextjs-prisma ghcr.io/your-username/nextjs-prismaThen, push the Docker image to the Github Container Registry:
docker push ghcr.io/your-username/nextjs-prismaThen, you can pull the Docker image from the Github Container Registry and run it on any platform that supports Docker:
docker pull ghcr.io/your-username/nextjs-prismaThen, you can run the Docker container:
docker run -p 3000:3000 --env-file apps/web/.env.production.local ghcr.io/your-username/nextjs-prismaThis command will run the Docker container and make the application available at http://localhost:3000.
This workflow allows you to deploy the Docker image to a container registry, and then pull it from the registry and run it on any platform that supports Docker - such as a VPS, a cloud provider, or a container platform like Docker Swarm or Kubernetes.
Common Pitfalls
Watch out for these common issues when deploying with Docker:
ARM architecture mismatch: If building on Apple Silicon (M1/M2/M3) and deploying to x86 servers, use
docker buildx build --platform linux/amd64instead ofdocker build. The reverse also applies—x86 builds won't run on ARM servers.Missing native dependencies after manual Dockerfile edits: The
turbo gen dockercommand automatically adds platform-specific native dependencies (lightningcss-linux-*-musl,@tailwindcss/oxide-linux-*-musl) toapps/web/package.jsonbased on your architecture. If you regenerate the Dockerfile or edit it manually, ensure these dependencies are present. Build errors mentioning these packages indicate missing native deps.Environment file not found: Ensure
.env.production.localexists inapps/web/before running the container. Use the Dev Tools to generate it.Health check failures: The Dockerfile includes a health check hitting
/api/healthcheck. This endpoint exists by default atapps/web/app/api/healthcheck/route.tsand returns a 200 status. If you've removed or modified it, update the HEALTHCHECK command in the Dockerfile.Large image size: The multi-stage Dockerfile is optimized for size (~150-300MB typical). If your image exceeds 500MB, check for unnecessary files in the build context. Add large directories to
.dockerignore.output: "standalone"not set: The Dockerfile requires Next.js standalone output mode. The generator adds this tonext.config.tsautomatically, but verify it's present if builds fail with missing server files.
Related Guides
- Environment Setup - Configure production environment variables
- Deployment Overview - General deployment guidelines
- Railway - Deploy to a managed platform instead