docker changes

This commit is contained in:
Anushlinux
2025-08-07 21:36:22 +05:30
parent 1e70ed74e1
commit a0c3daac96
9 changed files with 681 additions and 80 deletions

View File

@@ -1,18 +1,104 @@
Dockerfile
.dockerignore
# Dependencies
node_modules
npm-debug.log
README.md
.next
.git
.pnp
.pnp.js
.turbo
.vercel
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Production builds
.next/
out/
build
dist
npm-debug.log*
dist/
build/
# Environment files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# IDE files
.vscode/
.idea/
*.swp
*.swo
# OS files
.DS_Store
*.pem
Thumbs.db
# Git
.git
.gitignore
# Docker
Dockerfile*
docker-compose*
.dockerignore
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Coverage directory used by tools like istanbul
coverage/
*.lcov
# nyc test coverage
.nyc_output
# Dependency directories
jspm_packages/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Storybook build outputs
.out
.storybook-out
# Temporary folders
tmp/
temp/
# Turbo
.turbo
# Vercel
.vercel

243
DOCKER.md Normal file
View File

@@ -0,0 +1,243 @@
# Docker Setup for NextPlacement
This document explains how to use Docker with the NextPlacement monorepo.
## Overview
The project contains three Dockerfiles:
- `Dockerfile` - Root-level Dockerfile for the entire monorepo
- `apps/admin/Dockerfile` - Specific Dockerfile for the admin application
- `apps/student/Dockerfile` - Specific Dockerfile for the student application
## Quick Start
### Using Docker Compose (Recommended)
1. **Build and run both applications:**
```bash
docker-compose up --build
```
2. **Run in detached mode:**
```bash
docker-compose up -d --build
```
3. **Stop the services:**
```bash
docker-compose down
```
### Individual Application Builds
#### Build Admin Application
```bash
docker build -f apps/admin/Dockerfile -t nextplacement-admin .
docker run -p 3001:3001 nextplacement-admin
```
#### Build Student Application
```bash
docker build -f apps/student/Dockerfile -t nextplacement-student .
docker run -p 3000:3000 nextplacement-student
```
#### Build Entire Monorepo
```bash
docker build -t nextplacement .
docker run -p 3000:3000 nextplacement
```
## Ports
- **Student Application**: `http://localhost:3000`
- **Admin Application**: `http://localhost:3001`
## Environment Variables
Create a `.env` file in the root directory with your environment variables:
```env
# 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`:
```yaml
env_file:
- .env
```
## Dockerfile Features
### Multi-stage Builds
- **deps stage**: Installs dependencies with optimal caching
- **builder stage**: Builds the application
- **runner stage**: Creates the production image
### Security
- Runs as non-root user (`nextjs`)
- Minimal attack surface with Alpine Linux
- Proper file permissions
### Performance
- Layer caching optimization
- Standalone Next.js output
- Minimal production image size
### Monorepo Support
- Handles workspace dependencies
- Builds shared packages (`@workspace/ui`, `@workspace/db`)
- Uses Turbo for efficient builds
## Development with Docker
### Development Mode
For development, you can mount the source code:
```bash
docker run -v $(pwd):/app -p 3000:3000 nextplacement
```
### Hot Reload
To enable hot reload in development:
```bash
docker-compose -f docker-compose.dev.yml up
```
## Production Deployment
### Environment Variables
Ensure all required environment variables are set:
```bash
docker run -e DATABASE_URL="..." -e NEXTAUTH_SECRET="..." -p 3000:3000 nextplacement
```
### Health Checks
The docker-compose configuration includes health checks that verify the applications are running properly.
### Scaling
You can scale individual services:
```bash
docker-compose up --scale student=3 --scale admin=2
```
## Troubleshooting
### Build Issues
1. **Clear Docker cache:**
```bash
docker system prune -a
```
2. **Rebuild without cache:**
```bash
docker-compose build --no-cache
```
### Runtime Issues
1. **Check logs:**
```bash
docker-compose logs student
docker-compose logs admin
```
2. **Access container shell:**
```bash
docker-compose exec student sh
```
### Port Conflicts
If ports 3000 or 3001 are already in use, modify the `docker-compose.yml`:
```yaml
ports:
- "3002:3000" # Map to different host port
```
## Best Practices
1. **Always use specific image tags in production**
2. **Set up proper logging and monitoring**
3. **Use secrets management for sensitive data**
4. **Implement proper backup strategies**
5. **Monitor resource usage**
## Advanced Configuration
### Custom Dockerfile
You can create custom Dockerfiles for specific environments:
```dockerfile
# Dockerfile.prod
FROM node:22-alpine AS base
# ... production-specific configuration
```
### Docker Compose Overrides
Create `docker-compose.override.yml` for local development:
```yaml
version: '3.8'
services:
student:
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
```
## Monitoring
### Health Checks
The applications include health check endpoints. Create an API route:
```typescript
// apps/student/app/api/health/route.ts
export async function GET() {
return Response.json({ status: 'ok' })
}
```
### Logging
Configure proper logging for production:
```bash
docker-compose up --build 2>&1 | tee app.log
```
## Security Considerations
1. **Never commit `.env` files**
2. **Use Docker secrets for sensitive data**
3. **Regularly update base images**
4. **Scan images for vulnerabilities**
5. **Implement proper network policies**
## Performance Optimization
1. **Use multi-stage builds** (already implemented)
2. **Optimize layer caching** (already implemented)
3. **Use `.dockerignore`** (already implemented)
4. **Consider using BuildKit**
5. **Monitor image sizes**
## Support
For issues related to Docker setup, check:
1. Docker logs
2. Application logs
3. Network connectivity
4. Environment variables
5. File permissions

View File

@@ -1,29 +1,68 @@
# Use the official Node.js runtime as the base image
FROM node:22-alpine AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk update && apk add --no-cache libc6-compat
WORKDIR /app
# Install pnpm globally
RUN corepack enable && corepack prepare pnpm@latest --activate
FROM base AS builder
RUN apk update && apk add --no-cache libc6-compat
WORKDIR /app
RUN pnpm add -g turbo@^2
COPY . .
RUN turbo prune admin --docker
# Copy package files
COPY package.json pnpm-lock.yaml* pnpm-workspace.yaml* ./
COPY apps/admin/package.json ./apps/admin/
COPY apps/student/package.json ./apps/student/
COPY packages/db/package.json ./packages/db/
COPY packages/ui/package.json ./packages/ui/
FROM base AS installer
RUN apk update && apk add --no-cache libc6-compat
# Install dependencies
RUN pnpm install --frozen-lockfile
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=builder /app/out/json/ .
RUN pnpm fetch --frozen-lockfile
RUN pnpm install --offline --frozen-lockfile --prod=false
COPY --from=builder /app/out/full/ .
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Set environment variables for build
ENV NEXT_TELEMETRY_DISABLED 1
ENV NODE_ENV production
# Build all applications
RUN pnpm turbo run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy the standalone outputs
COPY --from=builder /app/apps/admin/.next/standalone ./apps/admin/
COPY --from=builder /app/apps/admin/.next/static ./apps/admin/.next/static
COPY --from=builder /app/apps/admin/public ./apps/admin/public
COPY --from=builder /app/apps/student/.next/standalone ./apps/student/
COPY --from=builder /app/apps/student/.next/static ./apps/student/.next/static
COPY --from=builder /app/apps/student/public ./apps/student/public
# Set the correct permission for prerender cache
RUN mkdir -p apps/admin/.next apps/student/.next
RUN chown -R nextjs:nodejs apps/
USER nextjs
COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/.next/standalone ./
COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/.next/static ./apps/admin/.next/static
COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/public ./apps/admin/public
CMD node apps/admin/server.js
EXPOSE 3000 3001
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
# Default to running the student app
# You can override this with CMD ["node", "apps/admin/server.js"] for admin
CMD ["node", "apps/student/server.js"]

View File

@@ -1,29 +1,63 @@
# Use the official Node.js runtime as the base image
FROM node:22-alpine AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk update && apk add --no-cache libc6-compat
WORKDIR /app
# Install pnpm globally
RUN corepack enable && corepack prepare pnpm@latest --activate
# Copy package files
COPY package.json pnpm-lock.yaml* pnpm-workspace.yaml* ./
COPY apps/admin/package.json ./apps/admin/
COPY packages/db/package.json ./packages/db/
COPY packages/ui/package.json ./packages/ui/
# Install dependencies
RUN pnpm install --frozen-lockfile
# Rebuild the source code only when needed
FROM base AS builder
RUN apk update && apk add --no-cache libc6-compat
WORKDIR /app
RUN pnpm add -g turbo@^2
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN turbo prune admin --docker
FROM base AS installer
RUN apk update && apk add --no-cache libc6-compat
WORKDIR /app
COPY --from=builder /app/out/json/ .
RUN pnpm fetch --frozen-lockfile
RUN pnpm install --offline --frozen-lockfile --prod=false
COPY --from=builder /app/out/full/ .
RUN pnpm turbo run build
# Set environment variables for build
ENV NEXT_TELEMETRY_DISABLED 1
ENV NODE_ENV production
# Build the application
RUN pnpm turbo run build --filter=admin...
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy the standalone output
COPY --from=builder /app/apps/admin/.next/standalone ./
COPY --from=builder /app/apps/admin/.next/static ./apps/admin/.next/static
COPY --from=builder /app/apps/admin/public ./apps/admin/public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
USER nextjs
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
CMD node apps/web/server.js
EXPOSE 3001
ENV PORT 3001
ENV HOSTNAME "0.0.0.0"
# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "apps/admin/server.js"]

View File

@@ -0,0 +1,27 @@
import { NextResponse } from 'next/server'
export async function GET() {
try {
// You can add additional health checks here
// For example, database connectivity, external service checks, etc.
return NextResponse.json(
{
status: 'ok',
timestamp: new Date().toISOString(),
service: 'admin-app'
},
{ status: 200 }
)
} catch (error) {
return NextResponse.json(
{
status: 'error',
message: 'Health check failed',
timestamp: new Date().toISOString(),
service: 'admin-app'
},
{ status: 500 }
)
}
}

View File

@@ -1,38 +1,63 @@
# Use the official Node.js runtime as the base image
FROM node:22-alpine AS base
FROM base AS builder
RUN apk update
RUN apk add --no-cache libc6-compat
# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk update && apk add --no-cache libc6-compat
WORKDIR /app
RUN corepack enable pnpm && pnpm add -g turbo@^2
# Install pnpm globally
RUN corepack enable && corepack prepare pnpm@latest --activate
# Copy package files
COPY package.json pnpm-lock.yaml* pnpm-workspace.yaml* ./
COPY apps/student/package.json ./apps/student/
COPY packages/db/package.json ./packages/db/
COPY packages/ui/package.json ./packages/ui/
# Install dependencies
RUN pnpm install --frozen-lockfile
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN turbo prune student --docker
# Set environment variables for build
ENV NEXT_TELEMETRY_DISABLED 1
ENV NODE_ENV production
FROM base AS installer
RUN apk update
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY --from=builder /app/out/json/ .
RUN yarn install --frozen-lockfile
COPY --from=builder /app/out/full/ .
RUN pnpm turbo run build
# Build the application
RUN pnpm turbo run build --filter=student...
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
# Don't run production as root
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy the standalone output
COPY --from=builder /app/apps/student/.next/standalone ./
COPY --from=builder /app/apps/student/.next/static ./apps/student/.next/static
COPY --from=builder /app/apps/student/public ./apps/student/public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
USER nextjs
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
EXPOSE 3000
CMD node apps/web/server.js
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "apps/student/server.js"]

View File

@@ -0,0 +1,27 @@
import { NextResponse } from 'next/server'
export async function GET() {
try {
// You can add additional health checks here
// For example, database connectivity, external service checks, etc.
return NextResponse.json(
{
status: 'ok',
timestamp: new Date().toISOString(),
service: 'student-app'
},
{ status: 200 }
)
} catch (error) {
return NextResponse.json(
{
status: 'error',
message: 'Health check failed',
timestamp: new Date().toISOString(),
service: 'student-app'
},
{ status: 500 }
)
}
}

58
docker-compose.dev.yml Normal file
View File

@@ -0,0 +1,58 @@
version: '3.8'
services:
# Student application (Development)
student-dev:
build:
context: .
dockerfile: apps/student/Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=development
- PORT=3000
- HOSTNAME=0.0.0.0
volumes:
- .:/app
- /app/node_modules
- /app/apps/student/node_modules
- /app/packages/ui/node_modules
- /app/packages/db/node_modules
command: ["pnpm", "dev", "--filter=student"]
restart: unless-stopped
# Admin application (Development)
admin-dev:
build:
context: .
dockerfile: apps/admin/Dockerfile
ports:
- "3001:3001"
environment:
- NODE_ENV=development
- PORT=3001
- HOSTNAME=0.0.0.0
volumes:
- .:/app
- /app/node_modules
- /app/apps/admin/node_modules
- /app/packages/ui/node_modules
- /app/packages/db/node_modules
command: ["pnpm", "dev", "--filter=admin"]
restart: unless-stopped
# Database (Development)
postgres-dev:
image: postgres:15-alpine
environment:
POSTGRES_DB: nextplacement_dev
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
volumes:
- postgres_dev_data:/var/lib/postgresql/data
ports:
- "5432:5432"
restart: unless-stopped
volumes:
postgres_dev_data:

62
docker-compose.yml Normal file
View File

@@ -0,0 +1,62 @@
version: '3.8'
services:
# Student application
student:
build:
context: .
dockerfile: apps/student/Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
- HOSTNAME=0.0.0.0
# Add your environment variables here
# env_file:
# - .env
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Admin application
admin:
build:
context: .
dockerfile: apps/admin/Dockerfile
ports:
- "3001:3001"
environment:
- NODE_ENV=production
- PORT=3001
- HOSTNAME=0.0.0.0
# Add your environment variables here
# env_file:
# - .env
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Database (if you need one)
# postgres:
# image: postgres:15-alpine
# environment:
# POSTGRES_DB: nextplacement
# POSTGRES_USER: postgres
# POSTGRES_PASSWORD: password
# volumes:
# - postgres_data:/var/lib/postgresql/data
# ports:
# - "5432:5432"
# restart: unless-stopped
# volumes:
# postgres_data: