infra/@dev-prod-rf.server/design/ARCHITECTURE.md

Architecture: @infra-dev-prod-rf

Document: Infrastructure Architecture Design
Status: PRODUCTION ACTIVE
Last Updated: 2025-11-09
Version: 1.0.0


Overview

Unified Development + Production Platform with Docker containerization serving 7 Docker stacks containing 34 containers across 3 architectural layers.

Server: leruepecie (45.144.177.147)
Region: Production Platform
Uptime: 24/7


Architectural Layers

Layer 1: Infrastructure (pro-0kt-stack)

Purpose: Core infrastructure services for all projects
Containers: 16
Network: pro-0kt-stack_pro-0kt-network
Status: CRITICAL

Core services:
- Nginx Proxy Manager (NPM) - reverse proxy + SSL management
- Homarr - unified dashboard
- Authelia - OAuth authentication
- PostgreSQL Shared - shared database
- MariaDB Shared - shared database
- Redis Shared - caching layer
- Git hosting (Gitea)
- S3 storage (MinIO)
- Docker management (Portainer)
- Database UI (PgAdmin)
- Email testing (Mailhog)
- Workflow automation (N8N)
- Notebook environment (Jupyter)
- Status monitoring (Uptime Kuma)
- Backup server (Restic)

Critical Components:
- NPM is a single point of failure - ALL traffic routes through this
- PostgreSQL Shared and MariaDB Shared provide shared database access

Layer 2: Development (5 stacks)

Purpose: Development and testing environments
Containers: 14
Networks: Isolated per stack
Status: ACTIVE

Stacks:
1. seller1-dev-stack (4 containers)
- Drupal/Varbase development
- Domain: seller1.dev.0kt.ru
- Network: seller1-dev-stack_seller1-dev-network

  1. myshop-stack (3 containers)
    - Drupal Commerce demo
    - Domain: myshop.dev.0kt.ru
    - Network: myshop-stack_myshop-network

  2. commerce-stack (3 containers)
    - Commerce Kickstart demo
    - Domain: commerce.demo.0kt.ru
    - Network: commerce-stack_commerce-network

  3. varbase-stack (3 containers)
    - Varbase distribution demo
    - Domain: varbase.demo.0kt.ru
    - Network: varbase-stack_varbase-network

  4. python-stack (2 containers)
    - Python Flask apps
    - Domains: py.dev.0kt.ru, py.tst.0kt.ru
    - Network: python-stack_python-network

Layer 3: Production (seller1-prod-stack)

Purpose: Production service for seller1.ru
Containers: 4
Network: seller1-prod-stack_seller1-prod-network
Status: CRITICAL 24/7

Criticality: 🔴 CRITICAL PRODUCTION SERVICE

Services:
- seller1-prod-web - Drupal/Varbase (Varbase framework)
- seller1-prod-db - PostgreSQL isolated database
- seller1-prod-redis - Caching layer
- seller1-prod-n8n - Workflow automation

Domains:
- seller1.ru - Main production site (CRITICAL)
- www.seller1.ru - Redirect to seller1.ru
- pro.seller1.ru - Backend N8N (CRITICAL)


Network Architecture

Layer 1: NPM Connectivity

Nginx Proxy Manager (NPM) operates as central reverse proxy:

┌─────────────────────────────────────┐
    Internet (80, 443)                
└──────────────┬──────────────────────┘
               
┌──────────────▼──────────────────────┐
   NPM (pro-0kt-nginx)                
   - All SSL termination              
   - All domain routing               
   - Force SSL redirect               
   - HSTS headers                     
└──────────────┬──────────────────────┘
               
      ┌────────┼────────┬────────────────┬─────────────┐
                                                   
                                                   
  pro-0kt-  seller1- seller1-dev-   varbase-   commerce-
  network   prod-net  network        network    network

NPM Network Connectivity:
NPM container is connected to all 7 Docker networks for traffic routing:

# Connections maintained:
docker network connect pro-0kt-stack_pro-0kt-network pro-0kt-nginx
docker network connect seller1-prod-stack_seller1-prod-network pro-0kt-nginx
docker network connect seller1-dev-stack_seller1-dev-network pro-0kt-nginx
docker network connect myshop-stack_myshop-network pro-0kt-nginx
docker network connect commerce-stack_commerce-network pro-0kt-nginx
docker network connect varbase-stack_varbase-network pro-0kt-nginx
docker network connect python-stack_python-network pro-0kt-nginx

Layer 2: Domain Routing

All domains configured in NPM proxy hosts with:
- Forward Host: container name
- Forward Port: service port
- SSL: Let's Encrypt (auto-renewal)
- HTTP/2: Enabled
- HSTS: Enabled
- Block Exploits: Enabled

Layer 3: Internal Services

Services communication:
- Shared Databases: All stacks can access PostgreSQL/MariaDB on shared network
- Shared Cache: Redis shared instance for all stacks
- Shared Storage: MinIO S3 storage accessible to all


Container Inventory

Infrastructure Layer (16 containers)

Container Service Port(s) Role
pro-0kt-nginx Nginx Proxy Manager 80, 81, 443 Reverse proxy, SSL
pro-0kt-homarr Homarr 7575 Dashboard
pro-0kt-authelia Authelia 9091 OAuth provider
pro-0kt-postgres PostgreSQL 5432 Shared DB
pro-0kt-mariadb MariaDB 3306 Shared DB
pro-0kt-redis Redis 6379 Shared cache
pro-0kt-gitea Gitea 3000, 2222 Git hosting
pro-0kt-minio MinIO 9000, 9001 S3 storage
pro-0kt-portainer Portainer 9002 Docker UI
pro-0kt-pgadmin PgAdmin 5050 PostgreSQL UI
pro-0kt-mailhog Mailhog 1025, 8025 Email testing
pro-0kt-n8n N8N 5678 Workflow automation
pro-0kt-jupyter Jupyter 8888 Notebooks
pro-0kt-uptime Uptime Kuma 3001 Monitoring
pro-0kt-restic Restic N/A Backup server
pro-0kt-adminer Adminer N/A Database UI

Production Layer (4 containers)

Container Service Port(s) Role
seller1-prod-web Drupal/Varbase 80 Web server
seller1-prod-db PostgreSQL 5432 Isolated DB
seller1-prod-redis Redis 6379 Cache
seller1-prod-n8n N8N 5678 Automation

Development Layers (14 containers)

seller1-dev-stack (4)
- seller1-dev-web: Drupal/Varbase
- seller1-dev-db: PostgreSQL
- seller1-dev-redis: Redis
- seller1-dev-n8n: N8N

varbase-stack (3)
- varbase-web: Varbase
- varbase-db: PostgreSQL
- varbase-redis: Redis

commerce-stack (3)
- commerce-web: Drupal Commerce
- commerce-db: MariaDB
- commerce-redis: Redis

myshop-stack (3)
- myshop-web: Drupal Commerce
- myshop-db: MariaDB
- myshop-redis: Redis

python-stack (2)
- python-dev: Flask dev
- python-tst: Flask test


Storage Architecture

Persistent Storage Locations

All container data stored in /mnt/data/ for durability:

/mnt/data/
├── nginx/                    # NPM configuration + SSL certs
├── homarr/                   # Dashboard data
├── authelia/                 # OAuth configuration
├── postgres-shared/          # Shared PostgreSQL data
├── mariadb-shared/           # Shared MariaDB data
├── redis-shared/             # Shared Redis data
├── gitea/                    # Git repository data
├── minio/                    # S3 object storage
├── portainer/                # Docker management data
├── pgadmin/                  # PgAdmin configuration
├── mailhog/                  # Email messages
├── n8n-utils/                # N8N workflows
├── jupyter/                  # Notebooks
├── uptime/                   # Uptime Kuma data
├── restic/                   # Backup repository
├── seller1-dev/              # Development database data
├── myshop/                   # MyShop data
├── commerce/                 # Commerce data
├── varbase/                  # Varbase data
├── python/                   # Python apps data
└── seller1-prod/             # CRITICAL PRODUCTION DATA

Total Storage: ~40GB SSD


Security Architecture

Network Isolation

Each stack runs in isolated Docker network:
- Internal communication only
- No cross-stack network exposure
- NPM acts as security gateway

Firewall (UFW)

Only essential ports open to internet:
- 22 - SSH (management only)
- 80 - HTTP (redirects to 443)
- 443 - HTTPS (all traffic)

Ports closed to internet:
- 81 - NPM Admin (SSH tunnel only)
- 5432 - PostgreSQL (internal only)
- 3306 - MariaDB (internal only)
- 6379 - Redis (internal only)
- Others - internal only

SSL/TLS

Authentication

OAuth for *.0kt.ru domains:
- Provider: Authelia
- 2FA: Available
- Admin: admin

OAuth for seller1.ru:
- Provider: Drupal Simple OAuth
- Endpoint: auth.seller1.ru

fail2ban


Networking Details

Port Mapping

External (Public Internet):
- 80 → HTTP (NPM redirects to 443)
- 443 → HTTPS (all SSL-terminated traffic)
- 22 → SSH (management only)

Internal (Docker Only):
- 5432 → PostgreSQL Shared
- 3306 → MariaDB Shared
- 6379 → Redis Shared
- 3000 → Gitea SSH
- 9000 → MinIO API
- 9001 → MinIO Console
- 9002 → Portainer
- 5678 → N8N
- 8888 → Jupyter
- 5050 → PgAdmin
- 1025, 8025 → Mailhog
- 3001 → Uptime Kuma
- 7575 → Homarr

SSH Tunnel Access (to 91.218.142.168):
- 81 → NPM Admin Panel: ssh -L 81:localhost:81 root@45.144.177.147


Architectural Decision Records (ADR)

ADR-001: Docker Swarm vs Compose

Status: DECIDED - Compose
Date: 2025-10-26

Context:
Need orchestration for 34 containers across 7 independent stacks with mixed requirements (development, utilities, production).

Options Considered:
1. Docker Swarm - multi-node clustering, built-in orchestration
2. Docker Compose - single-node, simpler management, file-based configuration

Decision: Docker Compose

Rationale:
- Single-server deployment (45.144.177.147)
- Simpler operational model - no cluster management overhead
- Each stack independent with own docker-compose.yml
- Easy version control and rollback
- Better for development/production mix
- Easier debugging and logs per stack

Consequences:
- Single point of failure on this server (mitigated by backup strategy)
- Limited horizontal scaling (use DEV-PRO for management)
- Requires careful process management on server restarts


ADR-002: Shared vs Isolated Databases

Status: DECIDED - Hybrid
Date: 2025-10-26

Context:
Multiple stacks need database access. Decision on whether to share databases or isolate them.

Options Considered:
1. All shared - single PostgreSQL instance for everything
2. All isolated - each stack has own database
3. Hybrid - shared for utilities, isolated for production

Decision: Hybrid Model

Shared Databases (pro-0kt-stack):
- PostgreSQL Shared (5432) - for utilities + dev stacks
- MariaDB Shared (3306) - for utilities + dev stacks
- Redis Shared (6379) - caching for all

Isolated Databases:
- seller1-prod-db (5432) - CRITICAL, production only
- seller1-dev-db (5432) - development separate
- varbase-db (5432) - development separate
- commerce-db (3306) - development separate
- myshop-db (3306) - development separate

Rationale:
- Production isolation from development
- Reduces attack surface on production database
- Utilities don't interfere with business logic
- Development environments can be reset without affecting others
- Shared cache (Redis) reduces memory usage

Consequences:
- More database containers to manage (9 total)
- More complex backup strategy
- Requires careful credential management
- Production database has strict isolation requirements


ADR-003: NPM Single Point of Failure

Status: ACKNOWLEDGED - Risk Accepted
Date: 2025-10-26

Context:
All 21 domains route through single NPM container.

Risk Level: HIGH

Mitigation Strategy:
1. NPM container auto-restart on failure
2. Health checks every 1 minute
3. Docker restart policy: always
4. Backup NPM configuration daily
5. Quick restoration procedure documented
6. Production monitoring (Uptime Kuma)

Future Improvements:
- Consider HAProxy or dual NPM setup
- CloudFlare as secondary SSL provider
- CDN for static assets


Resource Allocation

CPU & Memory

Disk Space

Disk Usage by Stack:
- /mnt/data/varbase/: 746MB (largest)
- /mnt/data/seller1-prod/: 417MB (CRITICAL)
- /mnt/data/commerce/: 419MB
- /mnt/data/myshop/: 419MB
- /mnt/data/seller1-dev/: 249MB


Scaling Considerations

Vertical Scaling

Horizontal Scaling

Load Balancing


Monitoring Strategy

Key Metrics

Health Checks

Alerting


Backup & Disaster Recovery

Backup Strategy

Recovery Procedure

  1. Database Recovery:
    bash docker exec -i seller1-prod-db psql -U postgres < backup.sql

  2. Volume Recovery:
    bash cd / && tar -xzf backup.tar.gz

  3. Full Server Recovery:
    - Restic restore from offsite backup
    - Redeployment from git repositories


Deployment Process

Deployment Layers (from DEV-PRO)

Layer system for controlled deployment:

Each layer gates subsequent layers on success.


Operational Runbooks

See $WORKSPACE/infra/@infra-dev-prod-rf/management/README.md for:
- Quick start commands
- Service management
- Troubleshooting procedures



Document Version: 1.0.0
Last Review: 2025-11-09
Next Review: 2025-12-09