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 <noreply@anthropic.com>
This commit is contained in:
@@ -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/
|
|
||||||
@@ -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=
|
|
||||||
219
DOCKER.md
219
DOCKER.md
@@ -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
|
|
||||||
```
|
|
||||||
72
Dockerfile
72
Dockerfile
@@ -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"]
|
|
||||||
@@ -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
|
|
||||||
@@ -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 "$@"
|
|
||||||
Reference in New Issue
Block a user