- ROADMAP: dodano funkcję #2 (e-deklaracja PZ) z analizą flow PDF + samodzielny podpis - architecture/03,07,08,09,11 + flows/06: aktualizacja pod OVH VPS (IP, user maciejpi zamiast www-data, brak NPM dla prod) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1267 lines
34 KiB
Markdown
1267 lines
34 KiB
Markdown
# Critical Configurations Reference
|
|
|
|
**Document Version:** 1.0
|
|
**Last Updated:** 2026-04-04
|
|
**Status:** Production LIVE (OVH VPS)
|
|
**Diagram Type:** Configuration Reference / Operations Guide
|
|
|
|
---
|
|
|
|
> **NOTE (2026-04-04):** Production migrated from on-prem VM 249 (10.22.68.249) to OVH VPS (57.128.200.27, hostname inpi-vps-waw01). NPM proxy host 27 configuration now applies to staging only. Production uses nginx on the VPS directly. Deploy via rsync (no git on OVH VPS).
|
|
|
|
## Overview
|
|
|
|
This document provides a **comprehensive reference** of all critical configurations for the Norda Biznes Partner infrastructure. It serves as the **single source of truth** for:
|
|
|
|
- **NPM reverse proxy configuration** (includes critical port 5000 warning)
|
|
- **Port mappings** across all servers and services
|
|
- **SSL/TLS certificate configuration** (Let's Encrypt)
|
|
- **Environment variables** and secrets management
|
|
- **Database connection strings** and credentials
|
|
- **Gunicorn/WSGI configuration** for Flask application
|
|
- **Systemd service configuration** for application lifecycle
|
|
- **Git repository configuration** for deployment
|
|
- **Critical file paths** and directory structure
|
|
- **Firewall rules** and network ACLs
|
|
|
|
**Abstraction Level:** Infrastructure Configuration
|
|
**Audience:** System Administrators, DevOps Engineers, Production Support
|
|
**Purpose:** Configuration reference, incident response, disaster recovery, new server provisioning
|
|
|
|
**⚠️ WARNING:** This document contains references to production configurations. Actual secrets are stored in `.env` files and are **never** committed to version control.
|
|
|
|
**Related Documentation:**
|
|
- [Deployment Architecture](03-deployment-architecture.md) - Infrastructure overview
|
|
- [Network Topology](07-network-topology.md) - Network layout and zones
|
|
- [HTTP Request Flow](flows/06-http-request-flow.md) - Request path details
|
|
- [Incident Report 2026-01-02](../INCIDENT_REPORT_20260102.md) - NPM port misconfiguration incident
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [NPM Reverse Proxy Configuration](#npm-reverse-proxy-configuration)
|
|
2. [Port Mappings Reference](#port-mappings-reference)
|
|
3. [SSL/TLS Configuration](#ssltls-configuration)
|
|
4. [Environment Variables](#environment-variables)
|
|
5. [Database Configuration](#database-configuration)
|
|
6. [Gunicorn WSGI Configuration](#gunicorn-wsgi-configuration)
|
|
7. [Systemd Service Configuration](#systemd-service-configuration)
|
|
8. [Git Repository Configuration](#git-repository-configuration)
|
|
9. [Critical File Paths](#critical-file-paths)
|
|
10. [Firewall and Network Rules](#firewall-and-network-rules)
|
|
11. [Backup and Recovery Locations](#backup-and-recovery-locations)
|
|
12. [Configuration Management](#configuration-management)
|
|
13. [Verification Checklist](#verification-checklist)
|
|
|
|
---
|
|
|
|
## Production Reverse Proxy Configuration (OVH VPS)
|
|
|
|
Production uses nginx on OVH VPS (57.128.200.27) as a reverse proxy to Gunicorn on 127.0.0.1:5000.
|
|
|
|
**Traffic flow:** Internet -> nginx (57.128.200.27:443) -> Gunicorn (127.0.0.1:5000)
|
|
|
|
**SSL:** Let's Encrypt via certbot (auto-renewal)
|
|
|
|
**Verification:**
|
|
```bash
|
|
curl -I https://nordabiznes.pl/health
|
|
# Expected: HTTP/2 200 OK
|
|
```
|
|
|
|
---
|
|
|
|
## NPM Reverse Proxy Configuration (STAGING ONLY)
|
|
|
|
> **NOTE:** This section now applies to **staging** (staging.nordabiznes.pl) only.
|
|
> Production no longer uses NPM.
|
|
|
|
### Port 5000 Configuration (Staging)
|
|
|
|
**Proxy Host ID:** 44 (staging)
|
|
|
|
> **HISTORICAL WARNING:** The 2026-01-02 production incident was caused by NPM forwarding to port 80 instead of 5000. See: [INCIDENT_REPORT_20260102.md](../INCIDENT_REPORT_20260102.md)
|
|
|
|
### Complete NPM Configuration
|
|
|
|
```json
|
|
{
|
|
"id": 27,
|
|
"domain_names": [
|
|
"nordabiznes.pl",
|
|
"www.nordabiznes.pl"
|
|
],
|
|
"forward_scheme": "http",
|
|
"forward_host": "57.128.200.27",
|
|
"forward_port": 5000, // ⚠️ CRITICAL: Must be 5000, NOT 80!
|
|
"certificate_id": 27,
|
|
"ssl_forced": true,
|
|
"http2_support": true,
|
|
"block_exploits": true,
|
|
"allow_websocket_upgrade": true,
|
|
"hsts_enabled": true,
|
|
"hsts_subdomains": true,
|
|
"advanced_config": "",
|
|
"access_list_id": 0,
|
|
"meta": {
|
|
"letsencrypt_agree": true,
|
|
"dns_challenge": false
|
|
}
|
|
}
|
|
```
|
|
|
|
### NPM Server Details
|
|
|
|
| Parameter | Value |
|
|
|-----------|-------|
|
|
| **Server** | R11-REVPROXY-01 |
|
|
| **VM ID** | 119 |
|
|
| **IP Address** | 10.22.68.250 |
|
|
| **NPM Version** | Latest (Docker) |
|
|
| **Container Name** | `nginx-proxy-manager_app_1` |
|
|
| **Admin Panel** | http://10.22.68.250:81 |
|
|
| **Database** | SQLite (`/data/database.sqlite`) |
|
|
|
|
### Verification Commands
|
|
|
|
```bash
|
|
# 1. Check NPM proxy host configuration
|
|
ssh maciejpi@10.22.68.250 "docker exec nginx-proxy-manager_app_1 \
|
|
sqlite3 /data/database.sqlite \
|
|
\"SELECT id, domain_names, forward_host, forward_port FROM proxy_host WHERE id = 27;\""
|
|
# Expected output: 27|["nordabiznes.pl","www.nordabiznes.pl"]|57.128.200.27|5000
|
|
|
|
# 2. Verify website is accessible
|
|
curl -I https://nordabiznes.pl/health
|
|
# Expected: HTTP/2 200 OK
|
|
|
|
# 3. Check NPM logs for errors
|
|
ssh maciejpi@10.22.68.250 "docker logs nginx-proxy-manager_app_1 --tail 50"
|
|
|
|
# 4. Verify SSL certificate
|
|
openssl s_client -connect nordabiznes.pl:443 -servername nordabiznes.pl < /dev/null 2>/dev/null | \
|
|
openssl x509 -noout -dates -subject -issuer
|
|
```
|
|
|
|
### NPM Configuration Update Procedure
|
|
|
|
**IMPORTANT:** Always verify port 5000 after making any changes to NPM!
|
|
|
|
```python
|
|
# NPM API configuration update (Python)
|
|
import requests
|
|
|
|
NPM_URL = "http://10.22.68.250:81/api"
|
|
NPM_EMAIL = "admin@example.com"
|
|
NPM_PASSWORD = "your_npm_password"
|
|
|
|
# Step 1: Authenticate
|
|
auth_response = requests.post(
|
|
f"{NPM_URL}/tokens",
|
|
json={"identity": NPM_EMAIL, "secret": NPM_PASSWORD}
|
|
)
|
|
token = auth_response.json()["token"]
|
|
headers = {"Authorization": f"Bearer {token}"}
|
|
|
|
# Step 2: Get current configuration
|
|
current = requests.get(
|
|
f"{NPM_URL}/nginx/proxy-hosts/27",
|
|
headers=headers
|
|
).json()
|
|
|
|
# Step 3: Verify port is 5000
|
|
if current["forward_port"] != 5000:
|
|
print("⚠️ WARNING: Port is not 5000! Current:", current["forward_port"])
|
|
# Update to correct port
|
|
current["forward_port"] = 5000
|
|
requests.put(
|
|
f"{NPM_URL}/nginx/proxy-hosts/27",
|
|
headers=headers,
|
|
json=current
|
|
)
|
|
print("✓ Port corrected to 5000")
|
|
else:
|
|
print("✓ Port is correctly set to 5000")
|
|
|
|
# Step 4: Verify website works
|
|
import subprocess
|
|
result = subprocess.run(["curl", "-I", "https://nordabiznes.pl/health"], capture_output=True)
|
|
if b"200 OK" in result.stdout:
|
|
print("✓ Website is accessible")
|
|
else:
|
|
print("❌ Website check failed!")
|
|
```
|
|
|
|
---
|
|
|
|
## Port Mappings Reference
|
|
|
|
### Production Port Matrix (OVH VPS 57.128.200.27)
|
|
|
|
| Server | Service | Port | Protocol | Access | Purpose |
|
|
|--------|---------|------|----------|--------|---------|
|
|
| **OVH VPS** | Nginx (HTTPS) | 443 | HTTPS | Public | SSL termination + proxy |
|
|
| OVH VPS | Nginx (HTTP) | 80 | HTTP | Public | Redirect to HTTPS |
|
|
| OVH VPS | **Gunicorn/Flask** | **5000** | HTTP | **Localhost** | **Application** |
|
|
| OVH VPS | PostgreSQL | 5432 | TCP | Localhost | Database |
|
|
| OVH VPS | SSH | 22 | SSH | Public (key-only) | Remote management |
|
|
|
|
### Staging Port Matrix (on-prem, via FortiGate + NPM)
|
|
| **OVH VPS inpi-vps-waw01** | **Flask/Gunicorn** | **5000** | **HTTP** | **LAN** | **Application (CRITICAL!)** |
|
|
| OVH VPS inpi-vps-waw01 | PostgreSQL | 5432 | TCP | Localhost | Database |
|
|
| OVH VPS inpi-vps-waw01 | Nginx (System) | 80 | HTTP | LAN | ⚠️ DO NOT USE (causes redirect loop) |
|
|
| OVH VPS inpi-vps-waw01 | Nginx (System) | 443 | HTTPS | LAN | ⚠️ DO NOT USE |
|
|
| OVH VPS inpi-vps-waw01 | SSH | 22 | SSH | Admin | Remote management |
|
|
| **r11-git-inpi** | Gitea HTTPS | 3000 | HTTPS | LAN | Git repository |
|
|
| r11-git-inpi | SSH | 22 | SSH | Admin | Remote management |
|
|
|
|
### NAT/Port Forwarding Rules (Fortigate)
|
|
|
|
```
|
|
Public → Internal NAT Mappings:
|
|
|
|
85.237.177.83:443 → 10.22.68.250:443 (NPM Proxy - HTTPS)
|
|
85.237.177.83:80 → 10.22.68.250:80 (NPM Proxy - HTTP)
|
|
|
|
Internal → Internal Routing:
|
|
|
|
10.22.68.250:* → 57.128.200.27:5000 (NPM → Flask) ⚠️ CRITICAL PORT
|
|
57.128.200.27:* → 127.0.0.1:5432 (Flask → PostgreSQL)
|
|
57.128.200.27:* → 10.22.68.180:3000 (Flask → Gitea)
|
|
```
|
|
|
|
### Port Usage by Zone
|
|
|
|
**Public Internet Zone:**
|
|
- Port 443 (HTTPS) - Public website access
|
|
- Port 80 (HTTP) - Redirects to HTTPS
|
|
|
|
**DMZ Zone (R11-REVPROXY-01):**
|
|
- Port 443 (HTTPS) - NPM SSL termination
|
|
- Port 80 (HTTP) - NPM HTTP redirect
|
|
- Port 81 (HTTP) - NPM admin panel (internal only)
|
|
|
|
**Application Zone (OVH VPS inpi-vps-waw01):**
|
|
- **Port 5000 (HTTP) - Flask/Gunicorn application** ⚠️ CRITICAL
|
|
- Port 5432 (TCP) - PostgreSQL (localhost only)
|
|
- Port 80/443 (HTTP/HTTPS) - System nginx (DO NOT USE for app)
|
|
|
|
**Internal Services Zone:**
|
|
- Port 3000 (HTTPS) - Gitea
|
|
|
|
---
|
|
|
|
## SSL/TLS Configuration
|
|
|
|
### Let's Encrypt Certificate
|
|
|
|
**Certificate Details:**
|
|
- **Provider:** Let's Encrypt
|
|
- **Managed By:** NPM (Nginx Proxy Manager)
|
|
- **Certificate ID:** 27
|
|
- **Domains:**
|
|
- nordabiznes.pl
|
|
- www.nordabiznes.pl
|
|
- **Key Type:** RSA 2048-bit
|
|
- **Validity:** 90 days
|
|
- **Renewal:** Automatic (30 days before expiry)
|
|
- **ACME Challenge:** HTTP-01
|
|
|
|
**Certificate Storage:**
|
|
- **Location (NPM):** `/data/letsencrypt/live/npm-27/`
|
|
- **Files:**
|
|
- `fullchain.pem` - Full certificate chain
|
|
- `privkey.pem` - Private key
|
|
- `cert.pem` - Certificate only
|
|
- `chain.pem` - Intermediate certificates
|
|
|
|
### TLS Configuration
|
|
|
|
```nginx
|
|
# NPM TLS Configuration (auto-generated)
|
|
|
|
ssl_certificate /data/letsencrypt/live/npm-27/fullchain.pem;
|
|
ssl_certificate_key /data/letsencrypt/live/npm-27/privkey.pem;
|
|
|
|
# SSL Protocols
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
# Cipher Suites (Modern configuration)
|
|
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
|
|
ssl_prefer_server_ciphers off;
|
|
|
|
# SSL Session
|
|
ssl_session_timeout 1d;
|
|
ssl_session_cache shared:SSL:50m;
|
|
ssl_session_tickets off;
|
|
|
|
# OCSP Stapling
|
|
ssl_stapling on;
|
|
ssl_stapling_verify on;
|
|
```
|
|
|
|
### Security Headers (NPM)
|
|
|
|
```http
|
|
# Headers added by NPM for all requests
|
|
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
|
X-Frame-Options: SAMEORIGIN
|
|
X-Content-Type-Options: nosniff
|
|
X-XSS-Protection: 1; mode=block
|
|
```
|
|
|
|
### SSL Verification Commands
|
|
|
|
```bash
|
|
# Check certificate expiry
|
|
echo | openssl s_client -connect nordabiznes.pl:443 -servername nordabiznes.pl 2>/dev/null | \
|
|
openssl x509 -noout -dates
|
|
|
|
# Test SSL configuration
|
|
curl -vI https://nordabiznes.pl 2>&1 | grep -E "(SSL|TLS|expire)"
|
|
|
|
# Check HSTS header
|
|
curl -I https://nordabiznes.pl | grep -i strict
|
|
|
|
# Test HTTP/2 support
|
|
curl -I --http2 https://nordabiznes.pl | head -1
|
|
|
|
# Comprehensive SSL test (requires ssllabs-scan)
|
|
ssllabs-scan --quiet nordabiznes.pl
|
|
```
|
|
|
|
### Certificate Renewal Process
|
|
|
|
**Automatic Renewal (NPM handles this):**
|
|
1. NPM checks certificates 30 days before expiry
|
|
2. Initiates ACME HTTP-01 challenge with Let's Encrypt
|
|
3. Creates `.well-known/acme-challenge/` endpoint
|
|
4. Let's Encrypt validates domain ownership
|
|
5. New certificate issued and NPM reloads nginx
|
|
6. Zero downtime renewal
|
|
|
|
**Manual Renewal (if automatic fails):**
|
|
```bash
|
|
# SSH to NPM server
|
|
ssh maciejpi@10.22.68.250
|
|
|
|
# Force certificate renewal
|
|
docker exec nginx-proxy-manager_app_1 \
|
|
certbot renew --force-renewal
|
|
|
|
# Reload nginx
|
|
docker exec nginx-proxy-manager_app_1 nginx -s reload
|
|
|
|
# Verify new certificate
|
|
curl -vI https://nordabiznes.pl 2>&1 | grep "expire date"
|
|
```
|
|
|
|
---
|
|
|
|
## Environment Variables
|
|
|
|
### Production Environment Variables
|
|
|
|
**Location:** `/var/www/nordabiznes/.env`
|
|
**Owner:** `maciejpi:maciejpi`
|
|
**Permissions:** `0600` (read/write owner only)
|
|
|
|
**⚠️ WARNING:** Never commit `.env` to version control!
|
|
|
|
### Required Variables
|
|
|
|
```bash
|
|
# Flask Configuration
|
|
SECRET_KEY=<random-64-character-hex-string>
|
|
FLASK_ENV=production
|
|
|
|
# Server Configuration
|
|
PORT=5000
|
|
HOST=0.0.0.0
|
|
|
|
# Database Configuration
|
|
DATABASE_URL=postgresql://nordabiz_app:<password>@127.0.0.1:5432/nordabiz
|
|
|
|
# Google Gemini API
|
|
GOOGLE_GEMINI_API_KEY=<gemini-api-key>
|
|
|
|
# Google PageSpeed Insights API
|
|
GOOGLE_PAGESPEED_API_KEY=<pagespeed-api-key>
|
|
|
|
# Google Places API
|
|
GOOGLE_PLACES_API_KEY=<places-api-key>
|
|
|
|
# Brave Search API
|
|
BRAVE_SEARCH_API_KEY=<brave-api-key>
|
|
|
|
# Microsoft Graph API (OAuth 2.0)
|
|
MS_GRAPH_CLIENT_ID=<client-id>
|
|
MS_GRAPH_CLIENT_SECRET=<client-secret>
|
|
MS_GRAPH_TENANT_ID=<tenant-id>
|
|
|
|
# Email Configuration (Microsoft Graph)
|
|
MAIL_DEFAULT_SENDER=noreply@nordabiznes.pl
|
|
|
|
# Application URLs
|
|
APP_URL=https://nordabiznes.pl
|
|
VERIFY_EMAIL_URL=https://nordabiznes.pl/verify-email
|
|
```
|
|
|
|
### Environment Variable Generation
|
|
|
|
```bash
|
|
# Generate SECRET_KEY (64 random hex characters)
|
|
python3 -c "import secrets; print(secrets.token_hex(32))"
|
|
|
|
# Generate random password (32 characters)
|
|
openssl rand -base64 32
|
|
|
|
# Verify .env file permissions
|
|
ls -la /var/www/nordabiznes/.env
|
|
# Expected: -rw------- 1 maciejpi maciejpi ... .env
|
|
```
|
|
|
|
### Development Environment Variables
|
|
|
|
**Location:** `.env` (in project root, git-ignored)
|
|
**Template:** `.env.example`
|
|
|
|
```bash
|
|
# Development configuration (localhost)
|
|
DATABASE_URL=postgresql://nordabiz_app:NordaBiz2025Secure@127.0.0.1:5433/nordabiz
|
|
APP_URL=http://localhost:5000
|
|
FLASK_ENV=development
|
|
```
|
|
|
|
**Note:** Development uses Docker PostgreSQL on port 5433 (not 5432)
|
|
|
|
---
|
|
|
|
## Database Configuration
|
|
|
|
### Production Database
|
|
|
|
**Server:** OVH VPS (57.128.200.27, hostname: inpi-vps-waw01)
|
|
**DBMS:** PostgreSQL 14
|
|
**Database Name:** `nordabiz`
|
|
**Port:** 5432 (localhost only)
|
|
|
|
### Database Users and Roles
|
|
|
|
| User | Role | Permissions | Purpose |
|
|
|------|------|-------------|---------|
|
|
| `postgres` | Superuser | ALL | Database administration |
|
|
| `nordabiz_app` | Application user | CRUD on all tables | Flask application |
|
|
| `nordabiz_readonly` | Read-only | SELECT only | Reporting, backups |
|
|
|
|
### Connection Strings
|
|
|
|
**Production (Flask app):**
|
|
```
|
|
postgresql://nordabiz_app:<password>@127.0.0.1:5432/nordabiz
|
|
```
|
|
|
|
**Development (Docker):**
|
|
```
|
|
postgresql://nordabiz_app:NordaBiz2025Secure@127.0.0.1:5433/nordabiz
|
|
```
|
|
|
|
**Direct psql (production):**
|
|
```bash
|
|
# As application user
|
|
psql -U nordabiz_app -d nordabiz -h 127.0.0.1
|
|
|
|
# As postgres superuser
|
|
sudo -u postgres psql nordabiz
|
|
```
|
|
|
|
### PostgreSQL Configuration Files
|
|
|
|
**Location:** `/etc/postgresql/14/main/`
|
|
|
|
**postgresql.conf (Key Settings):**
|
|
```conf
|
|
# Network Settings
|
|
listen_addresses = 'localhost' # ⚠️ CRITICAL: localhost only!
|
|
port = 5432
|
|
|
|
# Memory Settings
|
|
shared_buffers = 256MB
|
|
effective_cache_size = 1GB
|
|
work_mem = 16MB
|
|
|
|
# Connection Settings
|
|
max_connections = 100
|
|
|
|
# Logging
|
|
log_destination = 'stderr'
|
|
logging_collector = on
|
|
log_directory = '/var/log/postgresql'
|
|
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
|
|
log_statement = 'mod' # Log all modifications
|
|
log_min_duration_statement = 1000 # Log slow queries (>1s)
|
|
```
|
|
|
|
**pg_hba.conf (Access Control):**
|
|
```conf
|
|
# TYPE DATABASE USER ADDRESS METHOD
|
|
|
|
# Local connections
|
|
local all postgres peer
|
|
local nordabiz nordabiz_app md5
|
|
|
|
# IPv4 local connections
|
|
host nordabiz nordabiz_app 127.0.0.1/32 md5
|
|
|
|
# ⚠️ CRITICAL: No external connections allowed!
|
|
# External access is blocked by listening on localhost only
|
|
```
|
|
|
|
### Database Backup Configuration
|
|
|
|
**Backup Location:** `/var/backups/nordabiz/`
|
|
**Owner:** `postgres:postgres`
|
|
**Retention:** 7 days
|
|
|
|
**Daily Backup Cron:**
|
|
```bash
|
|
# /etc/cron.d/nordabiz-backup
|
|
0 2 * * * postgres pg_dump -U nordabiz_app nordabiz | gzip > /var/backups/nordabiz/nordabiz_$(date +\%Y\%m\%d).sql.gz
|
|
```
|
|
|
|
**Manual Backup:**
|
|
```bash
|
|
# Create backup
|
|
sudo -u postgres pg_dump -U nordabiz_app nordabiz > /tmp/nordabiz_backup_$(date +%Y%m%d_%H%M%S).sql
|
|
|
|
# Create compressed backup
|
|
sudo -u postgres pg_dump -U nordabiz_app nordabiz | gzip > /tmp/nordabiz_backup.sql.gz
|
|
|
|
# Restore from backup
|
|
sudo -u postgres psql -U nordabiz_app nordabiz < /tmp/nordabiz_backup.sql
|
|
```
|
|
|
|
---
|
|
|
|
## Gunicorn WSGI Configuration
|
|
|
|
### Gunicorn Settings
|
|
|
|
**Location:** Configured in systemd service file
|
|
**Socket:** `0.0.0.0:5000`
|
|
**Workers:** 4 (recommended: 2-4 x CPU cores)
|
|
**Worker Class:** `sync` (default)
|
|
**Timeout:** 120 seconds
|
|
**Max Requests:** 1000 (worker restart after 1000 requests)
|
|
**Access Log:** `/var/log/nordabiznes/gunicorn_access.log`
|
|
**Error Log:** `/var/log/nordabiznes/gunicorn_error.log`
|
|
|
|
### Gunicorn Command
|
|
|
|
```bash
|
|
gunicorn \
|
|
--bind 127.0.0.1:5000 \
|
|
--workers 4 \
|
|
--timeout 120 \
|
|
--max-requests 1000 \
|
|
--access-logfile /var/log/nordabiznes/gunicorn_access.log \
|
|
--error-logfile /var/log/nordabiznes/gunicorn_error.log \
|
|
--log-level info \
|
|
app:app
|
|
```
|
|
|
|
### Worker Calculation
|
|
|
|
```python
|
|
# Recommended workers formula
|
|
workers = (2 * num_cpu_cores) + 1
|
|
|
|
# For OVH VPS inpi-vps-waw01 (4 vCPUs)
|
|
workers = (2 * 4) + 1 = 9 # Maximum
|
|
workers = 4 # Current (conservative)
|
|
```
|
|
|
|
### Gunicorn Tuning Considerations
|
|
|
|
| Parameter | Current | Tuning Notes |
|
|
|-----------|---------|--------------|
|
|
| Workers | 4 | Increase to 6-8 under high load |
|
|
| Timeout | 120s | Sufficient for AI chat (Gemini API ~2-5s) |
|
|
| Max Requests | 1000 | Prevents memory leaks |
|
|
| Worker Class | sync | Consider `gevent` for WebSocket support |
|
|
| Keep-Alive | 5s | Default, no tuning needed |
|
|
|
|
---
|
|
|
|
## Systemd Service Configuration
|
|
|
|
### Service File Location
|
|
|
|
**File:** `/etc/systemd/system/nordabiznes.service`
|
|
**Owner:** `root:root`
|
|
**Permissions:** `0644`
|
|
|
|
### Complete Service Configuration
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=Norda Biznes Partner - Flask Application
|
|
After=network.target postgresql.service
|
|
Requires=postgresql.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=maciejpi
|
|
Group=maciejpi
|
|
WorkingDirectory=/var/www/nordabiznes
|
|
Environment="PATH=/var/www/nordabiznes/venv/bin"
|
|
EnvironmentFile=/var/www/nordabiznes/.env
|
|
ExecStart=/var/www/nordabiznes/venv/bin/gunicorn \
|
|
--bind 127.0.0.1:5000 \
|
|
--workers 4 \
|
|
--timeout 120 \
|
|
--max-requests 1000 \
|
|
--access-logfile /var/log/nordabiznes/gunicorn_access.log \
|
|
--error-logfile /var/log/nordabiznes/gunicorn_error.log \
|
|
--log-level info \
|
|
app:app
|
|
|
|
# Restart policy
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
# Logging
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=nordabiznes
|
|
|
|
# Security
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
### Service Management Commands
|
|
|
|
```bash
|
|
# Start service
|
|
sudo systemctl start nordabiznes
|
|
|
|
# Stop service
|
|
sudo systemctl stop nordabiznes
|
|
|
|
# Restart service (after code changes)
|
|
sudo systemctl restart nordabiznes
|
|
|
|
# Reload service (graceful restart)
|
|
sudo systemctl reload nordabiznes
|
|
|
|
# Check status
|
|
sudo systemctl status nordabiznes
|
|
|
|
# Enable autostart on boot
|
|
sudo systemctl enable nordabiznes
|
|
|
|
# Disable autostart
|
|
sudo systemctl disable nordabiznes
|
|
|
|
# View logs
|
|
sudo journalctl -u nordabiznes -f
|
|
|
|
# View logs (last 100 lines)
|
|
sudo journalctl -u nordabiznes -n 100
|
|
|
|
# View logs (since 1 hour ago)
|
|
sudo journalctl -u nordabiznes --since "1 hour ago"
|
|
```
|
|
|
|
### Service Restart After Changes
|
|
|
|
```bash
|
|
# After modifying .env file
|
|
sudo systemctl restart nordabiznes
|
|
|
|
# After modifying Python code
|
|
sudo systemctl restart nordabiznes
|
|
|
|
# After modifying systemd service file
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl restart nordabiznes
|
|
|
|
# After database schema changes
|
|
# (Usually no restart needed, but recommended)
|
|
sudo systemctl restart nordabiznes
|
|
```
|
|
|
|
---
|
|
|
|
## Git Repository Configuration
|
|
|
|
### Git Remotes
|
|
|
|
| Remote | URL | Purpose |
|
|
|--------|-----|---------|
|
|
| **inpi** (primary) | `https://10.22.68.180:3000/maciejpi/nordabiz.git` | Internal Gitea (deployment source) |
|
|
| **origin** | `git@github.com:pienczyn/nordabiz.git` | GitHub (cloud backup) |
|
|
|
|
### Production Deployment (OVH VPS — no git)
|
|
|
|
**Deployment method:** rsync from development machine (no git on OVH VPS)
|
|
|
|
**Application Location:** `/var/www/nordabiznes/`
|
|
**User:** `maciejpi`
|
|
|
|
### Deployment Workflow
|
|
|
|
```bash
|
|
# On development machine (Mac)
|
|
git push origin master # Push to GitHub
|
|
git push inpi master # Push to internal Gitea
|
|
|
|
# Deploy to production via rsync
|
|
rsync -avz --exclude='.env' --exclude='venv/' --exclude='.git/' \
|
|
./ maciejpi@57.128.200.27:/var/www/nordabiznes/
|
|
|
|
# Restart service
|
|
ssh maciejpi@57.128.200.27 "sudo systemctl reload nordabiznes"
|
|
|
|
# Verify
|
|
curl -I https://nordabiznes.pl/health
|
|
```
|
|
|
|
### Gitea Server Configuration (staging deploy source)
|
|
|
|
**Server:** r11-git-inpi
|
|
**IP:** 10.22.68.180
|
|
**Port:** 3000 (HTTPS)
|
|
**URL:** https://10.22.68.180:3000/
|
|
**User:** `maciejpi`
|
|
**Repository:** `maciejpi/nordabiz`
|
|
|
|
### SSH Keys for Git Access
|
|
|
|
**Production Server:**
|
|
- Location: `/home/maciejpi/.ssh/`
|
|
- Public key: `id_rsa.pub`
|
|
- Private key: `id_rsa`
|
|
- Known hosts: `known_hosts` (includes Gitea fingerprint)
|
|
|
|
**Development Machine:**
|
|
- GitHub SSH key: `~/.ssh/id_rsa` (GitHub account: `pienczyn`)
|
|
- Gitea HTTP access: Username/password (no SSH key required due to HTTPS)
|
|
|
|
---
|
|
|
|
## Critical File Paths
|
|
|
|
### Application Files
|
|
|
|
| Path | Description | Owner | Permissions |
|
|
|------|-------------|-------|-------------|
|
|
| `/var/www/nordabiznes/` | Application root directory | maciejpi:maciejpi | 0755 |
|
|
| `/var/www/nordabiznes/app.py` | Main Flask application | maciejpi:maciejpi | 0644 |
|
|
| `/var/www/nordabiznes/.env` | Environment variables (secrets) | maciejpi:maciejpi | 0600 |
|
|
| `/var/www/nordabiznes/venv/` | Python virtual environment | maciejpi:maciejpi | 0755 |
|
|
| `/var/www/nordabiznes/static/` | Static assets (CSS, JS, images) | maciejpi:maciejpi | 0755 |
|
|
| `/var/www/nordabiznes/templates/` | Jinja2 templates | maciejpi:maciejpi | 0755 |
|
|
| `/var/www/nordabiznes/database.py` | SQLAlchemy models | maciejpi:maciejpi | 0644 |
|
|
| `/var/www/nordabiznes/scripts/` | Background scripts | maciejpi:maciejpi | 0755 |
|
|
|
|
### Configuration Files
|
|
|
|
| Path | Description | Owner | Permissions |
|
|
|------|-------------|-------|-------------|
|
|
| `/etc/systemd/system/nordabiznes.service` | Systemd service file | root:root | 0644 |
|
|
| `/etc/postgresql/14/main/postgresql.conf` | PostgreSQL configuration | postgres:postgres | 0644 |
|
|
| `/etc/postgresql/14/main/pg_hba.conf` | PostgreSQL access control | postgres:postgres | 0640 |
|
|
|
|
### Log Files
|
|
|
|
| Path | Description | Rotation | Owner |
|
|
|------|-------------|----------|-------|
|
|
| `/var/log/nordabiznes/gunicorn_access.log` | Gunicorn access log | Daily | maciejpi |
|
|
| `/var/log/nordabiznes/gunicorn_error.log` | Gunicorn error log | Daily | maciejpi |
|
|
| `/var/log/postgresql/postgresql-*.log` | PostgreSQL logs | Weekly | postgres |
|
|
| `journalctl -u nordabiznes` | Systemd service logs | 30 days | root |
|
|
|
|
### Backup Locations
|
|
|
|
| Path | Description | Retention | Owner |
|
|
|------|-------------|-----------|-------|
|
|
| `/var/backups/nordabiz/` | Daily database backups | 7 days | postgres |
|
|
| `/home/maciejpi/backups/` | Manual backups | Manual | maciejpi |
|
|
|
|
### Temporary Files
|
|
|
|
| Path | Description | Cleanup | Owner |
|
|
|------|-------------|---------|-------|
|
|
| `/tmp/` | Temporary files (uploads, etc.) | Reboot | Various |
|
|
| `/var/tmp/` | Persistent temp files | 30 days | Various |
|
|
|
|
---
|
|
|
|
## Firewall and Network Rules
|
|
|
|
### Fortigate Firewall Configuration
|
|
|
|
**WAN Interface:** `wan1` (85.237.177.83)
|
|
**LAN Interface:** `internal` (10.22.68.1)
|
|
|
|
**NAT Rules (Destination NAT / Port Forwarding):**
|
|
```
|
|
Rule 1: HTTPS
|
|
External: 85.237.177.83:443 → Internal: 10.22.68.250:443
|
|
Protocol: TCP
|
|
Action: DNAT
|
|
|
|
Rule 2: HTTP
|
|
External: 85.237.177.83:80 → Internal: 10.22.68.250:80
|
|
Protocol: TCP
|
|
Action: DNAT
|
|
```
|
|
|
|
**Firewall Policies:**
|
|
```
|
|
Policy 1: Allow HTTPS from Internet
|
|
Source: all
|
|
Destination: 10.22.68.250
|
|
Service: HTTPS (443)
|
|
Action: ACCEPT
|
|
|
|
Policy 2: Allow HTTP from Internet
|
|
Source: all
|
|
Destination: 10.22.68.250
|
|
Service: HTTP (80)
|
|
Action: ACCEPT
|
|
|
|
Policy 3: Allow SSH from Admin Network
|
|
Source: admin_network (10.22.68.0/24)
|
|
Destination: all_internal_servers
|
|
Service: SSH (22)
|
|
Action: ACCEPT
|
|
|
|
Policy 4: Allow Internal Traffic
|
|
Source: 10.22.68.0/24
|
|
Destination: 10.22.68.0/24
|
|
Service: any
|
|
Action: ACCEPT
|
|
|
|
Policy 5: Default Deny
|
|
Source: all
|
|
Destination: all
|
|
Service: any
|
|
Action: DENY
|
|
```
|
|
|
|
### OVH VPS Firewall (ufw)
|
|
|
|
**Status:** Active on OVH VPS (production does not use FortiGate)
|
|
|
|
**Default Policy:**
|
|
```bash
|
|
# Check ufw status
|
|
sudo ufw status verbose
|
|
|
|
# Expected rules: ALLOW 22/tcp, 80/tcp, 443/tcp
|
|
```
|
|
|
|
### PostgreSQL Access Control
|
|
|
|
**Network Access:** `listen_addresses = 'localhost'` (127.0.0.1 only)
|
|
|
|
**pg_hba.conf Rules:**
|
|
```
|
|
# Only allow localhost connections
|
|
host nordabiz nordabiz_app 127.0.0.1/32 md5
|
|
|
|
# Block all other addresses (implicit)
|
|
```
|
|
|
|
---
|
|
|
|
## Backup and Recovery Locations
|
|
|
|
### Database Backups
|
|
|
|
**Automated Daily Backups:**
|
|
- **Location:** `/var/backups/nordabiz/`
|
|
- **Filename Pattern:** `nordabiz_YYYYMMDD.sql.gz`
|
|
- **Schedule:** 2:00 AM daily (cron)
|
|
- **Retention:** 7 days (automatic cleanup)
|
|
- **Size:** ~5-10 MB compressed
|
|
|
|
**Manual Backups:**
|
|
```bash
|
|
# Create manual backup
|
|
sudo -u postgres pg_dump -U nordabiz_app nordabiz > \
|
|
/home/maciejpi/backups/nordabiz_manual_$(date +%Y%m%d_%H%M%S).sql
|
|
|
|
# Restore from backup
|
|
sudo -u postgres psql -U nordabiz_app nordabiz < \
|
|
/home/maciejpi/backups/nordabiz_manual_20260110_120000.sql
|
|
```
|
|
|
|
### Application Backups
|
|
|
|
**Git Repository:**
|
|
- **Primary:** Gitea (10.22.68.180) - internal backup
|
|
- **Secondary:** GitHub (github.com/pienczyn/nordabiz) - cloud backup
|
|
|
|
**VM Snapshots (Proxmox):**
|
|
- **Location:** Proxmox Backup Server
|
|
- **Schedule:** Weekly
|
|
- **Retention:** 4 weeks
|
|
- **VM ID:** 249 (OVH VPS inpi-vps-waw01)
|
|
|
|
### Configuration Backups
|
|
|
|
**NPM Configuration:**
|
|
```bash
|
|
# Backup NPM database
|
|
ssh maciejpi@10.22.68.250 \
|
|
"docker cp nginx-proxy-manager_app_1:/data/database.sqlite /tmp/npm_backup.sqlite"
|
|
|
|
# Copy to local
|
|
scp maciejpi@10.22.68.250:/tmp/npm_backup.sqlite ~/backups/
|
|
```
|
|
|
|
**Environment Variables:**
|
|
```bash
|
|
# Backup .env file (contains secrets!)
|
|
sudo cp /var/www/nordabiznes/.env /home/maciejpi/backups/.env.backup
|
|
sudo chmod 600 /home/maciejpi/backups/.env.backup
|
|
```
|
|
|
|
### Disaster Recovery Procedure
|
|
|
|
**Complete Server Rebuild:**
|
|
|
|
1. **Restore VM from Proxmox snapshot** (or provision new VM)
|
|
2. **Install base packages:**
|
|
```bash
|
|
sudo apt update
|
|
sudo apt install -y python3 python3-venv python3-pip postgresql-14 git nginx
|
|
```
|
|
3. **Restore database:**
|
|
```bash
|
|
sudo -u postgres createdb nordabiz
|
|
sudo -u postgres psql nordabiz < /path/to/backup.sql
|
|
```
|
|
4. **Clone application:**
|
|
```bash
|
|
sudo mkdir -p /var/www/nordabiznes
|
|
sudo chown maciejpi:maciejpi /var/www/nordabiznes
|
|
sudo -u maciejpi git clone https://10.22.68.180:3000/maciejpi/nordabiz.git /var/www/nordabiznes
|
|
```
|
|
5. **Restore .env file:**
|
|
```bash
|
|
sudo cp /path/to/.env.backup /var/www/nordabiznes/.env
|
|
sudo chown maciejpi:maciejpi /var/www/nordabiznes/.env
|
|
sudo chmod 600 /var/www/nordabiznes/.env
|
|
```
|
|
6. **Install Python dependencies:**
|
|
```bash
|
|
cd /var/www/nordabiznes
|
|
sudo -u maciejpi python3 -m venv venv
|
|
sudo -u maciejpi venv/bin/pip install -r requirements.txt
|
|
```
|
|
7. **Configure systemd service:**
|
|
```bash
|
|
sudo cp nordabiznes.service /etc/systemd/system/
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable nordabiznes
|
|
sudo systemctl start nordabiznes
|
|
```
|
|
8. **Reconfigure NPM:**
|
|
- Update proxy host 27 to point to new server IP
|
|
- Verify `forward_port = 5000`
|
|
9. **Verify deployment:**
|
|
```bash
|
|
curl -I https://nordabiznes.pl/health
|
|
# Expected: HTTP/2 200 OK
|
|
```
|
|
|
|
---
|
|
|
|
## Configuration Management
|
|
|
|
### Configuration Change Procedure
|
|
|
|
**⚠️ ALWAYS follow this procedure for production changes:**
|
|
|
|
1. **Backup current configuration**
|
|
```bash
|
|
# Database
|
|
sudo -u postgres pg_dump nordabiz > /tmp/backup_before_change.sql
|
|
|
|
# Application
|
|
cd /var/www/nordabiznes
|
|
sudo -u maciejpi git status # Ensure clean state
|
|
```
|
|
|
|
2. **Test changes in development**
|
|
```bash
|
|
# On local machine
|
|
# Test with Docker PostgreSQL on port 5433
|
|
python3 app.py
|
|
# Verify functionality
|
|
```
|
|
|
|
3. **Document the change**
|
|
- Update CLAUDE.md if architecture changes
|
|
- Update this document if configuration changes
|
|
- Add entry to CHANGELOG.md
|
|
|
|
4. **Apply change to production**
|
|
```bash
|
|
# SSH to production
|
|
ssh maciejpi@57.128.200.27
|
|
|
|
# Pull changes
|
|
cd /var/www/nordabiznes
|
|
sudo -u maciejpi git pull
|
|
|
|
# Restart service
|
|
sudo systemctl restart nordabiznes
|
|
```
|
|
|
|
5. **Verify change**
|
|
```bash
|
|
# Check service status
|
|
sudo systemctl status nordabiznes
|
|
|
|
# Check application health
|
|
curl -I https://nordabiznes.pl/health
|
|
# Expected: HTTP/2 200 OK
|
|
|
|
# Monitor logs
|
|
sudo journalctl -u nordabiznes -f
|
|
```
|
|
|
|
6. **Rollback procedure (if needed)**
|
|
```bash
|
|
# Stop service
|
|
sudo systemctl stop nordabiznes
|
|
|
|
# Rollback code
|
|
sudo -u maciejpi git reset --hard HEAD~1
|
|
|
|
# Rollback database (if needed)
|
|
sudo -u postgres psql nordabiz < /tmp/backup_before_change.sql
|
|
|
|
# Start service
|
|
sudo systemctl start nordabiznes
|
|
```
|
|
|
|
### Configuration Version Control
|
|
|
|
**Tracked in Git:**
|
|
- Application code (`app.py`, `*.py`)
|
|
- Templates (`templates/`)
|
|
- Static assets (`static/`)
|
|
- Requirements (`requirements.txt`)
|
|
- Documentation (`docs/`, `CLAUDE.md`)
|
|
|
|
**NOT tracked in Git (secrets):**
|
|
- `.env` (environment variables)
|
|
- `*.pyc` (Python bytecode)
|
|
- `venv/` (virtual environment)
|
|
- `__pycache__/` (Python cache)
|
|
- Log files
|
|
|
|
**Tracked externally (infrastructure as code):**
|
|
- NPM configuration (stored in NPM SQLite database)
|
|
- Systemd service files (manual versioning)
|
|
- PostgreSQL configuration (manual versioning)
|
|
|
|
---
|
|
|
|
## Verification Checklist
|
|
|
|
### Pre-Deployment Verification
|
|
|
|
- [ ] Code changes tested in development environment
|
|
- [ ] Database migrations tested (if applicable)
|
|
- [ ] `.env` variables updated (if needed)
|
|
- [ ] No secrets committed to Git
|
|
- [ ] CHANGELOG.md updated
|
|
- [ ] Documentation updated (if architecture changed)
|
|
|
|
### Post-Deployment Verification
|
|
|
|
- [ ] **NPM configuration verified: `forward_port = 5000`** ⚠️ CRITICAL
|
|
- [ ] Website accessible: `curl -I https://nordabiznes.pl/health` returns 200
|
|
- [ ] SSL certificate valid: No browser warnings
|
|
- [ ] Database connection working: Query returns data
|
|
- [ ] Service running: `systemctl status nordabiznes` shows active
|
|
- [ ] No errors in logs: `journalctl -u nordabiznes -n 50`
|
|
- [ ] External APIs working: Test chat, SEO audit
|
|
- [ ] Authentication working: Test login/logout
|
|
- [ ] Static assets loading: Check browser console for 404s
|
|
|
|
### NPM Configuration Verification (CRITICAL!)
|
|
|
|
```bash
|
|
# ⚠️ ALWAYS run this after ANY NPM changes!
|
|
|
|
# 1. Check proxy host configuration
|
|
ssh maciejpi@10.22.68.250 "docker exec nginx-proxy-manager_app_1 \
|
|
sqlite3 /data/database.sqlite \
|
|
\"SELECT id, domain_names, forward_host, forward_port FROM proxy_host WHERE id = 27;\""
|
|
|
|
# Expected output:
|
|
# 27|["nordabiznes.pl","www.nordabiznes.pl"]|57.128.200.27|5000
|
|
# ^^^^
|
|
# MUST BE 5000!
|
|
|
|
# 2. Test website accessibility
|
|
curl -I https://nordabiznes.pl/health
|
|
# Expected: HTTP/2 200 OK
|
|
|
|
# 3. Test from external network (use phone without WiFi)
|
|
# Browse to: https://nordabiznes.pl
|
|
# Should load without ERR_TOO_MANY_REDIRECTS
|
|
```
|
|
|
|
### Database Verification
|
|
|
|
```bash
|
|
# Check database connectivity
|
|
psql -U nordabiz_app -d nordabiz -h 127.0.0.1 -c "SELECT COUNT(*) FROM companies;"
|
|
|
|
# Check recent data
|
|
psql -U nordabiz_app -d nordabiz -h 127.0.0.1 -c \
|
|
"SELECT name, slug FROM companies ORDER BY created_at DESC LIMIT 5;"
|
|
|
|
# Check database size
|
|
sudo -u postgres psql -c "SELECT pg_size_pretty(pg_database_size('nordabiz'));"
|
|
```
|
|
|
|
### Service Health Verification
|
|
|
|
```bash
|
|
# Systemd service status
|
|
sudo systemctl status nordabiznes
|
|
|
|
# Process check
|
|
ps aux | grep gunicorn
|
|
|
|
# Port listening check
|
|
sudo netstat -tlnp | grep 5000
|
|
# Expected: gunicorn listening on 0.0.0.0:5000
|
|
|
|
# Application logs (last 50 lines)
|
|
sudo journalctl -u nordabiznes -n 50 --no-pager
|
|
|
|
# Error log check (should be minimal)
|
|
sudo journalctl -u nordabiznes -p err -n 20
|
|
```
|
|
|
|
---
|
|
|
|
## Emergency Contacts and Resources
|
|
|
|
### Server Access
|
|
|
|
| Server | IP | SSH User | Purpose |
|
|
|--------|-----|----------|---------|
|
|
| OVH VPS inpi-vps-waw01 | 57.128.200.27 | `maciejpi` | Application server |
|
|
| R11-REVPROXY-01 | 10.22.68.250 | `maciejpi` | NPM proxy |
|
|
| r11-git-inpi | 10.22.68.180 | `maciejpi` | Gitea repository |
|
|
|
|
**⚠️ NEVER SSH as root!** Always use `maciejpi` user and `sudo` for elevated privileges.
|
|
|
|
### Key Commands for Incidents
|
|
|
|
```bash
|
|
# 1. Quick health check
|
|
curl -I https://nordabiznes.pl/health
|
|
|
|
# 2. Check service status
|
|
ssh maciejpi@57.128.200.27 "sudo systemctl status nordabiznes"
|
|
|
|
# 3. Check NPM proxy configuration
|
|
ssh maciejpi@10.22.68.250 "docker exec nginx-proxy-manager_app_1 \
|
|
sqlite3 /data/database.sqlite \
|
|
\"SELECT forward_port FROM proxy_host WHERE id = 27;\""
|
|
|
|
# 4. View recent errors
|
|
ssh maciejpi@57.128.200.27 "sudo journalctl -u nordabiznes -p err -n 20"
|
|
|
|
# 5. Restart application
|
|
ssh maciejpi@57.128.200.27 "sudo systemctl restart nordabiznes"
|
|
```
|
|
|
|
### Documentation Resources
|
|
|
|
- **This Document:** `docs/architecture/08-critical-configurations.md`
|
|
- **Incident Report:** `docs/INCIDENT_REPORT_20260102.md`
|
|
- **Deployment Architecture:** `docs/architecture/03-deployment-architecture.md`
|
|
- **Network Topology:** `docs/architecture/07-network-topology.md`
|
|
- **HTTP Request Flow:** `docs/architecture/flows/06-http-request-flow.md`
|
|
- **Main Documentation:** `CLAUDE.md`
|
|
|
|
---
|
|
|
|
## Appendix: Quick Reference Cards
|
|
|
|
### Quick Reference: NPM Proxy
|
|
|
|
```
|
|
Proxy Host ID: 27
|
|
Domains: nordabiznes.pl, www.nordabiznes.pl
|
|
Backend: 57.128.200.27:5000 ⚠️ PORT 5000 (NOT 80!)
|
|
SSL: Let's Encrypt (auto-renew)
|
|
```
|
|
|
|
### Quick Reference: Port Mappings
|
|
|
|
```
|
|
Internet → Fortigate → NPM → Flask
|
|
:443 → :443 → :5000
|
|
|
|
⚠️ CRITICAL: NPM → Flask must use port 5000
|
|
```
|
|
|
|
### Quick Reference: Database
|
|
|
|
```
|
|
Host: 127.0.0.1 (localhost only)
|
|
Port: 5432
|
|
Database: nordabiz
|
|
User: nordabiz_app
|
|
```
|
|
|
|
### Quick Reference: Service Management
|
|
|
|
```bash
|
|
sudo systemctl restart nordabiznes # Restart app
|
|
sudo journalctl -u nordabiznes -f # View logs
|
|
curl -I https://nordabiznes.pl/health # Test health
|
|
```
|
|
|
|
### Quick Reference: Emergency Rollback
|
|
|
|
```bash
|
|
ssh maciejpi@57.128.200.27
|
|
cd /var/www/nordabiznes
|
|
sudo systemctl stop nordabiznes
|
|
sudo -u maciejpi git reset --hard HEAD~1
|
|
sudo systemctl start nordabiznes
|
|
curl -I https://nordabiznes.pl/health
|
|
```
|
|
|
|
---
|
|
|
|
**Document Maintenance:**
|
|
- Update this document after ANY configuration changes
|
|
- Verify accuracy quarterly
|
|
- Include in onboarding materials for new team members
|
|
- Reference in incident response procedures
|
|
|
|
**Last Verified:** 2026-01-10
|
|
**Next Review:** 2026-04-10
|