# IGNY8 Infrastructure & Deployment Documentation **Version:** 1.0 **Last Updated:** 2025-01-XX **Purpose:** Complete infrastructure and deployment documentation covering Docker setup, containers, networks, volumes, ports, environment configuration, and deployment procedures. --- ## Table of Contents 1. [Infrastructure Overview](#infrastructure-overview) 2. [Docker Architecture](#docker-architecture) 3. [Infrastructure Stack (igny8-infra)](#infrastructure-stack-igny8-infra) 4. [Application Stack (igny8-app)](#application-stack-igny8-app) 5. [Network Configuration](#network-configuration) 6. [Volume Management](#volume-management) 7. [Port Allocation](#port-allocation) 8. [Environment Variables](#environment-variables) 9. [Docker Images](#docker-images) 10. [Deployment Procedures](#deployment-procedures) 11. [Backup & Restore](#backup--restore) 12. [Monitoring & Health Checks](#monitoring--health-checks) 13. [Troubleshooting](#troubleshooting) --- ## Infrastructure Overview The IGNY8 platform runs on a Docker-based infrastructure with two main stacks: 1. **Infrastructure Stack (`igny8-infra`)**: Shared services used by all applications 2. **Application Stack (`igny8-app`)**: IGNY8-specific application services All containers run on a single Docker network (`igny8_net`) for inter-container communication. ### Infrastructure Components **Infrastructure Stack Services**: - PostgreSQL 15 (Database) - Redis 7 (Cache & Celery Broker) - pgAdmin 4 (Database Administration) - FileBrowser (File Management) - Caddy (Reverse Proxy & HTTPS) - setup-helper (Utility Container) **Application Stack Services**: - igny8_backend (Django Backend with Gunicorn) - igny8_frontend (React Frontend with Vite) - igny8_celery_worker (Celery Worker) - igny8_celery_beat (Celery Beat Scheduler) **External Services**: - Portainer (Container Management - runs separately) --- ## Docker Architecture ### Stack Organization **Two-Stack Architecture**: - **Infrastructure Stack**: Shared services (database, cache, reverse proxy) - **Application Stack**: Application-specific services (backend, frontend, workers) **Benefits**: - Separation of concerns - Independent scaling - Shared infrastructure across multiple apps - Easier maintenance and updates ### File Structure ``` /data/app/ ├── docker-compose.yml # Infrastructure stack (igny8-infra) └── igny8/ └── docker-compose.app.yml # Application stack (igny8-app) ``` ### Network Architecture **Single Network**: `igny8_net` (bridge network) **Network Type**: External bridge network (created manually) **All Containers**: Connected to `igny8_net` for inter-container communication --- ## Infrastructure Stack (igny8-infra) **File**: `/data/app/docker-compose.yml` **Stack Name**: `igny8-infra` **Purpose**: Shared infrastructure services used by all applications ### Services #### 1. PostgreSQL Database **Container Name**: `igny8_postgres` **Image**: `postgres:15` **Purpose**: Primary database for all applications **Configuration**: - **User**: `igny8` - **Password**: `igny8pass` - **Database**: `igny8_db` - **Port**: Internal only (no external port mapping) - **Volume**: `pgdata:/var/lib/postgresql/data` **Health Check**: - Command: `pg_isready -U $POSTGRES_USER -d $POSTGRES_DB` - Interval: 20s - Timeout: 5s - Retries: 5 - Start Period: 15s **Network**: `igny8_net` **Labels**: - `com.docker.compose.project=igny8-infra` - `com.docker.compose.service=postgres` #### 2. Redis Cache & Broker **Container Name**: `igny8_redis` **Image**: `redis:7` **Purpose**: - Celery task broker - Celery result backend - Application caching **Configuration**: - **Port**: Internal only (6379, no external mapping) - **Volume**: `redisdata:/data` - **Command**: `redis-server --save 60 1 --loglevel warning` **Health Check**: - Command: `redis-cli ping | grep -q PONG` - Interval: 20s - Timeout: 3s - Retries: 5 **Network**: `igny8_net` **Labels**: - `com.docker.compose.project=igny8-infra` - `com.docker.compose.service=redis` #### 3. pgAdmin **Container Name**: `igny8_pgadmin` **Image**: `dpage/pgadmin4` **Purpose**: PostgreSQL database administration interface **Configuration**: - **Port**: `5050:80` (external:internal) - **Email**: `admin@igny8.com` - **Password**: `admin123` - **Volume**: `pgadmin_data:/var/lib/pgadmin` **Access**: `http://localhost:5050` or `http://:5050` **Network**: `igny8_net` **Labels**: - `com.docker.compose.project=igny8-infra` - `com.docker.compose.service=pgadmin` #### 4. FileBrowser **Container Name**: `igny8_filebrowser` **Image**: `filebrowser/filebrowser:v2.25.0` **Purpose**: Web-based file management interface **Configuration**: - **Port**: `8080:80` (external:internal) - **Timezone**: `Asia/Karachi` - **Volumes**: - `/data:/srv` (read-write) - `/backups:/srv/backups` (read-write) - `filebrowser_db:/database` (database) **Access**: `http://localhost:8080` or `http://:8080` **Network**: `igny8_net` **Labels**: - `com.docker.compose.project=igny8-infra` - `com.docker.compose.service=filebrowser` #### 5. Caddy Reverse Proxy **Container Name**: `igny8_caddy` **Image**: `caddy:latest` **Purpose**: - Reverse proxy for all applications - HTTPS/SSL termination - Request routing **Configuration**: - **Ports**: - `80:80` (HTTP) - `443:443` (HTTPS) - **Volumes**: - `caddy_data:/data` (SSL certificates) - `caddy_config:/config` (configuration) - `/var/lib/docker/volumes/portainer_data/_data/caddy/Caddyfile:/etc/caddy/Caddyfile` (routing config) **Caddyfile Location**: `/var/lib/docker/volumes/portainer_data/_data/caddy/Caddyfile` **Network**: `igny8_net` **Labels**: - `com.docker.compose.project=igny8-infra` - `com.docker.compose.service=caddy` #### 6. Setup Helper **Container Name**: `setup-helper` **Image**: `alpine:3.20` **Purpose**: Utility container for setup and maintenance tasks **Configuration**: - **Command**: `sh -c "sleep infinity"` (keeps container running) - **Volumes**: - `/data/backups:/backups:rw` (backup directory) - `/scripts:/scripts:ro` (utility scripts) **Network**: `igny8_net` **Labels**: - `com.docker.compose.project=igny8-infra` - `com.docker.compose.service=setup-helper` ### Volumes **Infrastructure Stack Volumes**: - `pgdata`: PostgreSQL database data - `redisdata`: Redis data - `pgadmin_data`: pgAdmin configuration - `filebrowser_db`: FileBrowser database - `caddy_data`: Caddy SSL certificates and data - `caddy_config`: Caddy configuration ### Network **Network Name**: `igny8_net` **Type**: External bridge network **Creation**: Must be created manually before starting stacks **Command**: `docker network create igny8_net --driver bridge` --- ## Application Stack (igny8-app) **File**: `/data/app/igny8/docker-compose.app.yml` **Stack Name**: `igny8-app` **Purpose**: IGNY8 application-specific services ### Services #### 1. Backend Service **Container Name**: `igny8_backend` **Image**: `igny8-backend:latest` **Purpose**: Django REST API backend **Configuration**: - **Port**: `8011:8010` (external:internal) - **Working Directory**: `/app` - **Command**: `gunicorn igny8_core.wsgi:application --bind 0.0.0.0:8010 --workers 4 --timeout 120` **Environment Variables**: - `DB_HOST`: `postgres` - `DB_NAME`: `igny8_db` - `DB_USER`: `igny8` - `DB_PASSWORD`: `igny8pass` - `REDIS_HOST`: `redis` - `REDIS_PORT`: `6379` - `USE_SECURE_COOKIES`: `True` - `USE_SECURE_PROXY_HEADER`: `True` - `DEBUG`: `False` - `SECRET_KEY`: (should be set via environment variable in production) **Volumes**: - `/data/app/igny8/backend:/app:rw` (application code) - `/data/app/igny8:/data/app/igny8:ro` (read-only access to project root) - `/var/run/docker.sock:/var/run/docker.sock:ro` (Docker socket for container management) - `/data/app/logs:/app/logs:rw` (application logs) **Health Check**: - Command: `python -c "import urllib.request; urllib.request.urlopen('http://localhost:8010/api/v1/system/status/').read()"` - Interval: 30s - Timeout: 10s - Retries: 3 - Start Period: 40s **Network**: `igny8_net` **Dependencies**: - Requires `postgres` and `redis` from infrastructure stack (external services) **Labels**: - `com.docker.compose.project=igny8-app` - `com.docker.compose.service=igny8_backend` #### 2. Frontend Service **Container Name**: `igny8_frontend` **Image**: `igny8-frontend-dev:latest` **Purpose**: React frontend with Vite dev server **Configuration**: - **Port**: `8021:5173` (external:internal) - **Command**: `npm run dev -- --host 0.0.0.0 --port 5173` **Environment Variables**: - `VITE_BACKEND_URL`: `https://api.igny8.com/api` **Volumes**: - `/data/app/igny8/frontend:/app:rw` (application code) **Dependencies**: - `igny8_backend` (waits for backend to be healthy) **Network**: `igny8_net` **Labels**: - `com.docker.compose.project=igny8-app` - `com.docker.compose.service=igny8_frontend` #### 3. Celery Worker **Container Name**: `igny8_celery_worker` **Image**: `igny8-backend:latest` (same as backend) **Purpose**: Celery worker for asynchronous task processing **Configuration**: - **Working Directory**: `/app` - **Command**: `celery -A igny8_core worker --loglevel=info --concurrency=4` **Environment Variables**: - `DB_HOST`: `postgres` - `DB_NAME`: `igny8_db` - `DB_USER`: `igny8` - `DB_PASSWORD`: `igny8pass` - `REDIS_HOST`: `redis` - `REDIS_PORT`: `6379` - `DEBUG`: `False` **Volumes**: - `/data/app/igny8/backend:/app:rw` (application code) - `/data/app/igny8:/data/app/igny8:ro` (read-only access to project root) - `/data/app/logs:/app/logs:rw` (application logs) **Network**: `igny8_net` **Dependencies**: - Requires `postgres` and `redis` from infrastructure stack (external services) **Labels**: - `com.docker.compose.project=igny8-app` - `com.docker.compose.service=igny8_celery_worker` #### 4. Celery Beat **Container Name**: `igny8_celery_beat` **Image**: `igny8-backend:latest` (same as backend) **Purpose**: Celery beat scheduler for periodic tasks **Configuration**: - **Working Directory**: `/app` - **Command**: `celery -A igny8_core beat --loglevel=info` **Environment Variables**: - `DB_HOST`: `postgres` - `DB_NAME`: `igny8_db` - `DB_USER`: `igny8` - `DB_PASSWORD`: `igny8pass` - `REDIS_HOST`: `redis` - `REDIS_PORT`: `6379` - `DEBUG`: `False` **Volumes**: - `/data/app/igny8/backend:/app:rw` (application code) - `/data/app/igny8:/data/app/igny8:ro` (read-only access to project root) - `/data/app/logs:/app/logs:rw` (application logs) **Network**: `igny8_net` **Dependencies**: - Requires `postgres` and `redis` from infrastructure stack (external services) **Labels**: - `com.docker.compose.project=igny8-app` - `com.docker.compose.service=igny8_celery_beat` ### Network **Network Name**: `igny8_net` **Type**: External (uses network from infrastructure stack) **Configuration**: `external: true` --- ## Network Configuration ### Network Details **Network Name**: `igny8_net` **Type**: Bridge network **Driver**: `bridge` **Scope**: External (shared across stacks) ### Network Creation **Manual Creation Required**: ```bash docker network create igny8_net --driver bridge ``` **Verification**: ```bash docker network inspect igny8_net ``` ### Container IP Addresses **Infrastructure Stack** (172.18.0.x subnet): - `igny8_postgres`: 172.18.0.6 - `igny8_redis`: 172.18.0.2 - `igny8_pgadmin`: 172.18.0.4 - `igny8_filebrowser`: 172.18.0.8 - `igny8_caddy`: 172.18.0.7 - `setup-helper`: 172.18.0.5 **Application Stack** (172.18.0.x subnet): - `igny8_backend`: 172.18.0.3 - `igny8_frontend`: 172.18.0.11 - `igny8_celery_worker`: 172.18.0.9 - `igny8_celery_beat`: 172.18.0.10 **Note**: IP addresses are dynamically assigned by Docker and may vary. ### Inter-Container Communication **Service Discovery**: Containers can communicate using service names as hostnames **Examples**: - Backend → PostgreSQL: `postgres:5432` - Backend → Redis: `redis:6379` - Frontend → Backend: `igny8_backend:8010` (internal) or `https://api.igny8.com/api` (external via Caddy) --- ## Volume Management ### Infrastructure Stack Volumes #### pgdata **Purpose**: PostgreSQL database data **Location**: `/var/lib/docker/volumes/igny8-infra_pgdata/_data` **Backup**: Critical - contains all database data #### redisdata **Purpose**: Redis data persistence **Location**: `/var/lib/docker/volumes/igny8-infra_redisdata/_data` **Backup**: Optional - cache data can be regenerated #### pgadmin_data **Purpose**: pgAdmin configuration and settings **Location**: `/var/lib/docker/volumes/igny8-infra_pgadmin_data/_data` **Backup**: Optional - configuration can be recreated #### filebrowser_db **Purpose**: FileBrowser database **Location**: `/var/lib/docker/volumes/igny8-infra_filebrowser_db/_data` **Backup**: Optional - file browser state #### caddy_data **Purpose**: Caddy SSL certificates and data **Location**: `/var/lib/docker/volumes/igny8-infra_caddy_data/_data` **Backup**: Important - contains SSL certificates #### caddy_config **Purpose**: Caddy configuration **Location**: `/var/lib/docker/volumes/igny8-infra_caddy_config/_data` **Backup**: Important - contains Caddy configuration ### Host Volume Mounts #### Application Code **Path**: `/data/app/igny8/backend:/app:rw` **Purpose**: Backend application code (read-write for development) #### Application Root **Path**: `/data/app/igny8:/data/app/igny8:ro` **Purpose**: Read-only access to project root #### Logs **Path**: `/data/app/logs:/app/logs:rw` **Purpose**: Application logs directory #### Docker Socket **Path**: `/var/run/docker.sock:/var/run/docker.sock:ro` **Purpose**: Read-only access to Docker socket for container management #### FileBrowser Data **Path**: `/data:/srv` (read-write) **Purpose**: FileBrowser access to host filesystem #### FileBrowser Backups **Path**: `/backups:/srv/backups` (read-write) **Purpose**: FileBrowser access to backup directory #### Setup Helper Scripts **Path**: `/scripts:/scripts:ro` **Purpose**: Read-only access to utility scripts #### Setup Helper Backups **Path**: `/data/backups:/backups:rw` **Purpose**: Backup directory access ### Volume Backup **Docker Volumes**: ```bash # Backup all Docker volumes tar -czf docker-volumes-backup-$(date +%Y%m%d).tar.gz \ -C /var/lib/docker volumes/ ``` **Host Mounts**: ```bash # Backup application code tar -czf app-backup-$(date +%Y%m%d).tar.gz -C /data app/ # Backup logs tar -czf logs-backup-$(date +%Y%m%d).tar.gz -C /data logs/ ``` --- ## Port Allocation ### External Ports (Host → Container) **Infrastructure Stack**: - `5050` → pgAdmin (80) - `8080` → FileBrowser (80) - `80` → Caddy (80) - HTTP - `443` → Caddy (443) - HTTPS **Application Stack**: - `8011` → Backend (8010) - `8021` → Frontend (5173) **Portainer** (External): - `8000` → Portainer (8000) - HTTP - `9443` → Portainer (9443) - HTTPS ### Internal Ports (Container → Container) **Standardized Internal Ports**: - Backend: `8010` (Gunicorn) - Frontend Dev: `5173` (Vite dev server) - Frontend Prod: `8020` (Caddy) - PostgreSQL: `5432` - Redis: `6379` - pgAdmin: `80` - FileBrowser: `80` - Caddy: `80` (HTTP), `443` (HTTPS) ### Port Allocation Strategy **Pattern**: - Backend External: `XX11` (e.g., 8011) - Frontend External: `XX21` (e.g., 8021) **IGNY8 Port Range**: `8000-8099` - Backend: `8011` - Frontend: `8021` --- ## Environment Variables ### Backend Environment Variables **Database Configuration**: - `DB_HOST`: PostgreSQL hostname (default: `postgres`) - `DB_NAME`: Database name (default: `igny8_db`) - `DB_USER`: Database user (default: `igny8`) - `DB_PASSWORD`: Database password (default: `igny8pass`) - `DB_PORT`: Database port (default: `5432`) **Redis Configuration**: - `REDIS_HOST`: Redis hostname (default: `redis`) - `REDIS_PORT`: Redis port (default: `6379`) **Django Configuration**: - `SECRET_KEY`: Django secret key (REQUIRED in production) - `DEBUG`: Debug mode (default: `False`) - `ALLOWED_HOSTS`: Comma-separated list of allowed hosts - `DJANGO_SETTINGS_MODULE`: Django settings module (default: `igny8_core.settings`) **Security Settings**: - `USE_SECURE_COOKIES`: Enable secure cookies (default: `True` in production) - `USE_SECURE_PROXY_HEADER`: Enable secure proxy header (default: `True` in production) **JWT Configuration**: - `JWT_SECRET_KEY`: JWT secret key (defaults to `SECRET_KEY`) **Celery Configuration**: - `CELERY_BROKER_URL`: Celery broker URL (default: `redis://redis:6379/0`) - `CELERY_RESULT_BACKEND`: Celery result backend (default: `redis://redis:6379/0`) ### Frontend Environment Variables **API Configuration**: - `VITE_BACKEND_URL`: Backend API URL (default: `https://api.igny8.com/api`) **Build Configuration**: - `VITE_APP_NAME`: Application name ### Infrastructure Environment Variables **PostgreSQL**: - `POSTGRES_USER`: Database user (default: `igny8`) - `POSTGRES_PASSWORD`: Database password (default: `igny8pass`) - `POSTGRES_DB`: Database name (default: `igny8_db`) **pgAdmin**: - `PGADMIN_DEFAULT_EMAIL`: Admin email (default: `admin@igny8.com`) - `PGADMIN_DEFAULT_PASSWORD`: Admin password (default: `admin123`) **FileBrowser**: - `TZ`: Timezone (default: `Asia/Karachi`) --- ## Docker Images ### Image Building **Backend Image**: ```bash cd /data/app/igny8/backend docker build -t igny8-backend:latest -f Dockerfile . ``` **Frontend Dev Image**: ```bash cd /data/app/igny8/frontend docker build -t igny8-frontend-dev:latest -f Dockerfile.dev . ``` **Frontend Production Image**: ```bash cd /data/app/igny8/frontend docker build -t igny8-frontend:latest -f Dockerfile . ``` ### Image Details #### igny8-backend:latest **Base Image**: `python:3.11-slim` **Dependencies**: - System: `gcc`, `libpq-dev`, `curl`, `git` - Python: See `requirements.txt` **Exposed Port**: `8010` **Default Command**: `gunicorn igny8_core.wsgi:application --bind 0.0.0.0:8010` **Build Context**: `/data/app/igny8/backend` #### igny8-frontend-dev:latest **Base Image**: `node:18-alpine` **Dependencies**: See `package.json` **Exposed Port**: `5173` **Default Command**: `npm run dev -- --host 0.0.0.0 --port 5173` **Build Context**: `/data/app/igny8/frontend` #### igny8-frontend:latest **Base Image**: Multi-stage build - Stage 1: `node:18-alpine` (builder) - Stage 2: `caddy:latest` (server) **Exposed Port**: `8020` **Default Command**: `caddy run --config /etc/caddy/Caddyfile` **Build Context**: `/data/app/igny8/frontend` ### External Images **Infrastructure Images**: - `postgres:15` - PostgreSQL database - `redis:7` - Redis cache and broker - `dpage/pgadmin4` - pgAdmin interface - `filebrowser/filebrowser:v2.25.0` - FileBrowser - `caddy:latest` - Caddy reverse proxy - `alpine:3.20` - Setup helper utility **Management Images**: - `portainer/portainer-ce:latest` - Portainer container management --- ## Deployment Procedures ### Initial Setup #### 1. Prerequisites **System Requirements**: - Docker 20.10+ - Docker Compose 2.0+ - Sufficient disk space (minimum 20GB) - Network access for pulling images **Directory Structure**: ```bash /data/app/ ├── docker-compose.yml # Infrastructure stack └── igny8/ ├── docker-compose.app.yml # Application stack ├── backend/ └── frontend/ ``` #### 2. Create Docker Network ```bash docker network create igny8_net --driver bridge ``` #### 3. Build Docker Images **Backend Image**: ```bash cd /data/app/igny8/backend docker build -t igny8-backend:latest -f Dockerfile . ``` **Frontend Dev Image**: ```bash cd /data/app/igny8/frontend docker build -t igny8-frontend-dev:latest -f Dockerfile.dev . ``` #### 4. Start Infrastructure Stack ```bash cd /data/app docker compose -f docker-compose.yml -p igny8-infra up -d ``` **Verify**: ```bash docker ps --filter "label=com.docker.compose.project=igny8-infra" ``` #### 5. Start Application Stack ```bash cd /data/app/igny8 docker compose -f docker-compose.app.yml -p igny8-app up -d ``` **Verify**: ```bash docker ps --filter "label=com.docker.compose.project=igny8-app" ``` ### Database Initialization #### 1. Run Migrations ```bash docker exec -it igny8_backend python manage.py migrate ``` #### 2. Create Superuser ```bash docker exec -it igny8_backend python manage.py createsuperuser ``` #### 3. Load Initial Data (Optional) ```bash docker exec -it igny8_backend python manage.py loaddata initial_data.json ``` ### Caddy Configuration **Caddyfile Location**: `/var/lib/docker/volumes/portainer_data/_data/caddy/Caddyfile` **Configuration**: Managed via Portainer or manually **Example Configuration**: ``` api.igny8.com { reverse_proxy igny8_backend:8010 } app.igny8.com { reverse_proxy igny8_frontend:5173 } ``` **Reload Caddy**: ```bash docker exec igny8_caddy caddy reload --config /etc/caddy/Caddyfile ``` ### Production Deployment #### 1. Set Environment Variables **Create `.env` file or set via docker-compose**: ```bash SECRET_KEY= JWT_SECRET_KEY= DEBUG=False USE_SECURE_COOKIES=True USE_SECURE_PROXY_HEADER=True ``` #### 2. Update Caddyfile Configure domain names and SSL certificates in Caddyfile #### 3. Build Production Images **Backend** (already built): ```bash cd /data/app/igny8/backend docker build -t igny8-backend:latest -f Dockerfile . ``` **Frontend Production**: ```bash cd /data/app/igny8/frontend docker build -t igny8-frontend:latest -f Dockerfile . ``` #### 4. Update docker-compose.app.yml Change frontend image from `igny8-frontend-dev:latest` to `igny8-frontend:latest` #### 5. Restart Stacks ```bash # Restart application stack cd /data/app/igny8 docker compose -f docker-compose.app.yml -p igny8-app restart ``` ### Updates and Maintenance #### Update Application Code **Backend**: ```bash cd /data/app/igny8/backend git pull # or copy new files docker compose -f docker-compose.app.yml -p igny8-app restart igny8_backend ``` **Frontend**: ```bash cd /data/app/igny8/frontend git pull # or copy new files docker compose -f docker-compose.app.yml -p igny8-app restart igny8_frontend ``` #### Rebuild Images **Backend**: ```bash cd /data/app/igny8/backend docker build -t igny8-backend:latest -f Dockerfile . docker compose -f docker-compose.app.yml -p igny8-app up -d --force-recreate igny8_backend igny8_celery_worker igny8_celery_beat ``` **Frontend**: ```bash cd /data/app/igny8/frontend docker build -t igny8-frontend-dev:latest -f Dockerfile.dev . docker compose -f docker-compose.app.yml -p igny8-app up -d --force-recreate igny8_frontend ``` #### Database Migrations ```bash docker exec -it igny8_backend python manage.py migrate ``` #### Collect Static Files ```bash docker exec -it igny8_backend python manage.py collectstatic --noinput ``` --- ## Backup & Restore ### Backup Procedures #### 1. Database Backup **PostgreSQL Dump**: ```bash docker exec igny8_postgres pg_dump -U igny8 igny8_db > backup-$(date +%Y%m%d).sql ``` **With Compression**: ```bash docker exec igny8_postgres pg_dump -U igny8 igny8_db | gzip > backup-$(date +%Y%m%d).sql.gz ``` #### 2. Docker Volumes Backup **All Volumes**: ```bash tar -czf docker-volumes-backup-$(date +%Y%m%d).tar.gz \ -C /var/lib/docker volumes/ ``` **Individual Volumes**: ```bash # PostgreSQL data tar -czf pgdata-backup-$(date +%Y%m%d).tar.gz \ -C /var/lib/docker/volumes/igny8-infra_pgdata/_data . # Redis data tar -czf redisdata-backup-$(date +%Y%m%d).tar.gz \ -C /var/lib/docker/volumes/igny8-infra_redisdata/_data . # Caddy data (SSL certificates) tar -czf caddy-data-backup-$(date +%Y%m%d).tar.gz \ -C /var/lib/docker/volumes/igny8-infra_caddy_data/_data . ``` #### 3. Application Code Backup ```bash tar -czf app-backup-$(date +%Y%m%d).tar.gz -C /data app/ ``` #### 4. Logs Backup ```bash tar -czf logs-backup-$(date +%Y%m%d).tar.gz -C /data logs/ ``` #### 5. Complete System Backup ```bash #!/bin/bash BACKUP_DIR="/backups/complete-backup-$(date +%Y%m%d)" mkdir -p "$BACKUP_DIR" # Database docker exec igny8_postgres pg_dump -U igny8 igny8_db | gzip > "$BACKUP_DIR/database.sql.gz" # Docker volumes tar -czf "$BACKUP_DIR/docker-volumes.tar.gz" -C /var/lib/docker volumes/ # Application code tar -czf "$BACKUP_DIR/app.tar.gz" -C /data app/ # Logs tar -czf "$BACKUP_DIR/logs.tar.gz" -C /data logs/ # Caddyfile cp /var/lib/docker/volumes/portainer_data/_data/caddy/Caddyfile "$BACKUP_DIR/Caddyfile" ``` ### Restore Procedures #### 1. Database Restore **From SQL Dump**: ```bash docker exec -i igny8_postgres psql -U igny8 igny8_db < backup-YYYYMMDD.sql ``` **From Compressed Dump**: ```bash gunzip -c backup-YYYYMMDD.sql.gz | docker exec -i igny8_postgres psql -U igny8 igny8_db ``` #### 2. Docker Volumes Restore **Stop Services**: ```bash docker compose -f docker-compose.app.yml -p igny8-app down docker compose -f docker-compose.yml -p igny8-infra down ``` **Restore Volumes**: ```bash # Extract volume backups tar -xzf docker-volumes-backup-YYYYMMDD.tar.gz -C /var/lib/docker/ # Or restore individual volumes tar -xzf pgdata-backup-YYYYMMDD.tar.gz -C /var/lib/docker/volumes/igny8-infra_pgdata/_data/ ``` **Start Services**: ```bash docker compose -f docker-compose.yml -p igny8-infra up -d docker compose -f docker-compose.app.yml -p igny8-app up -d ``` #### 3. Application Code Restore ```bash tar -xzf app-backup-YYYYMMDD.tar.gz -C /data/ ``` #### 4. Complete System Restore ```bash #!/bin/bash BACKUP_DIR="/backups/complete-backup-YYYYMMDD" # Restore database gunzip -c "$BACKUP_DIR/database.sql.gz" | docker exec -i igny8_postgres psql -U igny8 igny8_db # Restore volumes tar -xzf "$BACKUP_DIR/docker-volumes.tar.gz" -C /var/lib/docker/ # Restore application code tar -xzf "$BACKUP_DIR/app.tar.gz" -C /data/ # Restore Caddyfile cp "$BACKUP_DIR/Caddyfile" /var/lib/docker/volumes/portainer_data/_data/caddy/Caddyfile # Restart services docker compose -f docker-compose.yml -p igny8-infra restart caddy docker compose -f docker-compose.app.yml -p igny8-app restart ``` --- ## Monitoring & Health Checks ### Health Check Endpoints #### Backend Health Check **Endpoint**: `http://localhost:8011/api/v1/system/status/` **Method**: `GET` **Expected Response**: HTTP 200 **Implementation**: Django view that checks database connectivity #### Frontend Health Check **Endpoint**: `http://localhost:8021/` **Method**: `GET` **Expected Response**: HTTP 200 (HTML page) ### Container Health Checks #### PostgreSQL **Check**: `pg_isready -U igny8 -d igny8_db` **Interval**: 20s **Timeout**: 5s **Retries**: 5 #### Redis **Check**: `redis-cli ping | grep -q PONG` **Interval**: 20s **Timeout**: 3s **Retries**: 5 #### Backend **Check**: `python -c "import urllib.request; urllib.request.urlopen('http://localhost:8010/api/v1/system/status/').read()"` **Interval**: 30s **Timeout**: 10s **Retries**: 3 **Start Period**: 40s ### Monitoring Script **File**: `/data/app/igny8/check-status.sh` **Purpose**: Quick status check for all stacks and containers **Usage**: ```bash cd /data/app/igny8 ./check-status.sh ``` **Output**: - Container status for both stacks - Network connectivity - Service health checks (Backend API, Frontend, PostgreSQL, Redis) - All IGNY8 containers list ### Log Monitoring #### View Container Logs **Backend**: ```bash docker logs -f igny8_backend ``` **Frontend**: ```bash docker logs -f igny8_frontend ``` **Celery Worker**: ```bash docker logs -f igny8_celery_worker ``` **Celery Beat**: ```bash docker logs -f igny8_celery_beat ``` **PostgreSQL**: ```bash docker logs -f igny8_postgres ``` **Redis**: ```bash docker logs -f igny8_redis ``` #### Application Logs **Location**: `/data/app/logs/` **Backend Logs**: `/data/app/logs/backend/` **Frontend Logs**: `/data/app/logs/frontend/` --- ## Troubleshooting ### Common Issues #### 1. Network Not Found **Error**: `network igny8_net not found` **Solution**: ```bash docker network create igny8_net --driver bridge ``` #### 2. Database Connection Failed **Error**: `could not connect to server: Connection refused` **Check**: ```bash # Verify PostgreSQL is running docker ps | grep igny8_postgres # Check PostgreSQL logs docker logs igny8_postgres # Test connection docker exec igny8_postgres pg_isready -U igny8 ``` **Solution**: Ensure infrastructure stack is running before application stack #### 3. Redis Connection Failed **Error**: `Error connecting to Redis` **Check**: ```bash # Verify Redis is running docker ps | grep igny8_redis # Check Redis logs docker logs igny8_redis # Test connection docker exec igny8_redis redis-cli ping ``` **Solution**: Ensure infrastructure stack is running before application stack #### 4. Port Already in Use **Error**: `Bind for 0.0.0.0:8011 failed: port is already allocated` **Check**: ```bash # Find process using port sudo lsof -i :8011 # or sudo netstat -tulpn | grep 8011 ``` **Solution**: Stop conflicting service or change port in docker-compose #### 5. Container Health Check Failing **Error**: Container shows as unhealthy **Check**: ```bash # View container health status docker inspect igny8_backend | grep -A 10 Health # View container logs docker logs igny8_backend # Test health check manually docker exec igny8_backend python -c "import urllib.request; urllib.request.urlopen('http://localhost:8010/api/v1/system/status/').read()" ``` **Solution**: Check application logs, verify dependencies are running #### 6. Celery Tasks Not Processing **Check**: ```bash # Verify Celery worker is running docker ps | grep igny8_celery_worker # Check Celery worker logs docker logs igny8_celery_worker # Verify Redis connection docker exec igny8_celery_worker celery -A igny8_core inspect active ``` **Solution**: Restart Celery worker, verify Redis connectivity #### 7. Static Files Not Loading **Error**: 404 for static files **Solution**: ```bash # Collect static files docker exec igny8_backend python manage.py collectstatic --noinput # Restart backend docker compose -f docker-compose.app.yml -p igny8-app restart igny8_backend ``` #### 8. CORS Errors **Error**: CORS policy blocked request **Check**: Verify `CORS_ALLOWED_ORIGINS` in Django settings **Solution**: Add frontend domain to `CORS_ALLOWED_ORIGINS` in `settings.py` ### Debugging Commands #### Container Inspection ```bash # Inspect container configuration docker inspect igny8_backend # View container environment variables docker exec igny8_backend env # View container network configuration docker network inspect igny8_net ``` #### Database Debugging ```bash # Connect to PostgreSQL docker exec -it igny8_postgres psql -U igny8 igny8_db # List databases docker exec igny8_postgres psql -U igny8 -l # Check database size docker exec igny8_postgres psql -U igny8 -c "SELECT pg_size_pretty(pg_database_size('igny8_db'));" ``` #### Redis Debugging ```bash # Connect to Redis CLI docker exec -it igny8_redis redis-cli # Check Redis info docker exec igny8_redis redis-cli INFO # List all keys docker exec igny8_redis redis-cli KEYS '*' ``` #### Application Debugging ```bash # Django shell docker exec -it igny8_backend python manage.py shell # Check Django settings docker exec igny8_backend python manage.py diffsettings # View Django URLs docker exec igny8_backend python manage.py show_urls ``` --- ## Summary The IGNY8 infrastructure is built on: 1. **Two-Stack Architecture**: Infrastructure stack (shared services) and Application stack (app-specific services) 2. **Single Network**: All containers on `igny8_net` bridge network 3. **Docker Compose**: Separate compose files for infrastructure and application 4. **Volume Management**: Docker volumes for persistent data, host mounts for code 5. **Health Checks**: Built-in health checks for critical services 6. **Port Allocation**: Standardized port allocation (8011 backend, 8021 frontend) 7. **Environment Variables**: Configuration via environment variables 8. **Backup & Restore**: Comprehensive backup procedures for database, volumes, and code 9. **Monitoring**: Health checks, logging, and status scripts 10. **Troubleshooting**: Common issues and debugging commands This infrastructure ensures reliability, scalability, and maintainability while providing a solid foundation for the IGNY8 application.