Skip to content

Latest commit

 

History

History
423 lines (310 loc) · 11.8 KB

File metadata and controls

423 lines (310 loc) · 11.8 KB

Docker Deployment Guide for Open LPR

This guide provides comprehensive instructions for deploying the Open LPR application using Docker and Docker Compose.

Overview

The Docker deployment includes:

  • Multi-stage optimized Dockerfile for production
  • Volume persistence for SQLite database and media files
  • Environment variable configuration
  • Health checks and monitoring
  • Gunicorn WSGI server for production performance (included in requirements.txt)
  • Multiple deployment options for different use cases

Prerequisites

  • Docker 20.10+ installed
  • Docker Compose 2.0+ installed
  • Sufficient disk space for media files and database
  • For LlamaCpp deployments: HuggingFace token for model download
  • For standard deployment: Qwen3-VL API access (API key and endpoint)

Deployment Options

This project provides multiple Docker Compose files for different deployment scenarios:

1. LlamaCpp with AMD GPU (Recommended for Production)

For users with AMD GPUs that support Vulkan:

# Clone the repository
git clone https://github.com/faisalthaheem/open-lpr.git
cd open-lpr

# Create environment file from template
cp .env.llamacpp.example .env.llamacpp

# Edit the environment file with your settings
nano .env.llamacpp

# Create necessary directories
mkdir -p model_files model_files_cache container-data container-media staticfiles

# Start the application with AMD Vulkan GPU support
docker-compose -f docker-compose-llamacpp-amd-vulcan.yml up -d

# Check the logs to ensure everything is running correctly
docker-compose -f docker-compose-llamacpp-amd-vulcan.yml logs -f

Prerequisites:

  • AMD GPU with Vulkan support
  • ROCm drivers installed
  • Sufficient GPU memory (8GB+ recommended)
  • HuggingFace token for model download

2. LlamaCpp with CPU (Universal Compatibility)

For users without compatible GPUs or for testing purposes:

# Clone the repository
git clone https://github.com/faisalthaheem/open-lpr.git
cd open-lpr

# Create environment file from template
cp .env.llamacpp.example .env.llamacpp

# Edit the environment file with your settings
nano .env.llamacpp

# Create necessary directories
mkdir -p model_files model_files_cache container-data container-media staticfiles

# Start the application with CPU support
docker-compose -f docker-compose-llamacpp-cpu.yml up -d

# Check the logs to ensure everything is running correctly
docker-compose -f docker-compose-llamacpp-cpu.yml logs -f

Prerequisites:

  • Sufficient RAM (16GB+ recommended)
  • Multi-core CPU for better performance
  • HuggingFace token for model download

3. Standard Docker with External API

For users who want to use an external OpenAI-compatible API endpoint:

# Clone the repository
git clone https://github.com/faisalthaheem/open-lpr.git
cd open-lpr

# Create environment file from template
cp .env.example .env

# Edit the environment file with your API settings
nano .env

# Create necessary directories
mkdir -p container-data container-media staticfiles

# Start the application
docker-compose up -d

# Check the logs to ensure everything is running correctly
docker-compose logs -f

Prerequisites:

  • Access to an OpenAI-compatible API endpoint
  • Valid API credentials

Access the Application

Regardless of the deployment option, the application will be available at:

For LlamaCpp deployments, the inference server is available at:

Volume Structure

The Docker setup uses the following volume mounts:

Standard Deployment

./container-data/ → /app/data/          (SQLite database)
./container-media/→ /app/media/         (Uploaded and processed images)
./staticfiles/   → /app/staticfiles/   (Collected static files)

LlamaCpp Deployments

./container-data/ → /app/data/          (SQLite database)
./container-media/→ /app/media/         (Uploaded and processed images)
./staticfiles/   → /app/staticfiles/   (Collected static files)
./model_files/   → /models/             (Downloaded GGUF models)
./model_files_cache/ → /root/.cache/   (HuggingFace cache)

Database Persistence

The SQLite database location is controlled by the DATABASE_PATH environment variable:

  • Default (Development): ./data/db.sqlite3 (project root/data/)
  • Docker: /app/data/db.sqlite3 (mounted to host ./container-data/)

This approach ensures:

  • Database persistence across container restarts
  • Easy backup and migration
  • Direct access to the database file for maintenance
  • Proper volume mounting for containerized deployment
  • No permission issues in development environment

Environment Configuration

The application automatically detects the environment and configures paths accordingly:

Development Environment (default):

  • Database: ./data/db.sqlite3
  • Logs: ./data/django.log
  • Media: ./media/
  • Static files: Automatically created in lpr_app/static/ if missing

Docker Environment:

  • Database: /app/data/db.sqlite3 (mounted to host ./container-data/)
  • Logs: /app/data/django.log (mounted to host ./container-data/)
  • Media: /app/media/ (mounted to host ./container-media/)

Media Files Persistence

All uploaded and processed images are stored in ./container-media/ on the host:

  • Original images: ./container-media/uploads/
  • Processed images: ./container-media/processed/

Production Deployment

1. Security Considerations

For production deployment:

  1. Change default secrets:

    SECRET_KEY=generate-a-strong-random-key
    DJANGO_SUPERUSER_PASSWORD=use-a-strong-password
  2. Set DEBUG to False:

    DEBUG=False
  3. Configure ALLOWED_HOSTS:

    ALLOWED_HOSTS=your-domain.com,www.your-domain.com
  4. Use HTTPS in production (configure reverse proxy like Nginx)

2. Performance Optimization

The Dockerfile is optimized for production with:

  • Multi-stage build for smaller image size
  • Non-root user for security
  • Gunicorn WSGI server with 3 workers
  • 120-second timeout for image processing

3. Scaling

For higher traffic, you can scale the application:

# Scale to 3 instances
docker-compose up -d --scale lpr-app=3

Note: When scaling, consider:

  • Using a shared database (PostgreSQL instead of SQLite)
  • Shared storage for media files (NFS, S3, etc.)
  • Load balancer for distributing traffic

Docker Commands Reference

Building and Running

# Build the image
docker build -t open-lpr:latest .

# Run with volume mounts
docker run -d \
  --name open-lpr \
  -p 8000:8000 \
  -v $(pwd)/container-data:/app/data \
  -v $(pwd)/container-media:/app/media \
  --env-file .env \
  open-lpr:latest

Maintenance

# View logs
docker-compose logs -f lpr-app

# Execute commands in container
docker-compose exec lpr-app bash

# Create Django superuser manually
docker-compose exec lpr-app python manage.py createsuperuser

# Run migrations
docker-compose exec lpr-app python manage.py migrate

# Collect static files
docker-compose exec lpr-app python manage.py collectstatic --noinput

Backup and Restore

# Backup database
docker-compose exec lpr-app cp /app/data/db.sqlite3 /app/data/db.sqlite3.backup

# Restore database
docker-compose exec lpr-app cp /app/data/db.sqlite3.backup /app/data/db.sqlite3

# Backup media files
tar -czf container-media-backup-$(date +%Y%m%d).tar.gz container-media/

Troubleshooting

Common Issues

  1. Container fails to start:

    # Check logs
    docker-compose logs lpr-app
    
    # Check configuration
    docker-compose config
  2. Database errors:

    # Check database permissions
    ls -la container-data/
    
    # Run migrations manually
    docker-compose exec lpr-app python manage.py migrate
  3. Permission issues:

    # Fix volume permissions
    sudo chown -R $USER:$USER container-data/ container-media/
  4. API connection issues:

    • Verify QWEN_API_KEY in .env file
    • Check QWEN_BASE_URL accessibility
    • Review application logs for API errors

Health Checks

The container includes health checks:

# Check health status
docker-compose ps

# Manual health check
curl http://localhost:8000/health/

Environment Variables Reference

Standard Deployment (.env file)

Variable Default Description
SECRET_KEY django-insecure-change-me Django secret key
DEBUG False Django debug mode
ALLOWED_HOSTS localhost,127.0.0.1 Allowed hosts for Django
QWEN_API_KEY - Qwen3-VL API key (required)
QWEN_BASE_URL https://ollama.computedsynergy.com/v1 API endpoint URL
QWEN_MODEL qwen3-vl-4b-instruct AI model name
UPLOAD_FILE_MAX_SIZE 10485760 Maximum upload size (10MB)
MAX_BATCH_SIZE 10 Maximum batch processing size
DJANGO_SUPERUSER_USERNAME - Auto-create superuser username
DJANGO_SUPERUSER_EMAIL - Auto-create superuser email
DJANGO_SUPERUSER_PASSWORD - Auto-create superuser password

LlamaCpp Deployment (.env.llamacpp file)

Variable Default Description
HF_TOKEN - HuggingFace token for model download (required)
MODEL_REPO unsloth/Qwen3-VL-4B-Instruct-GGUF HuggingFace model repository
MODEL_FILE Qwen3-VL-4B-Instruct-Q5_K_M.gguf Model file name
MMPROJ_URL https://huggingface.co/unsloth/Qwen3-VL-4B-Instruct-GGUF/resolve/main/mmproj-BF16.gguf Multimodal project file URL
SECRET_KEY django-insecure-change-me Django secret key
DEBUG False Django debug mode
ALLOWED_HOSTS localhost,127.0.0.1,0.0.0.0 Allowed hosts for Django
UPLOAD_FILE_MAX_SIZE 10485760 Maximum upload size (10MB)
MAX_BATCH_SIZE 10 Maximum batch processing size
DATABASE_PATH /app/data/db.sqlite3 Database path in container
DJANGO_SUPERUSER_USERNAME - Auto-create superuser username
DJANGO_SUPERUSER_EMAIL - Auto-create superuser email
DJANGO_SUPERUSER_PASSWORD - Auto-create superuser password

Advanced Configuration

Custom Gunicorn Settings

To customize Gunicorn settings, modify the command in docker-compose.yml:

command: ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "--worker-class", "gevent", "--timeout", "180", "lpr_project.wsgi:application"]

Using External Database

For production, consider using PostgreSQL:

  1. Add PostgreSQL service to docker-compose.yml
  2. Update DATABASE_URL environment variable
  3. Install psycopg2 in requirements.txt

Reverse Proxy Configuration

For production deployment with Nginx:

server {
    listen 80;
    server_name your-domain.com;
    
    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
    location /static/ {
        alias /path/to/staticfiles/;
    }
    
    location /media/ {
        alias /path/to/media/;
    }
}

Additional Resources

For specialized deployment scenarios:

Support

For issues related to:

  • Docker deployment: Check this guide and Docker documentation
  • Application functionality: Review the main README.md
  • API issues: Check API_DOCUMENTATION.md

For additional help, create an issue in the project repository with:

  • Docker version
  • Docker Compose version
  • Complete error logs
  • Environment configuration (without sensitive data)