docker changes
This commit is contained in:
114
.dockerignore
114
.dockerignore
@@ -1,18 +1,104 @@
|
|||||||
Dockerfile
|
# Dependencies
|
||||||
.dockerignore
|
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log*
|
||||||
README.md
|
yarn-debug.log*
|
||||||
.next
|
yarn-error.log*
|
||||||
.git
|
pnpm-debug.log*
|
||||||
.pnp
|
|
||||||
.pnp.js
|
# Production builds
|
||||||
.turbo
|
|
||||||
.vercel
|
|
||||||
.next/
|
.next/
|
||||||
out/
|
out/
|
||||||
build
|
dist/
|
||||||
dist
|
build/
|
||||||
npm-debug.log*
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS files
|
||||||
.DS_Store
|
.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
243
DOCKER.md
Normal 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
|
||||||
77
Dockerfile
77
Dockerfile
@@ -1,29 +1,68 @@
|
|||||||
|
# Use the official Node.js runtime as the base image
|
||||||
FROM node:22-alpine AS base
|
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
|
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||||
|
|
||||||
FROM base AS builder
|
# Copy package files
|
||||||
RUN apk update && apk add --no-cache libc6-compat
|
COPY package.json pnpm-lock.yaml* pnpm-workspace.yaml* ./
|
||||||
WORKDIR /app
|
COPY apps/admin/package.json ./apps/admin/
|
||||||
RUN pnpm add -g turbo@^2
|
COPY apps/student/package.json ./apps/student/
|
||||||
COPY . .
|
COPY packages/db/package.json ./packages/db/
|
||||||
RUN turbo prune admin --docker
|
COPY packages/ui/package.json ./packages/ui/
|
||||||
|
|
||||||
FROM base AS installer
|
# Install dependencies
|
||||||
RUN apk update && apk add --no-cache libc6-compat
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
# Rebuild the source code only when needed
|
||||||
|
FROM base AS builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /app/out/json/ .
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
RUN pnpm fetch --frozen-lockfile
|
COPY . .
|
||||||
RUN pnpm install --offline --frozen-lockfile --prod=false
|
|
||||||
COPY --from=builder /app/out/full/ .
|
# Set environment variables for build
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
ENV NODE_ENV production
|
||||||
|
|
||||||
|
# Build all applications
|
||||||
RUN pnpm turbo run build
|
RUN pnpm turbo run build
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
FROM base AS runner
|
FROM base AS runner
|
||||||
WORKDIR /app
|
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
|
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
|
EXPOSE 3000 3001
|
||||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/public ./apps/admin/public
|
|
||||||
CMD node apps/admin/server.js
|
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"]
|
||||||
|
|||||||
@@ -1,29 +1,63 @@
|
|||||||
|
# Use the official Node.js runtime as the base image
|
||||||
FROM node:22-alpine AS base
|
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
|
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
|
FROM base AS builder
|
||||||
RUN apk update && apk add --no-cache libc6-compat
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN pnpm add -g turbo@^2
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN turbo prune admin --docker
|
|
||||||
|
|
||||||
FROM base AS installer
|
# Set environment variables for build
|
||||||
RUN apk update && apk add --no-cache libc6-compat
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
WORKDIR /app
|
ENV NODE_ENV production
|
||||||
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
|
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
RUN pnpm turbo run build --filter=admin...
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
FROM base AS runner
|
FROM base AS runner
|
||||||
WORKDIR /app
|
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
|
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
|
EXPOSE 3001
|
||||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
|
|
||||||
CMD node apps/web/server.js
|
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"]
|
||||||
|
|||||||
27
apps/admin/app/api/health/route.ts
Normal file
27
apps/admin/app/api/health/route.ts
Normal 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 }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,38 +1,63 @@
|
|||||||
|
# Use the official Node.js runtime as the base image
|
||||||
FROM node:22-alpine AS base
|
FROM node:22-alpine AS base
|
||||||
|
|
||||||
FROM base AS builder
|
# Install dependencies only when needed
|
||||||
RUN apk update
|
FROM base AS deps
|
||||||
RUN apk add --no-cache libc6-compat
|
# 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
|
WORKDIR /app
|
||||||
|
|
||||||
RUN corepack enable pnpm && pnpm add -g turbo@^2
|
# Install pnpm globally
|
||||||
COPY . .
|
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||||
|
|
||||||
RUN turbo prune student --docker
|
# Copy package files
|
||||||
|
COPY package.json pnpm-lock.yaml* pnpm-workspace.yaml* ./
|
||||||
FROM base AS installer
|
COPY apps/student/package.json ./apps/student/
|
||||||
RUN apk update
|
COPY packages/db/package.json ./packages/db/
|
||||||
RUN apk add --no-cache libc6-compat
|
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
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY --from=builder /app/out/json/ .
|
COPY . .
|
||||||
RUN yarn install --frozen-lockfile
|
|
||||||
|
# Set environment variables for build
|
||||||
COPY --from=builder /app/out/full/ .
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
RUN pnpm turbo run build
|
ENV NODE_ENV production
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
RUN pnpm turbo run build --filter=student...
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
FROM base AS runner
|
FROM base AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Don't run production as root
|
ENV NODE_ENV production
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
RUN addgroup --system --gid 1001 nodejs
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
RUN adduser --system --uid 1001 nextjs
|
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
|
USER nextjs
|
||||||
|
|
||||||
# Automatically leverage output traces to reduce image size
|
EXPOSE 3000
|
||||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
|
||||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
|
ENV PORT 3000
|
||||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
|
ENV HOSTNAME "0.0.0.0"
|
||||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
|
|
||||||
|
# server.js is created by next build from the standalone output
|
||||||
CMD node apps/web/server.js
|
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
|
||||||
|
CMD ["node", "apps/student/server.js"]
|
||||||
27
apps/student/app/api/health/route.ts
Normal file
27
apps/student/app/api/health/route.ts
Normal 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
58
docker-compose.dev.yml
Normal 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
62
docker-compose.yml
Normal 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:
|
||||||
Reference in New Issue
Block a user