12 KiB
Docker Deployment Guide
Complete guide for deploying Dashboard Solusi AI Peternakan Ayam using Docker containers.
📋 Table of Contents
🏗️ Architecture
The application runs in 3 Docker containers:
┌─────────────────────────────────────────────────┐
│ Host Server │
│ │
│ ┌────────────────┐ ┌──────────────────┐ │
│ │ Frontend │ │ Backend │ │
│ │ (Nginx) │◄────►│ (Node.js) │ │
│ │ Port 80 │ │ Port 5001 │ │
│ └────────────────┘ └──────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────────┐ │
│ │ │ Database │ │
│ └──────────────►│ (PostgreSQL) │ │
│ │ Port 5432 │ │
│ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────┘
Container Details
| Container | Image | Port | Description |
|---|---|---|---|
| frontend | nginx:alpine | 80 | React app served by Nginx |
| backend | node:18-alpine | 5001 | Express API server |
| database | postgres:16-alpine | 15432→5432 | PostgreSQL database server |
Network Communication
- Frontend → Backend: Internal Docker network (
dashboard-network) - Backend → Database: Internal Docker network (
dashboard-network) - Client → Frontend: HTTP port 80 (or 5002 in dev)
- Host → Database: TCP port 15432 (for DBeaver, psql, backups)
📦 Prerequisites
Required Software
Check versions:
docker --version
docker-compose --version
Server Requirements
- OS: Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+)
- RAM: Minimum 2GB, Recommended 4GB+
- Disk: Minimum 10GB free space
- CPU: 2+ cores recommended
Ports
Ensure these ports are available:
- 80 or 5002: Frontend (HTTP)
- 5001: Backend API
- 15432: PostgreSQL (for local access, DBeaver, backups)
Check port availability:
sudo lsof -i :80
sudo lsof -i :5001
sudo lsof -i :15432
🚀 Quick Start
1. Clone Repository
git clone <repository-url>
cd dashboard-solusi-ai-peternakan-ayam
2. Configure Environment (Optional)
# Copy and edit if you need custom settings
cp .env.example .env
3. Build and Start Containers
docker-compose up -d --build
This will:
- ✅ Build frontend and backend images
- ✅ Create containers
- ✅ Initialize database
- ✅ Start all services
4. Verify Deployment
# Check container status
docker-compose ps
# Check logs
docker-compose logs -f
# Test frontend
curl http://localhost
# Test backend
curl http://localhost/api/health
5. Access Application
Open browser: http://your-server-ip
⚙️ Configuration
Environment Variables
Frontend (.env.example)
# API URL - Uses nginx proxy in Docker
VITE_API_URL=/api
Backend Environment Variables
These are set in docker-compose.yml:
environment:
- NODE_ENV=production
- PORT=5001
- DB_HOST=database
- DB_PORT=5432
- DB_USER=${DB_USER:-dashboard_user}
- DB_PASSWORD=${DB_PASSWORD:-change_this_password}
- DB_NAME=${DB_NAME:-dashboard_db}
- DB_SSL=false
Custom Configuration
1. Create environment file:
cp .env.example .env
cp backend/.env.example backend/.env
2. Edit docker-compose.yml:
Change ports:
services:
frontend:
ports:
- '8080:80' # Change from 80 to 8080
Change database credentials:
# Create .env file in project root:
DB_USER=my_user
DB_PASSWORD=my_secure_password
DB_NAME=my_database
🚢 Deployment
Development Deployment
# Build and start with logs
docker-compose up --build
# Press Ctrl+C to stop
Production Deployment
# Build and start in detached mode
docker-compose up -d --build
# View logs
docker-compose logs -f
# Stop viewing logs (Ctrl+C, containers keep running)
Update Deployment
When code changes:
# Pull latest code
git pull origin main
# Rebuild and restart
docker-compose down
docker-compose up -d --build
Zero-Downtime Update
# Build new images
docker-compose build
# Restart services one by one
docker-compose up -d --no-deps --build backend
docker-compose up -d --no-deps --build frontend
🔧 Management
Container Management
# Start all containers
docker-compose start
# Stop all containers
docker-compose stop
# Restart all containers
docker-compose restart
# Stop and remove containers
docker-compose down
# Stop and remove containers + volumes
docker-compose down -v
View Logs
# All containers
docker-compose logs -f
# Specific container
docker-compose logs -f backend
docker-compose logs -f frontend
# Last 100 lines
docker-compose logs --tail=100
# Since timestamp
docker-compose logs --since 2025-12-22T10:00:00
Execute Commands in Container
# Backend shell
docker-compose exec backend sh
# Frontend shell
docker-compose exec frontend sh
# Database shell (PostgreSQL)
docker-compose exec database psql -U dashboard_user -d dashboard_db
# Run seed in backend
docker-compose exec backend node database/seed-postgres.js
Database Management
# Backup database (recommended)
./scripts/backup-postgres.sh
# Manual backup
docker-compose exec database sh -c \
'PGPASSWORD="$POSTGRES_PASSWORD" pg_dump -h 127.0.0.1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
| gzip > backup-$(date +%Y%m%d).sql.gz
# Restore database
./scripts/restore-postgres-local.sh --reset backups/dashboard_db-YYYYMMDD.sql.gz
# Query database
docker-compose exec database psql -U dashboard_user -d dashboard_db -c "SELECT * FROM cycles;"
# Connect with psql from host
psql -h localhost -p 15432 -U dashboard_user -d dashboard_db
Health Checks
# Check container health
docker-compose ps
# Expected output:
# NAME STATUS
# dashboard-database Up (healthy)
# dashboard-backend Up (healthy)
# dashboard-frontend Up (healthy)
# Manual health checks
curl http://localhost:5002/health # Backend
curl http://localhost:5002/api/cycles # API test
# Database health
docker-compose exec database pg_isready -U dashboard_user
🐛 Troubleshooting
Container Won't Start
Problem: Container exits immediately
# Check logs
docker-compose logs backend
docker-compose logs frontend
# Common causes:
# - Port already in use
# - Missing dependencies
# - Configuration error
Solution:
# Remove and rebuild
docker-compose down
docker-compose up --build
Port Conflicts
Problem: Port 80 or 5001 already in use
# Find process using port
sudo lsof -i :80
sudo lsof -i :5001
# Kill process
sudo kill -9 <PID>
# Or change port in docker-compose.yml
Database Not Persisting
Problem: Data lost after restart
# Check volume
docker volume ls | grep db-data
docker volume inspect dashboard-solusi-ai-peternakan-ayam_db-data
# Check database is accessible
docker-compose exec database psql -U dashboard_user -d dashboard_db -c "SELECT COUNT(*) FROM cycles;"
Solution:
# Make sure you're not using -v flag when stopping
docker-compose down # Preserves volumes
# NOT: docker-compose down -v # This deletes volumes!
# Restart containers
docker-compose up -d
Frontend Can't Connect to Backend
Problem: API requests fail with CORS or connection errors
Check:
# Test backend directly
curl http://localhost:5001/health
# Check nginx proxy config
docker-compose exec frontend cat /etc/nginx/conf.d/default.conf
# Check network
docker network ls
docker network inspect peternakan-network
Solution:
# Verify both containers are on same network
docker-compose down
docker-compose up -d
Out of Disk Space
Problem: Build fails with "no space left on device"
# Check disk usage
df -h
# Clean Docker
docker system prune -a
docker volume prune
# Remove unused images
docker image prune -a
Database Connection Errors
Problem: Backend can't connect to database
# Check database container is running and healthy
docker-compose ps database
# Check logs
docker-compose logs database
docker-compose logs backend
# Verify connection from backend
docker-compose exec backend sh -c 'psql -h database -U $DB_USER -d $DB_NAME -c "SELECT 1"'
# Restart services
docker-compose restart database backend
Container Memory Issues
Problem: Container crashes with OOM
# Check memory usage
docker stats
# Add memory limits in docker-compose.yml:
services:
backend:
mem_limit: 512m
mem_reservation: 256m
📊 Monitoring
Resource Usage
# Real-time stats
docker stats
# Container processes
docker-compose top
Logs Analysis
# Search logs
docker-compose logs | grep ERROR
docker-compose logs | grep "Failed to"
# Export logs
docker-compose logs > application.log
🔒 Security
Production Recommendations
-
Use HTTPS:
- Add reverse proxy (Nginx/Apache) with SSL
- Get certificate from Let's Encrypt
-
Firewall:
# Allow only necessary ports
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
- Update regularly:
# Update base images
docker-compose pull
docker-compose up -d
- Secure database:
# Use strong passwords in production .env
DB_PASSWORD=your_very_strong_password_here
# Enable SSL for production
DB_SSL=true
# Block external database access (only allow from Docker network)
# Edit docker-compose.yml: remove or restrict ports section for database
🔄 Backup & Restore
Backup
Use the provided script:
./scripts/backup-postgres.sh
This creates a compressed SQL dump in ./backups/dashboard_db-YYYYMMDD-HHMMSS.sql.gz
Manual backup:
#!/bin/bash
# Manual backup example
BACKUP_DIR="./backups"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
docker-compose exec -T database sh -c \
'PGPASSWORD="$POSTGRES_PASSWORD" pg_dump -h 127.0.0.1 -U "$POSTGRES_USER" -d "$POSTGRES_DB" --no-owner --no-acl' \
| gzip -c > "$BACKUP_DIR/dashboard_db-$DATE.sql.gz"
echo "Backup completed: $BACKUP_DIR/dashboard_db-$DATE.sql.gz"
Restore
Use the provided script:
./scripts/restore-postgres-local.sh --reset backups/dashboard_db-YYYYMMDD-HHMMSS.sql.gz
This will:
- Stop and remove local Docker volumes
- Start fresh database
- Restore from backup file
Note: The --reset flag is required to prevent mixing old and new data.
📚 Additional Resources
🆘 Support
For issues specific to Docker deployment:
- Check logs:
docker-compose logs -f - Verify configuration:
docker-compose config - Check GitHub Issues
- Contact support@cpsp.id
Docker deployment guide by PT Cipta Pola Solusi Prima - 2025