# 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://<server-ip>: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://<server-ip>: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=<generate-secure-key>
JWT_SECRET_KEY=<generate-secure-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.

