chore: Production Dockerfile, deploy script, dev port 3001

- Multi-stage Dockerfile: build stage + slim production runner
- Runs `next build` + `next start` instead of `npm run dev`
- Dev server on port 3001 to avoid conflict with production on 3000
- Deploy script with version bumping and health checks
- Explicit .env.production for docker-compose
- Updated .gitignore and .dockerignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
mARTin 2026-02-21 22:07:46 +01:00
parent db00642c21
commit 02a8c2a0b4
7 changed files with 120 additions and 26 deletions

View File

@ -1,9 +1,12 @@
.node_modules node_modules
.npm .npm
.git .git
.gitignore .gitignore
README.md
Dockerfile Dockerfile
docker-compose.yml docker-compose*.yml
.env .env
.env.local
.planning
prisma/dev.db
*.md *.md
!prisma/**/*.md

2
.gitignore vendored
View File

@ -13,6 +13,8 @@ Thumbs.db
# Sensitive data # Sensitive data
Inspiration/ Inspiration/
.env .env
.env.local
.env.production
# Logs and temp files # Logs and temp files
*.log *.log

View File

@ -1,35 +1,52 @@
# Use the official Node.js 18 slim image as base # ---- Build stage ----
FROM node:18-slim FROM node:18-slim AS builder
# Set working directory
WORKDIR /app WORKDIR /app
# Create necessary directories with proper permissions # Install OpenSSL for Prisma
RUN mkdir -p /app/.next /app/logs /app/node_modules RUN apt-get update && apt-get install -y openssl && rm -rf /var/lib/apt/lists/*
RUN chmod 777 /app/.next /app/logs
# Copy package files
COPY package*.json ./ COPY package*.json ./
RUN npm ci
# Install all dependencies
RUN npm install
# Copy application code
COPY . . COPY . .
# Expose port # Generate Prisma client
EXPOSE 3000 RUN npx prisma generate
# Create non-root user for security # Build the Next.js application
RUN npm run build
# ---- Production stage ----
FROM node:18-slim AS runner
WORKDIR /app
ENV NODE_ENV=production
# Install OpenSSL for Prisma and curl for healthcheck
RUN apt-get update && apt-get install -y openssl curl && rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN addgroup --system --gid 1001 nodejs RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs RUN adduser --system --uid 1001 nextjs
RUN chown -R nextjs:nodejs /app
# Copy built output and dependencies
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/next.config.js ./
# Create logs directory
RUN mkdir -p /app/logs && chown -R nextjs:nodejs /app
USER nextjs USER nextjs
# Health check EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# Run the development server HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD ["npm", "run", "dev"] CMD curl -f http://localhost:3000/api/auth/session || exit 1
CMD ["npm", "run", "start"]

67
deploy.sh Executable file
View File

@ -0,0 +1,67 @@
#!/bin/bash
set -e
# Deploy script for My Weekly To-Do List
# Usage: ./deploy.sh [version]
# Example: ./deploy.sh 1.1.0
APP_NAME="my-weekly-todo"
COMPOSE_FILE="docker-compose.yml"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${GREEN}=== $APP_NAME Deploy ===${NC}"
# Ensure we're on main branch
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" != "main" ]; then
echo -e "${RED}Error: Must deploy from main branch (currently on '$BRANCH')${NC}"
echo "Run: git checkout main && git merge dev"
exit 1
fi
# Check for uncommitted changes
if [ -n "$(git status --porcelain)" ]; then
echo -e "${RED}Error: Uncommitted changes detected. Commit or stash first.${NC}"
git status --short
exit 1
fi
# Optional: bump version
VERSION=$1
if [ -n "$VERSION" ]; then
echo -e "${YELLOW}Bumping version to $VERSION...${NC}"
npm version "$VERSION" --no-git-tag-version
git add package.json package-lock.json
git commit -m "chore: bump version to v$VERSION"
git tag -a "v$VERSION" -m "Release v$VERSION"
echo -e "${GREEN}Tagged v$VERSION${NC}"
fi
# Run database migrations
echo -e "${YELLOW}Running database migrations...${NC}"
docker compose -f "$COMPOSE_FILE" run --rm app npx prisma migrate deploy 2>/dev/null || true
# Build and deploy
echo -e "${YELLOW}Building production image...${NC}"
docker compose -f "$COMPOSE_FILE" build --no-cache
echo -e "${YELLOW}Starting services...${NC}"
docker compose -f "$COMPOSE_FILE" up -d
# Wait for health check
echo -e "${YELLOW}Waiting for health check...${NC}"
sleep 10
if docker compose -f "$COMPOSE_FILE" ps | grep -q "healthy"; then
echo -e "${GREEN}Deployment successful!${NC}"
else
echo -e "${YELLOW}Services started (health check may still be warming up)${NC}"
docker compose -f "$COMPOSE_FILE" ps
fi
CURRENT_VERSION=$(node -p "require('./package.json').version")
echo -e "${GREEN}=== Deployed v$CURRENT_VERSION ===${NC}"

View File

@ -5,14 +5,18 @@ services:
build: . build: .
ports: ports:
- "13000:3000" - "13000:3000"
env_file:
- .env.production
environment: environment:
- DATABASE_URL=postgresql://root:WKE7xeZohxdZit7eObjG@db:5432/My-Weekly-ToDo-List?schema=public - DATABASE_URL=postgresql://root:WKE7xeZohxdZit7eObjG@db:5432/My-Weekly-ToDo-List?schema=public
- NEXTAUTH_SECRET=Ca7EoJzZSMJO2CkqwdWd - NEXTAUTH_SECRET=Ca7EoJzZSMJO2CkqwdWd
- NEXTAUTH_URL=https://todo.martin-bierschenk.de
- NEXT_PUBLIC_BASE_URL=https://todo.martin-bierschenk.de - NEXT_PUBLIC_BASE_URL=https://todo.martin-bierschenk.de
depends_on: depends_on:
- db - db
volumes: volumes:
- ./logs:/app/logs - ./logs:/app/logs
restart: unless-stopped
db: db:
image: postgres:15 image: postgres:15
@ -24,6 +28,7 @@ services:
- postgres_data:/var/lib/postgresql/data - postgres_data:/var/lib/postgresql/data
ports: ports:
- "15432:5432" - "15432:5432"
restart: unless-stopped
volumes: volumes:
postgres_data: postgres_data:

View File

@ -4,7 +4,7 @@
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"dev": "next dev -H 0.0.0.0", "dev": "next dev -H 0.0.0.0 -p 3001",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint", "lint": "next lint",

File diff suppressed because one or more lines are too long