Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,6 @@ RUN apk add --no-cache wget
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
COPY --from=builder --chown=nextjs:nodejs /app/prisma.config.ts ./prisma.config.ts
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json
COPY --from=builder --chown=nextjs:nodejs /app/pnpm-lock.yaml ./pnpm-lock.yaml

# Copy node_modules with Prisma from builder with correct ownership
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.bin/prisma ./node_modules/.bin/prisma
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.bin/tsx ./node_modules/.bin/tsx
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.pnpm ./node_modules/.pnpm
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/prisma ./node_modules/prisma
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/dotenv ./node_modules/dotenv
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/tsx ./node_modules/tsx

USER nextjs

Expand Down
30 changes: 30 additions & 0 deletions Dockerfile.migrations
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Dockerfile for running Prisma migrations
# This is a separate, lightweight container that runs migrations before the app starts

FROM node:24-alpine

# Enable corepack and prepare pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

WORKDIR /app

# Create nextjs user for consistency
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs

# Copy only files needed for migrations
COPY --chown=nextjs:nodejs package.json pnpm-lock.yaml ./
COPY --chown=nextjs:nodejs prisma ./prisma
COPY --chown=nextjs:nodejs prisma.config.ts ./prisma.config.ts

# Install production dependencies (skip postinstall to avoid prisma generate before CLI is available)
# Then install prisma CLI from devDependencies and generate client
RUN pnpm install --frozen-lockfile --prod --ignore-scripts && \
pnpm add -D prisma && \
pnpm exec prisma generate

# Switch to non-root user
USER nextjs

# Run migrations
CMD ["pnpm", "prisma", "migrate", "deploy"]
64 changes: 64 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,67 @@ This project uses [`next/font`](https://nextjs.org/docs/app/building-your-applic
- [Resend](https://resend.com) - emails

If you want to contribute to this template for future projects please work with the teaching staff. We welcome any technologies that could benefit the partners and speed to delivery for features.

## Production Deployment

The application uses Docker Compose for production deployments with an automated migration workflow:

### Architecture

- **Database**: PostgreSQL 17 with persistent volume storage
- **Migrations**: Separate init container that runs database migrations before the app starts
- **Application**: Next.js standalone server with optimized production build

### Deployment Commands

Build and start all services:

```bash
docker compose --profile production up -d --build
```

Check service status:

```bash
docker compose ps
```

View logs:

```bash
# All services
docker compose logs

# Specific service
docker compose logs template-app
docker compose logs template-migrations
```

Stop services:

```bash
docker compose --profile production down
```

Clean shutdown with volume and orphan container removal:

```bash
docker compose --profile production down --volumes --remove-orphans
```

### Migration Workflow

1. **Database starts** and waits for healthy status
2. **Migration container** runs `prisma migrate deploy` and exits
3. **Application starts** only after migrations complete successfully

The migration container (`template-migrations`) runs once per deployment and automatically exits after completion. Docker Compose handles cleanup of stopped containers on subsequent deployments.

### Environment Variables

All required environment variables must be set in your `.env` file before deployment. See `example.env` for the complete list. Key variables:

- `DATABASE_*`: PostgreSQL connection settings
- `AUTH_*`: NextAuth configuration
- `NEXT_PUBLIC_VAPID_PUBLIC_KEY` / `VAPID_PRIVATE_KEY`: Push notification keys
- `RESEND_API_KEY`: Email service configuration
24 changes: 17 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ services:
timeout: 5s
retries: 5

# Database migrations (production only)
template-migrations:
build:
context: .
dockerfile: Dockerfile.migrations
environment:
- DATABASE_URL=postgresql://${DATABASE_USER}:${DATABASE_PW}@template-db:5432/${DATABASE_NAME}
restart: "no"
depends_on:
template-db:
condition: service_healthy
profiles:
- production

# Next.js application (production only)
template-app:
build:
Expand All @@ -40,16 +54,12 @@ services:
- VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY}
- NEXTAUTH_URL=${NEXTAUTH_URL:-http://localhost:3000}
- AUTH_TRUST_HOST=${AUTH_TRUST_HOST:-true}
command: >
sh -c "
echo 'Running database migrations...' &&
./node_modules/.bin/prisma migrate deploy &&
echo 'Migrations completed, starting application...' &&
node server.js
"
command: node server.js
depends_on:
template-db:
condition: service_healthy
template-migrations:
condition: service_completed_successfully
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1"]
interval: 10s
Expand Down