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:
parent
db00642c21
commit
02a8c2a0b4
@ -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
2
.gitignore
vendored
@ -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
|
||||||
|
|||||||
57
Dockerfile
57
Dockerfile
@ -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
67
deploy.sh
Executable 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}"
|
||||||
@ -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:
|
||||||
|
|||||||
@ -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
Loading…
Reference in New Issue
Block a user