From 4bce1d3bf1ffb6879331dac6b4c9d3e254496003 Mon Sep 17 00:00:00 2001 From: Paul Huliganga Date: Tue, 24 Mar 2026 07:42:06 -0400 Subject: [PATCH] feat(devops): add backend Dockerfile with multi-stage build - Created production-ready Dockerfile for Node.js 22 backend - Implemented multi-stage build for optimized image size - Added .dockerignore to exclude unnecessary files from build - Included database migration on container startup - Created docker-backend.md documentation - Verified: npm build and npm test pass (34/34 tests) --- .dockerignore | 33 +++++++++++++++ Dockerfile | 50 +++++++++++++++++++++++ docs/docker-backend.md | 93 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docs/docker-backend.md diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4cc2007 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,33 @@ +# Dependencies +node_modules +npm-debug.log + +# Build output (will be built in Docker) +dist + +# Development files +.git +.gitignore +*.md +docs + +# Frontend (separate Dockerfile) +frontend + +# Tests +tests +**/*.test.ts +**/*.spec.ts + +# Data (should be volume-mounted) +data + +# Environment files +.env +.env.* + +# IDE +.vscode +.idea +*.swp +*.swo diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..df11219 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,50 @@ +# Recipe Manager Backend Dockerfile +# Multi-stage build for production + +# Stage 1: Build +FROM node:22-alpine AS builder + +WORKDIR /app + +# Copy package files +COPY package*.json ./ +COPY tsconfig.json ./ + +# Install all dependencies (including dev dependencies for build) +RUN npm ci + +# Copy source code +COPY src ./src + +# Build TypeScript +RUN npm run build + +# Stage 2: Production +FROM node:22-alpine + +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install production dependencies only +RUN npm ci --omit=dev + +# Copy built JavaScript from builder stage +COPY --from=builder /app/dist ./dist + +# Copy database schema (required by migrate script) +COPY src/backend/db/schema.sql ./src/backend/db/schema.sql + +# Create data directory for SQLite database +RUN mkdir -p /app/data + +# Expose API port +EXPOSE 3000 + +# Set environment variables +ENV NODE_ENV=production +ENV DATABASE_PATH=/app/data/recipes.db + +# Run database migrations on startup, then start server +CMD ["sh", "-c", "node dist/backend/db/migrate.js && node dist/backend/index.js"] diff --git a/docs/docker-backend.md b/docs/docker-backend.md new file mode 100644 index 0000000..53ada2a --- /dev/null +++ b/docs/docker-backend.md @@ -0,0 +1,93 @@ +# Backend Dockerfile Guide + +## Overview + +Multi-stage Dockerfile for the Recipe Manager backend API. + +## Build + +```bash +docker build -t recipe-manager-backend:latest . +``` + +## Run + +```bash +# Simple run +docker run -p 3000:3000 -v $(pwd)/data:/app/data recipe-manager-backend:latest + +# With environment variables +docker run \ + -p 3000:3000 \ + -v $(pwd)/data:/app/data \ + -e NODE_ENV=production \ + -e DATABASE_PATH=/app/data/recipes.db \ + recipe-manager-backend:latest +``` + +## Volume Mounts + +**Required:** +- `/app/data` — SQLite database storage (persistent) + +## Ports + +- `3000` — API server + +## Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `NODE_ENV` | `production` | Node environment | +| `DATABASE_PATH` | `/app/data/recipes.db` | SQLite database path | + +## Image Details + +**Base:** `node:22-alpine` +**Size:** ~200MB (optimized with multi-stage build) +**Architecture:** x86_64, arm64 (via Node.js official images) + +### Build Process + +1. **Builder stage:** Installs all dependencies, builds TypeScript +2. **Production stage:** Copies only built files, production dependencies +3. **Startup:** Runs migrations, then starts Express server + +### What's Included + +- Built JavaScript (`dist/`) +- Production npm dependencies +- Database schema (`src/backend/db/schema.sql`) +- Migration script + +### What's Excluded (via .dockerignore) + +- Source TypeScript files +- Tests +- Frontend code +- Documentation +- Development dependencies + +## Health Check + +```bash +curl http://localhost:3000/ +# Expected: {"success":true,"message":"Recipe Manager API is running","version":"0.1.0"} +``` + +## Debugging + +```bash +# View logs +docker logs + +# Access shell +docker exec -it sh + +# Check database +docker exec -it ls -lh /app/data/ +``` + +## Next Steps + +Use with `docker-compose.yml` for complete stack (backend + frontend + proxy).