From c0a471f7c22186f12f22047840b70185a8bdd87b Mon Sep 17 00:00:00 2001 From: Joerg Date: Wed, 21 Jan 2026 14:05:39 +0100 Subject: [PATCH] chore: remove Docker files from master branch Master is now for standalone/run-on-metal deployment only. Docker-related files moved to dedicated 'docker' branch. Co-Authored-By: Claude --- .dockerignore | 61 ------------ .env.docker.example | 26 ----- DOCKER.md | 219 ------------------------------------------- Dockerfile | 72 -------------- docker-compose.yml | 31 ------ docker-entrypoint.sh | 62 ------------ 6 files changed, 471 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .env.docker.example delete mode 100644 DOCKER.md delete mode 100644 Dockerfile delete mode 100644 docker-compose.yml delete mode 100644 docker-entrypoint.sh diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 1aabd33..0000000 --- a/.dockerignore +++ /dev/null @@ -1,61 +0,0 @@ -# Dependencies -node_modules -# Note: bun.lock is needed by Dockerfile for --frozen-lockfile - -# Environment -.env -.env.* -!.env.example - -# Database - will be in volume mount -**/*.db -**/*.db-shm -**/*.db-wal - -# Build outputs - built in container -src/frontend/build/ -src/frontend/.svelte-kit/ -src/frontend/dist/ -build/ -dist/ - -# IDE -.vscode -.idea -*.swp -*.swo - -# OS -.DS_Store -Thumbs.db - -# Git -.git/ -.gitignore - -# Documentation (keep docs in image but don't need in build context) -# README.md -docs/ -*.md - -# Logs -logs/ -*.log -backend.log - -# Tests -*.test.js -*.test.ts -coverage/ - -# Docker files -Dockerfile -docker-compose.yml -.dockerignore - -# CI/CD -.github/ -.gitlab-ci.yml - -# Data directory (for volume mount) -data/ diff --git a/.env.docker.example b/.env.docker.example deleted file mode 100644 index 953f938..0000000 --- a/.env.docker.example +++ /dev/null @@ -1,26 +0,0 @@ -# Docker Environment Configuration -# Copy this file to .env and update with your values - -# ============================================ -# Application Settings -# ============================================ -NODE_ENV=production -PORT=3001 -LOG_LEVEL=debug - -# ============================================ -# Security (IMPORTANT: Change in production!) -# ============================================ -# Generate a secure JWT secret with: openssl rand -base64 32 -JWT_SECRET=change-this-in-production-use-openssl-rand-base64-32 - -# ============================================ -# CORS Configuration -# ============================================ -# Your application's public URL (e.g., https://awards.example.com) -VITE_APP_URL= - -# Comma-separated list of allowed origins for CORS -# Only needed if not using same domain deployment -# Example: https://awards.example.com,https://www.awards.example.com -ALLOWED_ORIGINS= diff --git a/DOCKER.md b/DOCKER.md deleted file mode 100644 index f5c9b17..0000000 --- a/DOCKER.md +++ /dev/null @@ -1,219 +0,0 @@ -# Docker Deployment Guide - -This guide covers deploying Quickawards using Docker. - -## Quick Start - -1. **Create environment file:** - ```bash - cp .env.docker.example .env - ``` - -2. **Generate secure JWT secret:** - ```bash - openssl rand -base64 32 - ``` - Copy the output and set it as `JWT_SECRET` in `.env`. - -3. **Update `.env` with your settings:** - - `JWT_SECRET`: Strong random string (required) - - `VITE_APP_URL`: Your domain (e.g., `https://awards.example.com`) - - `ALLOWED_ORIGINS`: Your domain(s) for CORS - -4. **Start the application:** - ```bash - docker-compose up -d - ``` - -5. **Access the application:** - - URL: http://localhost:3001 - - Health check: http://localhost:3001/api/health - -## Architecture - -### Single Port Design - -The Docker stack exposes a single port (3001) which serves both: -- **Backend API** (`/api/*`) -- **Frontend SPA** (all other routes) - -### Database Persistence - -- **Location**: `./data/award.db` (host-mounted volume) -- **Initialization**: Automatic on first startup -- **Persistence**: Database survives container restarts/recreations - -### Startup Behavior - -1. **First startup**: Database is created from template -2. **Subsequent startups**: Existing database is used -3. **Container recreation**: Database persists in volume - -## Commands - -### Start the application -```bash -docker-compose up -d -``` - -### View logs -```bash -docker-compose logs -f -``` - -### Stop the application -```bash -docker-compose down -``` - -### Rebuild after code changes -```bash -docker-compose up -d --build -``` - -### Stop and remove everything (including database volume) -```bash -docker-compose down -v -``` - -## Environment Variables - -| Variable | Required | Default | Description | -|----------|----------|---------|-------------| -| `NODE_ENV` | No | `production` | Environment mode | -| `PORT` | No | `3001` | Application port | -| `LOG_LEVEL` | No | `info` | Logging level (debug/info/warn/error) | -| `JWT_SECRET` | **Yes** | - | JWT signing secret (change this!) | -| `VITE_APP_URL` | No | - | Your application's public URL | -| `ALLOWED_ORIGINS` | No | - | CORS allowed origins (comma-separated) | - -## Database Management - -### Backup the database -```bash -cp data/award.db data/award.db.backup.$(date +%Y%m%d) -``` - -### Restore from backup -```bash -docker-compose down -cp data/award.db.backup.YYYYMMDD data/award.db -docker-compose up -d -``` - -### Reset the database -```bash -docker-compose down -v -docker-compose up -d -``` - -## Troubleshooting - -### Container won't start -```bash -# Check logs -docker-compose logs -f - -# Check container status -docker-compose ps -``` - -### Database errors -```bash -# Check database file exists -ls -la data/ - -# Check database permissions -stat data/award.db -``` - -### Port already in use -Change the port mapping in `docker-compose.yml`: -```yaml -ports: - - "8080:3001" # Maps host port 8080 to container port 3001 -``` - -### Health check failing -```bash -# Check if container is responding -curl http://localhost:3001/api/health - -# Check container logs -docker-compose logs quickawards -``` - -## Production Deployment - -### Using a Reverse Proxy (nginx) - -Example nginx configuration: - -```nginx -server { - listen 80; - server_name awards.example.com; - - location / { - proxy_pass http://localhost:3001; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } -} -``` - -### SSL/TLS with Let's Encrypt - -Use certbot with nginx: - -```bash -sudo certbot --nginx -d awards.example.com -``` - -### Security Checklist - -- [ ] Set strong `JWT_SECRET` -- [ ] Set `NODE_ENV=production` -- [ ] Set `LOG_LEVEL=info` (or `warn` in production) -- [ ] Configure `ALLOWED_ORIGINS` to your domain only -- [ ] Use HTTPS/TLS in production -- [ ] Regular database backups -- [ ] Monitor logs for suspicious activity -- [ ] Keep Docker image updated - -## File Structure After Deployment - -``` -project/ -├── data/ -│ └── award.db # Persisted database (volume mount) -├── docker-compose.yml -├── Dockerfile -├── .dockerignore -├── .env # Your environment variables -└── ... (source code) -``` - -## Building Without docker-compose - -If you prefer to use `docker` directly: - -```bash -# Build the image -docker build -t quickawards . - -# Run the container -docker run -d \ - --name quickawards \ - -p 3001:3001 \ - -v $(pwd)/data:/data \ - -e JWT_SECRET=your-secret-here \ - -e NODE_ENV=production \ - quickawards -``` diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index fe362de..0000000 --- a/Dockerfile +++ /dev/null @@ -1,72 +0,0 @@ -# Multi-stage Dockerfile for Quickawards -# Uses official Bun runtime image - -# ============================================ -# Stage 1: Dependencies & Database Init -# ============================================ -FROM oven/bun:1 AS builder - -WORKDIR /app - -# Install ALL dependencies (including devDependencies for drizzle-kit) -COPY package.json bun.lock ./ -RUN bun install --frozen-lockfile - -# Copy source code (node_modules excluded by .dockerignore) -COPY . . - -# Reinstall frontend dependencies to get correct platform binaries -RUN cd src/frontend && bun install - -# Initialize database using custom script -# This creates a fresh database with the correct schema using bun:sqlite -RUN bun src/backend/scripts/init-db.js - -# Build frontend -RUN bun run build - -# ============================================ -# Stage 2: Production Image -# ============================================ -FROM oven/bun:1 AS production - -WORKDIR /app - -# Install production dependencies only -COPY package.json bun.lock ./ -RUN bun install --frozen-lockfile --production - -# Copy backend source and schema files -COPY src/backend ./src/backend -COPY award-definitions ./award-definitions -COPY drizzle.config.ts ./ - -# Copy frontend build from builder stage -COPY --from=builder /app/src/frontend/build ./src/frontend/build - -# Copy initialized database from builder (will be used as template) -COPY --from=builder /app/src/backend/award.db /app/award.db.template - -# Copy drizzle migrations (if they exist) -COPY --from=builder /app/drizzle ./drizzle - -# Create directory for database volume mount -RUN mkdir -p /data - -# Copy entrypoint script -COPY docker-entrypoint.sh /usr/local/bin/ -RUN chmod +x /usr/local/bin/docker-entrypoint.sh - -# Set environment variables -ENV NODE_ENV=production \ - PORT=3001 \ - LOG_LEVEL=info - -# Expose the application port -EXPOSE 3001 - -# Use entrypoint script to handle database initialization -ENTRYPOINT ["docker-entrypoint.sh"] - -# Start the backend server -CMD ["bun", "run", "src/backend/index.js"] diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 0235839..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,31 +0,0 @@ -services: - quickawards: - build: - context: . - dockerfile: Dockerfile - container_name: quickawards - restart: unless-stopped - ports: - - "3001:3001" - environment: - # Application settings - NODE_ENV: production - PORT: 3001 - LOG_LEVEL: info - - # Security - IMPORTANT: Change these in production! - JWT_SECRET: ${JWT_SECRET:-change-this-in-production} - - # CORS - Set to your domain in production - VITE_APP_URL: ${VITE_APP_URL:-} - ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-} - volumes: - # Host-mounted database directory - # Database will be created at ./data/award.db on first startup - - ./data:/data - healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/api/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100644 index ad489c1..0000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh -set -e - -# Docker container entrypoint script -# Handles database initialization on first startup - -echo "==========================================" -echo "Quickawards - Docker Entrypoint" -echo "==========================================" - -# Database location in volume mount -DB_PATH="/data/award.db" -TEMPLATE_DB="/app/award.db.template" -APP_DB_PATH="/app/src/backend/award.db" - -# Check if database exists in the volume -if [ ! -f "$DB_PATH" ]; then - echo "" - echo "📦 Database not found in volume mount." - echo " Initializing from template database..." - echo "" - - # Copy the template database (created during build with drizzle-kit push) - cp "$TEMPLATE_DB" "$DB_PATH" - - # Ensure proper permissions - chmod 644 "$DB_PATH" - - echo "✅ Database initialized at: $DB_PATH" - echo " This database will persist in the Docker volume." -else - echo "" - echo "✅ Existing database found at: $DB_PATH" - echo " Using existing database from volume mount." -fi - -# Create symlink from app's expected db location to volume mount -# The app expects the database at src/backend/award.db -# We create a symlink so it points to the volume-mounted database -if [ -L "$APP_DB_PATH" ]; then - # Symlink already exists, remove it to refresh - rm "$APP_DB_PATH" -elif [ -e "$APP_DB_PATH" ]; then - # File or directory exists (shouldn't happen in production, but handle it) - echo "⚠ Warning: Found existing database at $APP_DB_PATH, removing..." - rm -f "$APP_DB_PATH" -fi - -# Create symlink to the volume-mounted database -ln -s "$DB_PATH" "$APP_DB_PATH" -echo "✅ Created symlink: $APP_DB_PATH -> $DB_PATH" - -echo "" -echo "==========================================" -echo "Starting Quickawards application..." -echo "Port: ${PORT:-3001}" -echo "Environment: ${NODE_ENV:-production}" -echo "==========================================" -echo "" - -# Execute the main command (passed as CMD in Dockerfile) -exec "$@"