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

bash
# Interactive restore (prompts for backup selection)
ante restore

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

# Restore with confirmation
ante restore --interactive

# The CLI will:
# 1. Stop affected services
# 2. Restore all databases
# 3. Restore uploaded files
# 4. Restore configuration
# 5. Restart services
# 6. Verify health

Important: Always test restores monthly to ensure backup integrity.

Automated Backup Scheduling

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

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

Quarterly

  • [ ] Security audit
  • [ ] Capacity planning
  • [ ] Disaster recovery test
  • [ ] Documentation update

Next Steps


Last Updated: October 27, 2025

Released under the MIT License.