7.1 KiB
Docker Deployment Guide
This guide explains how to deploy the Pradit application using Docker and Docker Compose.
Prerequisites
- Docker Engine 20.10+
- Docker Compose 2.0+
- Gemini API Key (get from https://aistudio.google.com/app/apikey)
Quick Start
1. Setup Environment Variables
Copy the example environment file and add your Gemini API key:
cp .env.example .env
Edit .env and set your GEMINI_API_KEY:
GEMINI_API_KEY=your_actual_api_key_here
2. Run Development Mode
Development mode includes hot reload for rapid iteration:
docker-compose --profile dev up
Access the app at: http://localhost:3000
3. Run Production Mode
Production mode uses optimized build with nginx:
docker-compose --profile prod up -d
Access the app at: http://localhost:80
Docker Compose Profiles
This project uses Docker Compose profiles to separate dev and prod environments.
Development Profile (dev)
- Port: 3000
- Hot Reload: Enabled
- Volume Mounts: Source code mounted for live changes
- Server: Vite dev server
- Optimizations: None (fast rebuild)
Commands:
# Start dev server
docker-compose --profile dev up
# Start in background
docker-compose --profile dev up -d
# View logs
docker-compose --profile dev logs -f
# Stop
docker-compose --profile dev down
Production Profile (prod)
- Port: 80
- Hot Reload: Disabled
- Build: Optimized static build
- Server: Nginx with compression and caching
- Health Check: Enabled on /health endpoint
Commands:
# Build and start production
docker-compose --profile prod up -d
# Rebuild after code changes
docker-compose --profile prod up -d --build
# View logs
docker-compose --profile prod logs -f
# Stop
docker-compose --profile prod down
Manual Docker Commands
Build Images
# Development image
docker build -f Dockerfile.dev -t pradit:dev .
# Production image
docker build -f Dockerfile -t pradit:prod .
Run Containers
# Development
docker run -p 3000:3000 -v $(pwd):/app -v /app/node_modules \
-e GEMINI_API_KEY=your_key pradit:dev
# Production
docker run -p 80:80 pradit:prod
Architecture
Development Container
- Base: node:20-alpine
- Package Manager: pnpm
- Volumes: Source code mounted for hot reload
- Port: 3000
- Command:
pnpm run dev
Production Container
Multi-stage build for minimal image size:
-
Builder Stage:
- Installs dependencies with pnpm
- Builds optimized production bundle
- Uses node:20-alpine
-
Runtime Stage:
- Serves static files with nginx:alpine
- Configured for SPA routing
- Gzip compression enabled
- Security headers added
- Health check endpoint at
/health
Configuration Files
Dockerfile
Production multi-stage build configuration.
Dockerfile.dev
Development container with hot reload support.
docker-compose.yml
Orchestration for both dev and prod profiles.
nginx.conf
Nginx configuration for production:
- SPA routing (serves index.html for all routes)
- Gzip compression
- Static asset caching (1 year)
- Security headers
- Health check endpoint
.dockerignore
Excludes unnecessary files from Docker build context:
- node_modules
- Build artifacts
- Environment files
- IDE configurations
- Documentation
Environment Variables
| Variable | Required | Description |
|---|---|---|
GEMINI_API_KEY |
Yes | API key for Gemini AI |
NODE_ENV |
No | Environment mode (development/production) |
Security Note: Never commit .env file. Use .env.example as template.
Port Configuration
| Service | Port | Description |
|---|---|---|
| Development | 3000 | Vite dev server |
| Production | 80 | Nginx web server |
To use different ports, edit docker-compose.yml:
ports:
- "8080:80" # Host:Container
Troubleshooting
Port Already in Use
# Find process using port 3000
netstat -ano | findstr :3000 # Windows
lsof -i :3000 # Linux/Mac
# Change port in docker-compose.yml
ports:
- "3001:3000"
API Key Not Working
Ensure .env file exists and contains valid key:
cat .env # Linux/Mac
type .env # Windows
Restart containers after changing .env:
docker-compose --profile dev down
docker-compose --profile dev up
Container Won't Start
Check logs for errors:
docker-compose --profile dev logs
docker-compose --profile prod logs
Remove containers and rebuild:
docker-compose down -v
docker-compose --profile prod up -d --build
Volume Permission Issues (Linux)
If encountering permission issues with mounted volumes:
# Add user ID to docker-compose.yml
user: "${UID}:${GID}"
Build Cache Issues
Clear Docker build cache:
docker builder prune -a
docker-compose build --no-cache
Health Checks
Production container includes health check:
# Check container health
docker ps
# Manual health check
curl http://localhost/health
Logs and Debugging
# Follow logs
docker-compose logs -f
# Specific service logs
docker-compose --profile dev logs pradit-dev
docker-compose --profile prod logs pradit-prod
# Enter running container
docker exec -it pradit-dev sh
docker exec -it pradit-prod sh
Cleaning Up
# Stop and remove containers
docker-compose down
# Remove containers and volumes
docker-compose down -v
# Remove images
docker rmi pradit:dev pradit:prod
# Full cleanup (all unused Docker resources)
docker system prune -a
Production Deployment
For cloud deployment (AWS, GCP, Azure, etc.):
- Build and tag image:
docker build -t your-registry/pradit:latest .
- Push to registry:
docker push your-registry/pradit:latest
- Deploy to orchestration platform (Kubernetes, ECS, etc.)
Performance Optimization
Production Build
- Tree shaking removes unused code
- Minification reduces bundle size
- Gzip compression (nginx)
- Static asset caching (1 year)
- Multi-stage build minimizes image size
Development Build
- Fast rebuild with hot module replacement
- Source maps for debugging
- No minification for faster builds
Security Best Practices
- Never commit API keys - Use environment variables
- Use multi-stage builds - Minimize attack surface
- Run as non-root - Production nginx runs as nginx user
- Keep images updated - Regularly update base images
- Scan for vulnerabilities - Use
docker scan pradit:prod - Use secrets management - For production, use Docker secrets or cloud provider solutions
Additional Resources
Support
For issues specific to Docker setup, check:
- Docker daemon is running
- Environment variables are set correctly
- Ports are not already in use
- Sufficient disk space for images and containers
For application issues, refer to main README.md.