Docker Deployment Guide
This guide provides end-to-end instructions for deploying Scannersky using the containerized Docker Compose stack.
Docker Stack Architecture
The Docker deployment containerizes the full application stack into decoupled services:
| Service | Container Image | Port / Network | Purpose |
|---|---|---|---|
| django | scannersky-django-django:latest | 8000 (Internal) | Gunicorn WSGI app server running Django |
| postgres | postgres:16 | 5432 (Internal) | PostgreSQL database with persistent volume postgres_data |
| minio | minio/minio:latest | 9000 & 9001 (Internal) | Object storage for media uploads and static assets |
| nginx | nginx:1.27-alpine | 80 & 443 (Public) | Reverse proxy, static/media asset router, SSL termination |
| mcp | scannersky-django-mcp:latest | 8000 (Internal) | Model Context Protocol HTTP server for AI assistant tools |
Complete Start-to-End Docker Deployment
1. Host Prerequisites
Install Docker Engine 24+ and Docker Compose v2 on the host (Ubuntu/Debian):
sudo apt-get update && sudo apt-get install -y docker.io docker-compose-v2 git curl
sudo usermod -aG docker $USER
newgrp docker
2. Repository Setup
Private Repository Authentication: Since the repository is private, ensure your server is configured with an SSH Deploy Key or Personal Access Token before cloning. Refer to the dedicated Git Authentication Guide for complete setup options.
# Clone directly using SSH URL (recommended)
git clone -b docker/compose-migration git@github.com:codexcancerion/scannersky-django.git ~/scannersky-django
cd ~/scannersky-django
3. Environment Configuration (.env)
Run the automated environment initializer script to generate .env, populate secure random secret keys and passwords, and open the file in your terminal editor (nano / vi) for review:
bash ./deploy/scripts/setup-env.sh
What setup-env.sh does automatically:
- Copies
.env.exampleto.envif.envdoes not already exist. - Generates cryptographically secure random values for
DJANGO_SECRET_KEY,DB_PASSWORD, andMINIO_ROOT_PASSWORD. - Automatically opens
.envinnano(orvi) so you can review or adjustDJANGO_ALLOWED_HOSTSand database names.
4. Stack Build & Launch
Build the Docker images and start the stack:
docker compose up -d --build
[!NOTE] The
djangocontainer may temporarily show asunhealthy(with HTTP503indocker logs) after Step 4. This is expected because the required MinIO storage buckets have not been initialized yet. Proceed directly to Step 5 to provision the buckets, after which Django's health check will automatically turn healthy (200 OK).
5. MinIO Bucket Initialization & Container Startup
Provision MinIO buckets (scannersky-media and scannersky-static) and re-run docker compose up -d to start dependent containers (nginx and mcp) that were waiting for django health check:
bash ./deploy/scripts/setup-minio.sh
docker compose up -d
[!TIP] Running
docker compose up -dright aftersetup-minio.shstartsnginxandmcpnow thatdjangois healthy. This binds Nginx to Ports 80 & 443 so the web interface becomes immediately accessible.
6. Documentation Build, Migrations & Static Collection
Build the Docusaurus static documentation and run in-container database migrations & static asset collection:
# Build Docusaurus static documentation for Nginx /docs/ endpoint
cd docusaurus && npm install && npm run build
# Run in-container database migrations and static asset collection
docker compose exec -T django python manage.py migrate --noinput
docker compose exec -T django python manage.py collectstatic --noinput
7. Data & Media Restoration (Optional / Migration)
If restoring database records or media files from a previous system installation, execute the unified restoration entrypoint:
# Run interactive restoration
# Defaults to ~/db_backups and ~/media_backups
# Ensure contents inside ~/db_backups and ~/media_backups before running the script
bash ./deploy/scripts/restore-docker.sh --all
Complete Backup & Restore Guide
For complete instructions on single-instance media backups, interactive database selection menus, and custom path overrides (DUMP_FILEandMEDIA_DIR), please refer to the dedicated Backup and Restore Guide.
8. HTTPS / Let's Encrypt Setup (Optional / Production Domains)
For domain deployments, ensure 40-ssl-check.sh has executable permissions and initialize Let's Encrypt SSL certificates:
# Ensure Nginx dynamic SSL check entrypoint is executable
chmod +x ./deploy/nginx/40-ssl-check.sh
# Provision SSL certificate and activate HTTPS on Port 443
bash ./deploy/scripts/init-letsencrypt.sh scan.kcp.edu.ph admin@kcp.edu.ph
How it works:
- Nginx serves HTTP on port 80 initially and handles the Let's Encrypt ACME challenge at
/.well-known/acme-challenge/. init-letsencrypt.shobtains certificates and places them in/etc/letsencrypt/live/<domain>/.deploy/nginx/40-ssl-check.shdetects the certificates upon Nginx container restart and automatically enables HTTPS termination on port 443!
9. Production Health Validation
Execute the production validation suite:
bash ./deploy/scripts/validate-production.sh
Dynamic SSL vs. HTTP-Only Mode
The Nginx container dynamically adapts based on SSL certificate presence:
- HTTP-Only (Test/IP Deployment): If
/etc/letsencrypt/live/scan.kcp.edu.ph/fullchain.pemis absent, Nginx serves HTTP on port 80 for any domain or IP without crashing. - HTTPS Mode: When SSL certificates exist,
deploy/nginx/40-ssl-check.shautomatically enables SSL termination on port 443.
Routine Production Updates
To pull the latest code and update the container stack:
./deploy/scripts/update.sh
This script pulls latest git commits, rebuilds containers, applies migrations/collectstatic, reloads Nginx, and executes validate-production.sh.
Deployment Scripts Reference
deploy/scripts/setup-env.sh— Automated.envinitializer & secret generator (opens editor automatically)deploy/scripts/update.sh— Automated routine stack updatedeploy/scripts/validate-production.sh— Post-cutover validation suitedeploy/scripts/backup-docker.sh— PostgreSQL container database backupdeploy/scripts/restore-docker.sh— Unified database & media restore entrypoint (supports--all,--db-only,--media-only)deploy/scripts/restore-media.sh— Media backup importer to MinIO bucket (supports customMEDIA_DIR)deploy/scripts/setup-minio.sh— MinIO bucket provisioner