Skip to content

Maintenance & Updates

Guide to maintaining and updating your self-hosted ANTE ERP installation.

If you installed ANTE ERP using the CLI (ante-erp-cli), these commands simplify all maintenance tasks. The CLI handles complex operations automatically with built-in safety checks.

Daily Maintenance

bash
# Quick health check (recommended daily)
ante status

# View service logs
ante logs --lines 50

# Check for any errors
ante logs | grep -i error

Automated Daily Tasks:

  • Service health monitoring
  • Automatic log rotation
  • Built-in error detection

Backup Operations

Creating Backups

bash
# Create full backup (recommended before updates)
ante backup

# Backup creates:
# - Complete PostgreSQL dump
# - MongoDB backup
# - Redis data snapshot
# - Uploaded files
# - Configuration files
# - Stored in: ./backups/ante-backup-YYYYMMDD-HHMMSS.tar.gz

Backup Details:

  • Automatic compression (tar.gz format)
  • Timestamped filenames
  • Includes all critical data
  • Average backup time: 2-5 minutes
  • Average size: 100MB - 2GB (depends on data)

Managing Backups

bash
# List all backups with details
ante backup:list

# Shows:
# - Backup filename
# - Creation date
# - File size
# - Age

# Example output:
# Backup Files (sorted by date):
# ├─ ante-backup-20251027-140530.tar.gz (234 MB) - 2 days ago
# ├─ ante-backup-20251025-020015.tar.gz (228 MB) - 4 days ago
# └─ ante-backup-20251024-020012.tar.gz (225 MB) - 5 days ago

Restoring from Backup

The ante restore command automatically detects both local and S3 backups, allowing you to choose from all available backups.

bash
# Interactive restore (shows both local and S3 backups)
ante restore

# Example output:
# Found 8 backup(s):
#   Local: 3
#   S3:    5
#
# ? Select backup to restore:
#   ❯ [S3]     ante-backup-2025-11-18_03-00-00-AM.tar.gz (287.45 MB) - today
#     [S3]     ante-backup-2025-11-17_03-00-00-AM.tar.gz (285.32 MB) - 1 day ago
#     [S3]     ante-backup-2025-11-16_03-00-00-AM.tar.gz (283.19 MB) - 2 days ago
#     [LOCAL]  ante-backup-2025-11-15_03-00-00-AM.tar.gz (280.00 MB) - 3 days ago
#     [LOCAL]  ante-backup-2025-11-14_03-00-00-AM.tar.gz (278.00 MB) - 4 days ago

# Restore specific backup file
ante restore /path/to/backup.tar.gz

# The CLI will:
# 1. Download from S3 if remote backup selected (with progress)
# 2. Stop affected services
# 3. Restore all databases
# 4. Restore uploaded files
# 5. Restore configuration
# 6. Restart services
# 7. Clean up temporary files
# 8. Verify health

Features:

  • Unified view - Shows both local and S3 backups in one list
  • Auto-download - Automatically downloads S3 backups before restoring
  • Progress tracking - Shows download progress for S3 backups
  • Smart sorting - Newest backups appear first
  • Relative timestamps - Shows "today", "1 day ago", etc.
  • Auto-cleanup - Removes downloaded S3 files after restore

Multi-Server S3 Setup: If you use the same S3 bucket for multiple servers, backups are automatically isolated by server IP:

your-bucket/
├── 143.198.91.153/    # Production server
├── 178.128.49.38/     # Staging server
└── 192.168.1.100/     # Development server

Each server's ante restore command only shows backups from its own folder, preventing accidental cross-server restores.

Important: Always test restores monthly to ensure backup integrity.

The ANTE CLI provides automated daily backups to S3-compatible cloud storage (DigitalOcean Spaces, AWS S3, etc.) with automatic scheduling and retention management.

Setup Daily S3 Backups

bash
# Interactive setup (recommended for first-time configuration)
ante set-daily-backup

# The CLI will prompt you for:
# - S3 Endpoint (e.g., https://sgp1.digitaloceanspaces.com)
# - S3 Region (e.g., sgp1)
# - S3 Bucket Name
# - S3 Access Key
# - S3 Secret Key
# - Backup Schedule (default: 3:00 AM daily)
# - Retention Period (default: 30 days)

What Happens During Setup:

  1. ✅ Tests S3 connection with provided credentials
  2. ✅ Encrypts and stores credentials securely
  3. ✅ Sets up automated cron job for daily backups
  4. ✅ Runs immediate test backup to verify configuration
  5. ✅ Configures 30-day automatic cleanup

Non-Interactive Setup

bash
# Configure with command-line flags (useful for automation)
ante set-daily-backup \
  --endpoint https://sgp1.digitaloceanspaces.com \
  --region sgp1 \
  --bucket ante-backups \
  --access-key DO801A32T8C74... \
  --secret-key 4Uh5/JqSDrgkeQ... \
  --retention 30 \
  --folder-prefix my-server

Managing Daily Backups

bash
# Check backup status and configuration
ante daily-backup status

# Example output:
# ╔══════════════════════════════════════════╗
# ║      Daily Backup Status                 ║
# ╚══════════════════════════════════════════╝
#
#   Status          Enabled
#   Schedule        0 3 * * * (Daily at 3:00 AM)
#   S3 Bucket       ante-backups
#   S3 Endpoint     https://sgp1.digitaloceanspaces.com
#   Folder Prefix   143.198.91.153
#   Retention       30 days
#   Last Backup     2025-11-18 03:00:15
#   Last Status     Success
#
# 📊 S3 Bucket Info:
#   Total Backups   15
#   Total Size      4.2 GB
#   Oldest Backup   2025-10-20 03:00:02
#   Newest Backup   2025-11-18 03:00:15

# Trigger manual backup (for testing)
ante daily-backup run

# View backup logs
ante daily-backup logs

# List all remote backups on S3
ante daily-backup list

# Example output:
# 📦 Remote Backups (15 total):
# ┌──────────────────────────────────────────────┬──────────┬──────────────────────┐
# │ Name                                          │ Size     │ Date                 │
# ├──────────────────────────────────────────────┼──────────┼──────────────────────┤
# │ ante-backup-2025-11-18_03-00-00-AM.tar.gz    │ 287.45 MB│ 2025-11-18 03:00:15 │
# │ ante-backup-2025-11-17_03-00-00-AM.tar.gz    │ 285.32 MB│ 2025-11-17 03:00:10 │
# │ ante-backup-2025-11-16_03-00-00-AM.tar.gz    │ 283.19 MB│ 2025-11-16 03:00:08 │
# └──────────────────────────────────────────────┴──────────┴──────────────────────┘

# Clean old backups manually (respects retention period)
ante daily-backup clean

# Disable automated backups
ante disable-daily-backup

How It Works

Daily Backup Process:

  1. 3:00 AM - Cron triggers backup script
  2. Create Local Backup - Full database and files backup
  3. Upload to S3 - Encrypted transfer to cloud storage
  4. Organize by IP - Backups stored in server-specific folder
  5. Auto-Cleanup - Deletes backups older than retention period
  6. Logging - Records all operations to ~/.ante-cli-backup.log

File Organization on S3:

your-bucket/
└── 143.198.91.153/                          # Server IP or custom prefix
    ├── ante-backup-2025-11-18_03-00-00-AM.tar.gz
    ├── ante-backup-2025-11-17_03-00-00-AM.tar.gz
    ├── ante-backup-2025-11-16_03-00-00-AM.tar.gz
    └── ... (up to 30 days)

Backup Contents

Each backup includes:

  • ✅ Complete PostgreSQL database dump
  • ✅ MongoDB backup
  • ✅ Redis data snapshot
  • ✅ Uploaded files and attachments
  • ✅ Configuration files (.env, docker-compose.yml)
  • ✅ Compressed with gzip for efficiency

Security Features

  • 🔐 Encrypted Credentials - S3 keys encrypted at rest using AES-256
  • 🔐 Secure Transfer - HTTPS for all S3 operations
  • 🔐 Server Isolation - Each server stores backups in separate folder
  • 🔐 Access Control - Credentials stored in user-specific config

Cost Optimization

Storage Costs (DigitalOcean Spaces example):

  • 250GB included: $5/month
  • Average backup size: ~300MB
  • 30 days retention: ~9GB total
  • Estimated cost: $5/month (well within included storage)

Recommendations:

  • Use same region as your server to reduce egress costs
  • Configure 30-day retention (default) to balance recovery needs and cost
  • Monitor bucket size: ante daily-backup status

Troubleshooting

View backup logs:

bash
# View last 50 lines
ante daily-backup logs

# View last 100 lines
ante daily-backup logs --lines 100

# Follow logs in real-time (during manual run)
tail -f ~/.ante-cli-backup.log

Common issues:

  1. S3 connection failed

    • Verify credentials are correct
    • Check bucket exists and is accessible
    • Ensure firewall allows HTTPS (port 443)
  2. Upload timeout

    • Check network connectivity
    • Consider increasing timeout in code
    • Use same region as server
  3. Backup not running automatically

    • Verify cron job: crontab -l | grep ante-daily-backup
    • Check cron logs: grep CRON /var/log/syslog
    • Ensure CLI is in PATH: which ante
  4. Old backups not cleaning up

    • Run manual cleanup: ante daily-backup clean
    • Check retention setting: ante daily-backup status

Best Practices

Test before production - Run ante daily-backup run to test configuration ✅ Monitor regularly - Check ante daily-backup status weekly ✅ Verify backups - Periodically list remote backups with ante daily-backup listUse strong credentials - Generate dedicated S3 access keys with limited permissions ✅ Enable bucket versioning - Protect against accidental deletion in S3 ✅ Set lifecycle policies - Configure S3 lifecycle rules for additional retention tiers

Local Backup Scheduling (Legacy)

For local-only backups without cloud storage:

bash
# Schedule daily backups using cron
crontab -e

# Add this line for daily backup at 2 AM:
0 2 * * * /usr/local/bin/ante backup >> ~/ante-backup.log 2>&1

# Weekly backup verification (Sunday 3 AM):
0 3 * * 0 /usr/local/bin/ante backup:list >> ~/ante-backup-report.log 2>&1

Updating ANTE ERP

Automatic Update

bash
# Update to latest version (safest method)
ante update

# The CLI automatically:
# 1. Creates full backup first
# 2. Pulls latest Docker images
# 3. Stops services gracefully
# 4. Applies database migrations
# 5. Starts updated services
# 6. Verifies health
# 7. Rolls back if issues detected

Update Process:

  • Duration: 5-10 minutes
  • Downtime: 2-3 minutes
  • Automatic backup: Yes (before update)
  • Automatic rollback: Yes (if health check fails)

Check for Updates

bash
# Check if updates available (no changes made)
ante update --check

# Example output:
# Current version: 1.2.0
# Latest version: 1.3.0
# Update available: Yes
#
# Changelog:
# - Added new reporting features
# - Fixed timezone issues
# - Performance improvements

Update with Restart

bash
# Update and restart services
ante update --restart

# Force update (skip version check)
ante update --force

Database Maintenance

Database Migrations

bash
# Run pending migrations
ante db:migrate

# Check migration status
ante db:migrate --status

# Shows:
# ✓ 20251025120000_initial_schema
# ✓ 20251026140000_add_geolocation
# ⏳ 20251027100000_add_notifications (pending)

Database Optimization

bash
# Optimize database performance (recommended weekly)
ante db:optimize

# This performs:
# - VACUUM ANALYZE on PostgreSQL
# - Index optimization
# - Table statistics update
# - Query cache refresh
# - Duration: 5-15 minutes

Database Information

bash
# View database info and statistics
ante db:info

# Shows:
# - Database size
# - Number of tables
# - Connection count
# - Cache hit ratio
# - Top 5 largest tables
# - Index usage statistics

Database Shell Access

bash
# Open PostgreSQL shell (for manual queries)
ante db:shell

# Inside shell:
# \dt              - List tables
# \d table_name    - Describe table
# SELECT * FROM users LIMIT 10;  - Query data
# \q               - Exit

SSL Certificate Management

If you enabled HTTPS using ante ssl enable, SSL certificates are automatically managed and renewed. Here's how to monitor and maintain them:

Check Certificate Status

bash
# View certificate status and expiry
ante ssl status

# Example output:
# 🔒 SSL Certificate Status
#
# Frontend:
#    Domain: erp.company.com
#    URL: https://erp.company.com
# ✓ Certificate found
#    Expiry: 2026-01-27
#    Days remaining: 87
#    Status: Valid

Monitoring Recommendations:

  • Daily: Automated (no action needed - CLI configured auto-renewal)
  • Monthly: Run ante ssl status to verify certificates are valid
  • Quarterly: Review certificate expiry dates and ensure auto-renewal is working

Automatic Renewal

SSL certificates from Let's Encrypt are valid for 90 days and automatically renew when they have 30 days or less remaining.

Renewal is configured via:

  • Modern Linux: systemd timer (certbot.timer)
  • Legacy systems: Cron job at /etc/cron.d/certbot-renewal

Verify auto-renewal is active:

bash
# For systemd-based systems
systemctl status certbot.timer

# For cron-based systems
cat /etc/cron.d/certbot-renewal

Manual Certificate Renewal

If you need to renew certificates manually (e.g., testing or troubleshooting):

bash
# Test renewal (dry run - doesn't change anything)
sudo certbot renew --dry-run

# Force renewal (even if not due)
sudo certbot renew --force-renewal --nginx

# Reload NGINX to apply changes
sudo systemctl reload nginx

Certificate Troubleshooting

Certificate expiring soon but not renewing?

bash
# Check certbot logs
sudo tail -f /var/log/letsencrypt/letsencrypt.log

# Manually trigger renewal
sudo certbot renew --nginx

# Verify renewal timer/cron is running
systemctl is-active certbot.timer  # or check cron

Certificate already exists error?

bash
# View all certificates
sudo certbot certificates

# Delete old certificate and recreate
sudo certbot delete --cert-name your-domain.com
ante ssl enable --email admin@company.com

Domain validation failures?

bash
# Ensure DNS points to your server
dig +short your-domain.com

# Ensure ports 80 and 443 are accessible
sudo netstat -tlnp | grep -E ':(80|443)'
sudo ufw status

Re-enabling SSL After Domain Change

If you change domains or need to reconfigure SSL:

bash
# Step 1: Configure new domain
ante set-domain --frontend https://new-domain.com --api https://api.new-domain.com

# Step 2: Enable SSL for new domain
ante ssl enable --email admin@company.com

# Step 3: Verify new certificate
ante ssl status

Service Management

bash
# Check detailed status
ante status

# Start services
ante start

# Stop services (graceful shutdown)
ante stop

# Restart services
ante restart

# Restart specific service
ante restart --service backend

Health Diagnostics

bash
# Run comprehensive health check
ante doctor

# Checks performed:
# ✓ Docker installation
# ✓ Container health status
# ✓ Database connectivity
# ✓ Redis/Cache connection
# ✓ MongoDB connection
# ✓ Disk space (warns if <20% free)
# ✓ Memory usage (warns if >80%)
# ✓ Port availability
# ✓ Service response times

# Verbose output
ante doctor --verbose

# Check specific component
ante doctor --component database
ante doctor --component redis
ante doctor --component backend

Log Management

bash
# View recent logs (last 100 lines)
ante logs

# Follow logs in real-time
ante logs --follow

# View specific service logs
ante logs --service backend --follow

# View specific number of lines
ante logs --lines 500

# Search logs for errors
ante logs | grep -i error

# Export logs to file
ante logs > ante-logs-$(date +%Y%m%d).txt

Monitoring & Alerts

bash
# Daily health monitoring script
#!/bin/bash
# Save as: ~/ante-daily-check.sh

# Run health check
ante doctor

# Check for errors in logs
ERRORS=$(ante logs --lines 1000 | grep -i "error" | wc -l)

if [ $ERRORS -gt 10 ]; then
    echo "WARNING: $ERRORS errors found in logs"
    # Send notification (configure email/SMS)
fi

# Check disk space
ante status | grep -i "disk"

Schedule daily:

bash
crontab -e

# Add daily health check at 9 AM
0 9 * * * ~/ante-daily-check.sh >> ~/ante-health.log 2>&1

Configuration Management

bash
# View current configuration
ante config:show

# Edit configuration (opens in default editor)
ante config:edit

# Validate configuration
ante config:validate

# Reset to defaults (⚠️ creates backup first)
ante config:reset

Alternative: Manual Maintenance

If you installed manually without the CLI, use these Docker-based procedures:

Regular Maintenance Tasks

TaskFrequencyDurationPriority
Check service statusDaily2 minHigh
Review logsDaily5 minHigh
Database backupDaily10 minCritical
Check disk spaceWeekly2 minHigh
Update Docker imagesWeekly15 minMedium
Database maintenanceWeekly10 minMedium
Security auditMonthly30 minHigh
Test backup restoreMonthly30 minCritical
Review access logsMonthly15 minMedium

Automated Backups

Complete Backup Solution

Create a comprehensive backup script:

~/ante-erp/scripts/backup-all.sh:

bash
#!/bin/bash

###########################################
# ANTE ERP Complete Backup Script
###########################################

# Configuration
BACKUP_DIR=~/ante-erp/backups
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE=~/ante-erp/logs/backup.log

# Email notifications (optional)
NOTIFY_EMAIL="admin@yourcompany.com"
SMTP_ENABLED=false

# Docker Compose file location
COMPOSE_FILE=~/ante-erp/docker-compose.yml

###########################################
# Functions
###########################################

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

send_notification() {
    if [ "$SMTP_ENABLED" = true ]; then
        echo "$2" | mail -s "$1" "$NOTIFY_EMAIL"
    fi
}

###########################################
# Main Backup Process
###########################################

log "========================================="
log "Starting ANTE ERP backup: $DATE"
log "========================================="

# Create backup directory
mkdir -p "$BACKUP_DIR"/$DATE
cd "$BACKUP_DIR"/$DATE || exit 1

# 1. Backup PostgreSQL
log "Backing up PostgreSQL database..."
docker compose -f "$COMPOSE_FILE" exec -T postgres \
    pg_dump -U ante -F c ante_db > postgres.dump

if [ $? -eq 0 ]; then
    log "✓ PostgreSQL backup completed"
    pg_size=$(du -h postgres.dump | cut -f1)
    log "  Size: $pg_size"
else
    log "✗ PostgreSQL backup failed!"
    send_notification "ANTE ERP Backup Failed" "PostgreSQL backup failed"
    exit 1
fi

# 2. Backup MongoDB
log "Backing up MongoDB database..."
docker compose -f "$COMPOSE_FILE" exec -T mongodb mongodump \
    --username=ante \
    --password="$MONGO_PASSWORD" \
    --authenticationDatabase=admin \
    --db=ante \
    --archive=mongodb.archive \
    --gzip

docker cp ante-mongodb:/mongodb.archive ./mongodb.archive 2>/dev/null

if [ -f mongodb.archive ]; then
    log "✓ MongoDB backup completed"
    mongo_size=$(du -h mongodb.archive | cut -f1)
    log "  Size: $mongo_size"
else
    log "✗ MongoDB backup failed!"
fi

# 3. Backup Redis (if persistence enabled)
log "Backing up Redis data..."
docker compose -f "$COMPOSE_FILE" exec redis redis-cli \
    -a "$REDIS_PASSWORD" BGSAVE >/dev/null 2>&1
sleep 5
docker cp ante-redis:/data/dump.rdb ./redis.rdb 2>/dev/null

if [ -f redis.rdb ]; then
    log "✓ Redis backup completed"
else
    log "⚠ Redis backup skipped (no persistence)"
fi

# 4. Backup uploaded files
log "Backing up uploaded files..."
docker cp ante-backend:/app/uploads ./uploads 2>/dev/null

if [ -d uploads ]; then
    upload_size=$(du -sh uploads | cut -f1)
    log "✓ Uploads backup completed"
    log "  Size: $upload_size"
else
    log "⚠ No uploads to backup"
fi

# 5. Backup configuration files
log "Backing up configuration files..."
cp ~/ante-erp/docker-compose.yml ./docker-compose.yml
cp ~/ante-erp/.env ./env.backup

if [ -f docker-compose.yml ]; then
    log "✓ Configuration backup completed"
fi

# 6. Create compressed archive
log "Creating compressed archive..."
cd "$BACKUP_DIR" || exit 1
tar -czf "ante-erp-backup-${DATE}.tar.gz" "$DATE"

if [ $? -eq 0 ]; then
    backup_size=$(du -h "ante-erp-backup-${DATE}.tar.gz" | cut -f1)
    log "✓ Compressed archive created"
    log "  File: ante-erp-backup-${DATE}.tar.gz"
    log "  Size: $backup_size"
    
    # Remove uncompressed directory
    rm -rf "$DATE"
else
    log "✗ Failed to create compressed archive"
    exit 1
fi

# 7. Clean up old backups
log "Cleaning up old backups (retention: $RETENTION_DAYS days)..."
find "$BACKUP_DIR" -name "ante-erp-backup-*.tar.gz" -mtime +$RETENTION_DAYS -delete
old_count=$(find "$BACKUP_DIR" -name "ante-erp-backup-*.tar.gz" -mtime +$RETENTION_DAYS | wc -l)
log "✓ Removed $old_count old backups"

# 8. Summary
log "========================================="
log "Backup completed successfully!"
log "Location: $BACKUP_DIR/ante-erp-backup-${DATE}.tar.gz"
log "========================================="

# Send success notification
send_notification "ANTE ERP Backup Success" "Backup completed successfully at $(date)"

exit 0

Make it executable:

bash
chmod +x ~/ante-erp/scripts/backup-all.sh

Schedule Automated Backups

bash
# Edit crontab
crontab -e

# Add these entries:

# Daily backup at 2 AM
0 2 * * * ~/ante-erp/scripts/backup-all.sh

# Weekly full system check (Sunday 3 AM)
0 3 * * 0 ~/ante-erp/scripts/maintenance.sh

# Monthly backup report (1st of month, 4 AM)
0 4 1 * * ~/ante-erp/scripts/backup-report.sh

Restore from Backup

~/ante-erp/scripts/restore-backup.sh:

bash
#!/bin/bash

if [ -z "$1" ]; then
    echo "Usage: $0 <backup-file.tar.gz>"
    echo "Available backups:"
    ls -lh ~/ante-erp/backups/ante-erp-backup-*.tar.gz
    exit 1
fi

BACKUP_FILE=$1
RESTORE_DIR=~/ante-erp/restore_temp

echo "⚠️  WARNING: This will restore from backup and may overwrite current data!"
read -p "Are you sure you want to continue? (yes/no): " confirm

if [ "$confirm" != "yes" ]; then
    echo "Restore cancelled."
    exit 0
fi

echo "Stopping services..."
docker compose -f ~/ante-erp/docker-compose.yml stop backend frontend

echo "Extracting backup..."
mkdir -p "$RESTORE_DIR"
tar -xzf "$BACKUP_FILE" -C "$RESTORE_DIR"

BACKUP_DIR=$(ls -d "$RESTORE_DIR"/*/ | head -1)

echo "Restoring PostgreSQL..."
docker compose -f ~/ante-erp/docker-compose.yml exec -T postgres \
    pg_restore -U ante -d ante_db --clean --if-exists < "$BACKUP_DIR/postgres.dump"

echo "Restoring MongoDB..."
if [ -f "$BACKUP_DIR/mongodb.archive" ]; then
    docker cp "$BACKUP_DIR/mongodb.archive" ante-mongodb:/tmp/
    docker compose -f ~/ante-erp/docker-compose.yml exec mongodb \
        mongorestore --username=ante --password="$MONGO_PASSWORD" \
        --authenticationDatabase=admin --archive=/tmp/mongodb.archive --gzip
fi

echo "Restoring uploads..."
if [ -d "$BACKUP_DIR/uploads" ]; then
    docker cp "$BACKUP_DIR/uploads" ante-backend:/app/
fi

echo "Starting services..."
docker compose -f ~/ante-erp/docker-compose.yml start backend frontend

echo "Cleaning up..."
rm -rf "$RESTORE_DIR"

echo "✓ Restore completed!"

Make it executable:

bash
chmod +x ~/ante-erp/scripts/restore-backup.sh

Updating ANTE ERP

Update Process

  1. Backup First (Always!)
  2. Pull Latest Images
  3. Stop Services
  4. Start with New Images
  5. Run Migrations
  6. Verify

Update Script

~/ante-erp/scripts/update.sh:

bash
#!/bin/bash

echo "========================================="
echo "ANTE ERP Update Script"
echo "========================================="

cd ~/ante-erp

# 1. Create backup
echo "Step 1/6: Creating backup..."
./scripts/backup-all.sh
if [ $? -ne 0 ]; then
    echo "✗ Backup failed! Aborting update."
    exit 1
fi

# 2. Pull latest images
echo "Step 2/6: Pulling latest Docker images..."
docker compose pull

# 3. Stop services
echo "Step 3/6: Stopping services..."
docker compose down

# 4. Start with new images
echo "Step 4/6: Starting services with new images..."
docker compose up -d

# 5. Wait for services to be healthy
echo "Step 5/6: Waiting for services to be ready..."
sleep 30

# Check backend health
for i in {1..30}; do
    if curl -f http://localhost:3001/health >/dev/null 2>&1; then
        echo "✓ Backend is healthy"
        break
    fi
    if [ $i -eq 30 ]; then
        echo "✗ Backend did not become healthy. Check logs: docker compose logs backend"
        exit 1
    fi
    sleep 2
done

# 6. Verify
echo "Step 6/6: Verifying installation..."
docker compose ps

echo "========================================="
echo "✓ Update completed successfully!"
echo "========================================="
echo "Frontend: http://localhost:8080"
echo "Backend: http://localhost:3001"
echo ""
echo "Check logs: docker compose logs -f"

Make it executable:

bash
chmod +x ~/ante-erp/scripts/update.sh

Manual Update

bash
# Navigate to installation directory
cd ~/ante-erp

# Create backup
./scripts/backup-all.sh

# Pull latest images
docker compose pull

# Recreate containers
docker compose up -d --force-recreate

# Check status
docker compose ps

# View logs
docker compose logs -f backend

System Monitoring

Health Check Script

~/ante-erp/scripts/health-check.sh:

bash
#!/bin/bash

echo "ANTE ERP Health Check - $(date)"
echo "========================================="

# Check services
echo -e "\n1. Service Status:"
docker compose -f ~/ante-erp/docker-compose.yml ps

# Check disk space
echo -e "\n2. Disk Space:"
df -h | grep -E "Filesystem|/dev/"

# Check memory
echo -e "\n3. Memory Usage:"
free -h

# Check database connections
echo -e "\n4. PostgreSQL Connections:"
docker compose -f ~/ante-erp/docker-compose.yml exec -T postgres \
    psql -U ante -d ante_db -c "SELECT count(*) as connections FROM pg_stat_activity;" 2>/dev/null || echo "Failed to connect"

# Check backend health
echo -e "\n5. Backend API Health:"
curl -s http://localhost:3001/health | jq . 2>/dev/null || echo "Backend not responding"

# Check frontend
echo -e "\n6. Frontend Status:"
curl -I http://localhost:8080 2>/dev/null | head -1 || echo "Frontend not responding"

# Check logs for errors
echo -e "\n7. Recent Errors (last 10):"
docker compose -f ~/ante-erp/docker-compose.yml logs --tail=100 backend 2>/dev/null | \
    grep -i error | tail -10 || echo "No recent errors"

echo -e "\n========================================="

Monitoring with Prometheus & Grafana (Optional)

Add to docker-compose.yml:

yaml
services:
  prometheus:
    image: prom/prometheus:latest
    container_name: ante-prometheus
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"
    networks:
      - ante-network

  grafana:
    image: grafana/grafana:latest
    container_name: ante-grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
    networks:
      - ante-network

volumes:
  prometheus_data:
  grafana_data:

Log Management

View Logs

bash
# All services
docker compose logs

# Specific service
docker compose logs backend
docker compose logs frontend

# Follow logs (live)
docker compose logs -f backend

# Last N lines
docker compose logs --tail=100 backend

# Logs since timestamp
docker compose logs --since="2025-10-27T10:00:00" backend

# Search logs
docker compose logs backend | grep ERROR

Log Rotation

Docker handles log rotation automatically with the configuration in docker-compose.yml:

yaml
services:
  backend:
    logging:
      driver: "json-file"
      options:
        max-size: "50m"  # Maximum size per log file
        max-file: "5"    # Keep 5 files (total 250MB)

Export Logs

bash
# Export to file
docker compose logs > logs_$(date +%Y%m%d).txt

# Export specific timeframe
docker compose logs --since="2025-10-27" --until="2025-10-28" > logs_oct27.txt

Performance Monitoring

Resource Usage

bash
# Current usage
docker stats

# Specific container
docker stats ante-backend

# Non-streaming (one-time)
docker stats --no-stream

Database Performance

bash
# PostgreSQL stats
docker compose exec postgres psql -U ante -d ante_db -c "
    SELECT schemaname, tablename,
        pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size,
        pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) AS table_size,
        pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename) - 
                       pg_relation_size(schemaname||'.'||tablename)) AS index_size
    FROM pg_tables
    WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
    ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
"

# Redis memory
docker compose exec redis redis-cli -a "$REDIS_PASSWORD" INFO memory

# MongoDB stats
docker compose exec mongodb mongosh --username ante --password "$MONGO_PASSWORD" \
    --authenticationDatabase admin --eval "db.stats()"

Disk Space Management

Check Space Usage

bash
# Host system
df -h

# Docker disk usage
docker system df

# Detailed view
docker system df -v

Clean Up

bash
# Remove unused images
docker image prune -a

# Remove unused volumes (⚠️ careful!)
docker volume prune

# Remove everything unused
docker system prune -a --volumes

# Clean up logs
find ~/ante-erp/logs -name "*.log" -mtime +30 -delete

Database Maintenance

Create ~/ante-erp/scripts/db-maintenance.sh:

bash
#!/bin/bash

echo "Starting database maintenance..."

# PostgreSQL
echo "Optimizing PostgreSQL..."
docker compose -f ~/ante-erp/docker-compose.yml exec -T postgres psql -U ante -d ante_db <<EOF
    ANALYZE;
    VACUUM;
    REINDEX DATABASE ante_db;
EOF

# Redis
echo "Optimizing Redis..."
docker compose -f ~/ante-erp/docker-compose.yml exec redis \
    redis-cli -a "$REDIS_PASSWORD" BGREWRITEAOF

echo "Database maintenance completed!"

Schedule weekly:

bash
0 3 * * 0 ~/ante-erp/scripts/db-maintenance.sh >> ~/ante-erp/logs/maintenance.log 2>&1

Troubleshooting Common Issues

High Memory Usage

bash
# Check which container is using memory
docker stats --no-stream

# Restart heavy containers
docker compose restart backend

# Adjust memory limits in docker-compose.yml

Disk Full

bash
# Clean up Docker
docker system prune -a

# Remove old backups
find ~/ante-erp/backups -name "*.tar.gz" -mtime +90 -delete

# Clean logs
docker compose logs > /dev/null

Slow Performance

  1. Check database indexes
  2. Optimize queries
  3. Increase resources
  4. Enable Redis caching
  5. Check disk I/O

See Troubleshooting Guide for more.

Maintenance Checklist

Daily

  • [ ] Check service status
  • [ ] Verify backups completed
  • [ ] Review error logs
  • [ ] Check disk space

Weekly

  • [ ] Update Docker images
  • [ ] Run database maintenance
  • [ ] Review performance metrics
  • [ ] Clean up old logs

Monthly

  • [ ] Test backup restore
  • [ ] Review user access
  • [ ] Check security updates
  • [ ] Audit system logs
  • [ ] Performance review
  • [ ] Check SSL certificate status (ante ssl status)

Quarterly

  • [ ] Security audit
  • [ ] Capacity planning
  • [ ] Disaster recovery test
  • [ ] Documentation update
  • [ ] Verify SSL auto-renewal is working (systemctl status certbot.timer)

Next Steps


Last Updated: October 27, 2025

Released under the MIT License.