This document explains how to use Docker with the NextPlacement monorepo.
The project contains three Dockerfiles:
Dockerfile- Root-level Dockerfile for the entire monorepoapps/admin/Dockerfile- Specific Dockerfile for the admin applicationapps/student/Dockerfile- Specific Dockerfile for the student application
-
Build and run both applications:
docker-compose up --build
-
Run in detached mode:
docker-compose up -d --build
-
Stop the services:
docker-compose down
docker build -f apps/admin/Dockerfile -t nextplacement-admin .
docker run -p 3001:3001 nextplacement-admindocker build -f apps/student/Dockerfile -t nextplacement-student .
docker run -p 3000:3000 nextplacement-studentdocker build -t nextplacement .
docker run -p 3000:3000 nextplacement- Student Application:
http://localhost:3000 - Admin Application:
http://localhost:3001
Create a .env file in the root directory with your environment variables:
# Database
DATABASE_URL="your-database-url"
# NextAuth
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-secret"
# Other environment variables...Then uncomment the env_file section in docker-compose.yml:
env_file:
- .env- deps stage: Installs dependencies with optimal caching
- builder stage: Builds the application
- runner stage: Creates the production image
- Runs as non-root user (
nextjs) - Minimal attack surface with Alpine Linux
- Proper file permissions
- Layer caching optimization
- Standalone Next.js output
- Minimal production image size
- Handles workspace dependencies
- Builds shared packages (
@workspace/ui,@workspace/db) - Uses Turbo for efficient builds
For development, you can mount the source code:
docker run -v $(pwd):/app -p 3000:3000 nextplacementTo enable hot reload in development:
docker-compose -f docker-compose.dev.yml upEnsure all required environment variables are set:
docker run -e DATABASE_URL="..." -e NEXTAUTH_SECRET="..." -p 3000:3000 nextplacementThe docker-compose configuration includes health checks that verify the applications are running properly.
You can scale individual services:
docker-compose up --scale student=3 --scale admin=2-
Clear Docker cache:
docker system prune -a
-
Rebuild without cache:
docker-compose build --no-cache
-
Check logs:
docker-compose logs student docker-compose logs admin
-
Access container shell:
docker-compose exec student sh
If ports 3000 or 3001 are already in use, modify the docker-compose.yml:
ports:
- "3002:3000" # Map to different host port- Always use specific image tags in production
- Set up proper logging and monitoring
- Use secrets management for sensitive data
- Implement proper backup strategies
- Monitor resource usage
You can create custom Dockerfiles for specific environments:
# Dockerfile.prod
FROM node:22-alpine AS base
# ... production-specific configurationCreate docker-compose.override.yml for local development:
version: '3.8'
services:
student:
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=developmentThe applications include health check endpoints. Create an API route:
// apps/student/app/api/health/route.ts
export async function GET() {
return Response.json({ status: 'ok' })
}Configure proper logging for production:
docker-compose up --build 2>&1 | tee app.log- Never commit
.envfiles - Use Docker secrets for sensitive data
- Regularly update base images
- Scan images for vulnerabilities
- Implement proper network policies
- Use multi-stage builds (already implemented)
- Optimize layer caching (already implemented)
- Use
.dockerignore(already implemented) - Consider using BuildKit
- Monitor image sizes
For issues related to Docker setup, check:
- Docker logs
- Application logs
- Network connectivity
- Environment variables
- File permissions