Document: Infrastructure Architecture Design
Status: PRODUCTION ACTIVE
Last Updated: 2025-11-09
Version: 1.0.0
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
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
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
myshop-stack (3 containers)
- Drupal Commerce demo
- Domain: myshop.dev.0kt.ru
- Network: myshop-stack_myshop-network
commerce-stack (3 containers)
- Commerce Kickstart demo
- Domain: commerce.demo.0kt.ru
- Network: commerce-stack_commerce-network
varbase-stack (3 containers)
- Varbase distribution demo
- Domain: varbase.demo.0kt.ru
- Network: varbase-stack_varbase-network
python-stack (2 containers)
- Python Flask apps
- Domains: py.dev.0kt.ru, py.tst.0kt.ru
- Network: python-stack_python-network
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)
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
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
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 | 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 |
| 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 |
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
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
Each stack runs in isolated Docker network:
- Internal communication only
- No cross-stack network exposure
- NPM acts as security gateway
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
OAuth for *.0kt.ru domains:
- Provider: Authelia
- 2FA: Available
- Admin: admin
OAuth for seller1.ru:
- Provider: Drupal Simple OAuth
- Endpoint: auth.seller1.ru
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
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
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
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
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
Database Recovery:
bash
docker exec -i seller1-prod-db psql -U postgres < backup.sql
Volume Recovery:
bash
cd / && tar -xzf backup.tar.gz
Full Server Recovery:
- Restic restore from offsite backup
- Redeployment from git repositories
Layer system for controlled deployment:
Each layer gates subsequent layers on success.
See $WORKSPACE/infra/@infra-dev-prod-rf/management/README.md for:
- Quick start commands
- Service management
- Troubleshooting procedures
SERVERS.md - Server specificationsSTACKS.md - Stack-specific architectureDOMAINS.md - Domain and DNS architectureDocument Version: 1.0.0
Last Review: 2025-11-09
Next Review: 2025-12-09