Files
task-manager/DOCKER-COMPOSE.md
paul-nothaft e0512aa412
continuous-integration/drone/push Build is passing
Fix Vite module not found error in production Docker deployments
Update Dockerfile to compile server files separately without bundling, preventing Vite dependency issues in production. Includes troubleshooting documentation for the Vite module error.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/SBF5OKZ
2025-10-23 15:00:04 +00:00

9.7 KiB

Docker Compose Deployment Guide

This guide provides step-by-step instructions for deploying TaskFlow using Docker Compose.

Prerequisites

  • Docker Engine 20.10 or later
  • Docker Compose 2.0 or later
  • At least 1GB free disk space

Quick Start

1. Create Environment File

Copy the example environment file and customize it:

cp .env.example .env

2. Configure Environment Variables

Edit the .env file with your settings:

# Required: Set a secure database password
POSTGRES_PASSWORD=your_secure_password_here

# Optional: Customize these if needed
NODE_ENV=production
PORT=5000
POSTGRES_USER=taskflow
POSTGRES_DB=taskflow

3. Start the Application

docker-compose up -d

4. Verify Deployment

Check that both services are running:

docker-compose ps

You should see both taskflow-app and taskflow-db with status "Up".

5. Access the Application

Open your browser and navigate to:

http://localhost:5000

Or if deployed on a server:

http://your-server-ip:5000

Environment Variables Reference

Required Variables

Variable Description Example
POSTGRES_PASSWORD Database password (MUST be changed from default) MySecurePass123!

Optional Variables

Variable Description Default Notes
NODE_ENV Application environment production Use production for deployment
PORT Application port 5000 Change if port 5000 is already in use
POSTGRES_USER Database username taskflow Can be customized
POSTGRES_DB Database name taskflow Can be customized
POSTGRES_PORT Internal database port 5432 Usually no need to change

Auto-Generated Variables

These are automatically set by docker-compose and don't need configuration:

  • DATABASE_URL - Full PostgreSQL connection string
  • PGHOST - Database hostname
  • PGUSER - Database username (from POSTGRES_USER)
  • PGPASSWORD - Database password (from POSTGRES_PASSWORD)
  • PGDATABASE - Database name (from POSTGRES_DB)
  • PGPORT - Database port (from POSTGRES_PORT)

Changing the Port

If port 5000 is already in use, you have two options:

Edit .env:

PORT=8080

Edit docker-compose.yml:

services:
  app:
    ports:
      - "8080:8080"  # Change both ports

Option 2: Map to Different External Port

Edit docker-compose.yml only:

services:
  app:
    ports:
      - "8080:5000"  # External:Internal

Then access at http://localhost:8080

Security Best Practices

1. Strong Database Password

Never use the default password in production!

Generate a strong password:

# On Linux/Mac
openssl rand -base64 32

# Or use a password manager

2. Restrict Network Access

If running on a server, use a firewall to restrict access:

# Example: Allow only from specific IP
sudo ufw allow from 192.168.1.0/24 to any port 5000

3. Use HTTPS in Production

For production deployments, place TaskFlow behind a reverse proxy with SSL:

  • Nginx
  • Traefik
  • Caddy

Example Nginx configuration:

server {
    listen 443 ssl;
    server_name taskflow.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Common Operations

View Logs

# All services
docker-compose logs -f

# App only
docker-compose logs -f app

# Database only
docker-compose logs -f db

Restart Services

# Restart all
docker-compose restart

# Restart app only
docker-compose restart app

Stop Services

# Stop but keep data
docker-compose stop

# Stop and remove containers (data persists)
docker-compose down

# Stop and remove everything including data
docker-compose down -v

Update Application

# Pull latest changes
git pull

# Rebuild and restart
docker-compose up -d --build

Check Service Health

# Check container status
docker-compose ps

# Check app health endpoint
curl http://localhost:5000/api/health

# Should return: {"status":"ok"}

Database Management

Backup Database

docker-compose exec db pg_dump -U taskflow taskflow > backup.sql

Restore Database

docker-compose exec -T db psql -U taskflow taskflow < backup.sql

Access Database Console

docker-compose exec db psql -U taskflow taskflow

View Database Data

# Connect to database
docker-compose exec db psql -U taskflow taskflow

# List tables
\dt

# Query tasks
SELECT * FROM tasks;

# Query labels
SELECT * FROM labels;

# Exit
\q

Troubleshooting

Vite Module Error

If you see an error like:

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'vite'

Solution: This has been fixed in the latest version. Make sure you're using the updated Dockerfile that compiles server files separately. See DOCKER-FIX.md for technical details.

Quick fix:

  1. Rebuild your Docker image with the latest Dockerfile
  2. Redeploy with docker-compose up -d --build

Container Won't Start

Check logs:

docker-compose logs app

Common issues:

  • Port already in use: Change PORT in .env
  • Database not ready: Wait 10-20 seconds and check again
  • Permission issues: Check file permissions on project directory

Database Connection Failed

Check database is running:

docker-compose ps db

Verify DATABASE_URL:

docker-compose exec app env | grep DATABASE_URL

Test database connection:

docker-compose exec db pg_isready -U taskflow

Application Shows Errors

Check environment variables:

docker-compose config

Restart with fresh build:

docker-compose down
docker-compose up -d --build

Data Not Persisting

Make sure the database volume exists:

docker volume ls | grep taskflow

If missing, recreate:

docker-compose down
docker-compose up -d

Port Already in Use

Find what's using the port:

# Linux/Mac
sudo lsof -i :5000

# Or
sudo netstat -tulpn | grep 5000

Options:

  1. Stop the other service
  2. Change TaskFlow port (see "Changing the Port" section)

Production Deployment Checklist

  • Change POSTGRES_PASSWORD to a strong, unique password
  • Set NODE_ENV=production in .env
  • Configure firewall rules
  • Set up SSL/HTTPS reverse proxy
  • Configure automated backups
  • Set up monitoring/logging
  • Test database backup and restore procedures
  • Document your configuration
  • Set up automatic updates (optional)

Advanced Configuration

Custom Database Configuration

Edit docker-compose.yml to add PostgreSQL configuration:

services:
  db:
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_INITDB_ARGS=-E UTF8 --locale=en_US.UTF-8

Resource Limits

Limit container resources in docker-compose.yml:

services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M

External Database

To use an external PostgreSQL database instead of the container:

  1. Remove the db service from docker-compose.yml
  2. Set DATABASE_URL in .env:
    DATABASE_URL=postgresql://user:password@external-host:5432/taskflow
    

Deployment via CI/CD (Drone CI)

If you're using Drone CI to build and deploy your Docker images:

Using Pre-built Images

If your CI system (like Drone) builds the image for you:

  1. Pull the image from your registry:

    docker pull registry.local.nothaft.cloud/taskflow:latest
    
  2. Create docker-compose.yml for pre-built image:

    version: '3.8'
    
    services:
      db:
        image: postgres:16-alpine
        environment:
          - POSTGRES_USER=${POSTGRES_USER:-taskflow}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
          - POSTGRES_DB=${POSTGRES_DB:-taskflow}
        volumes:
          - postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-taskflow}"]
          interval: 5s
          timeout: 5s
          retries: 5
    
      app:
        image: registry.local.nothaft.cloud/taskflow:latest  # Use pre-built image
        ports:
          - "${PORT:-5000}:5000"
        environment:
          - NODE_ENV=production
          - DATABASE_URL=postgresql://${POSTGRES_USER:-taskflow}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-taskflow}
          - PORT=5000
        depends_on:
          db:
            condition: service_healthy
        restart: unless-stopped
    
    volumes:
      postgres_data:
    
  3. Start services:

    docker-compose up -d
    

.drone.yml Configuration

Your .drone.yml file should build and push to your registry:

kind: pipeline
type: docker
name: default

steps:
  - name: build taskflow
    image: plugins/docker
    settings:
      repo: registry.local.nothaft.cloud/taskflow
      tags: latest
      dockerfile: Dockerfile
      context: .
      registry: registry.local.nothaft.cloud

Support

For issues and questions:

  • Check the main README.md
  • Review DEPLOYMENT.md for detailed deployment options
  • Open an issue on the repository

Next Steps

Once deployed:

  1. Create your first tasks and labels
  2. Explore calendar and kanban views
  3. Try the time tracking feature
  4. Set up automated backups
  5. Configure HTTPS for secure access

Happy task managing! 🚀