Files
award/DOCKER.md
Joerg 52234a32b6 feat: add Docker support with single-port deployment
Add complete Docker configuration for containerized deployment:
- Multi-stage Dockerfile using official Bun runtime
- docker-compose.yml for single-port stack orchestration
- Host-mounted database volume with auto-initialization
- Custom database init script using bun:sqlite
- Entrypoint script for seamless database setup
- Environment configuration template
- Comprehensive DOCKER.md documentation

Key features:
- Single exposed port (3001) serving both API and frontend
- Database persists in ./data directory on host
- Auto-creates database from template on first startup
- Health checks for monitoring
- Architecture-agnostic (works on x86 and ARM64)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-19 16:08:06 +01:00

4.6 KiB

Docker Deployment Guide

This guide covers deploying Quickawards using Docker.

Quick Start

  1. Create environment file:

    cp .env.docker.example .env
    
  2. Generate secure JWT secret:

    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:

    docker-compose up -d
    
  5. Access the application:

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

docker-compose up -d

View logs

docker-compose logs -f

Stop the application

docker-compose down

Rebuild after code changes

docker-compose up -d --build

Stop and remove everything (including database volume)

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

cp data/award.db data/award.db.backup.$(date +%Y%m%d)

Restore from backup

docker-compose down
cp data/award.db.backup.YYYYMMDD data/award.db
docker-compose up -d

Reset the database

docker-compose down -v
docker-compose up -d

Troubleshooting

Container won't start

# Check logs
docker-compose logs -f

# Check container status
docker-compose ps

Database errors

# 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:

ports:
  - "8080:3001"  # Maps host port 8080 to container port 3001

Health check failing

# 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:

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:

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:

# 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