# 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: ```bash cp .env.example .env ``` ### 2. Configure Environment Variables Edit the `.env` file with your settings: ```env # 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 ```bash docker-compose up -d ``` ### 4. Verify Deployment Check that both services are running: ```bash 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: ### Option 1: Change Application Port (Recommended) Edit `.env`: ```env PORT=8080 ``` Edit `docker-compose.yml`: ```yaml services: app: ports: - "8080:8080" # Change both ports ``` ### Option 2: Map to Different External Port Edit `docker-compose.yml` only: ```yaml 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: ```bash # 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: ```bash # 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: ```nginx 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 ```bash # All services docker-compose logs -f # App only docker-compose logs -f app # Database only docker-compose logs -f db ``` ### Restart Services ```bash # Restart all docker-compose restart # Restart app only docker-compose restart app ``` ### Stop Services ```bash # 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 ```bash # Pull latest changes git pull # Rebuild and restart docker-compose up -d --build ``` ### Check Service Health ```bash # Check container status docker-compose ps # Check app health endpoint curl http://localhost:5000/api/health # Should return: {"status":"ok"} ``` ## Database Management ### Backup Database ```bash docker-compose exec db pg_dump -U taskflow taskflow > backup.sql ``` ### Restore Database ```bash docker-compose exec -T db psql -U taskflow taskflow < backup.sql ``` ### Access Database Console ```bash docker-compose exec db psql -U taskflow taskflow ``` ### View Database Data ```bash # 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](./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:** ```bash 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:** ```bash docker-compose ps db ``` **Verify DATABASE_URL:** ```bash docker-compose exec app env | grep DATABASE_URL ``` **Test database connection:** ```bash docker-compose exec db pg_isready -U taskflow ``` ### Application Shows Errors **Check environment variables:** ```bash docker-compose config ``` **Restart with fresh build:** ```bash docker-compose down docker-compose up -d --build ``` ### Data Not Persisting Make sure the database volume exists: ```bash docker volume ls | grep taskflow ``` If missing, recreate: ```bash docker-compose down docker-compose up -d ``` ### Port Already in Use **Find what's using the port:** ```bash # 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: ```yaml 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`: ```yaml 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`: ```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:** ```bash docker pull registry.local.nothaft.cloud/taskflow:latest ``` 2. **Create docker-compose.yml for pre-built image:** ```yaml 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:** ```bash docker-compose up -d ``` ### .drone.yml Configuration Your `.drone.yml` file should build and push to your registry: ```yaml 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](./README.md) - Review [DEPLOYMENT.md](./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! 🚀