docs(infra): add PostgreSQL tuning and systemd service documentation
- POSTGRESQL_TUNING.md: documents applied config (8GB shared_buffers, 64MB work_mem, 8GB max_wal_size, SSD params) - SYSTEMD_SERVICES.md: lists all production systemd services - systemd/: versioned copies of all .service and .timer files - .gitignore: ignore package-lock.json and backups/
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -80,3 +80,10 @@ node_modules/
|
||||
|
||||
# Diagram images (served from static, too large for git)
|
||||
dashboard/static/diagrams/
|
||||
|
||||
# Playwright / Node
|
||||
package-lock.json
|
||||
|
||||
# Backups
|
||||
backups/
|
||||
|
||||
|
||||
40
docs/POSTGRESQL_TUNING.md
Normal file
40
docs/POSTGRESQL_TUNING.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# PostgreSQL Tuning — Nexus Autoparts
|
||||
|
||||
**Server:** 48 GB RAM, 8 cores, SSD (QEMU)
|
||||
**Applied:** 2026-04-26
|
||||
**Requires restart:** Yes (done)
|
||||
|
||||
## Configuration Changes
|
||||
|
||||
File: `/etc/postgresql/17/main/postgresql.conf`
|
||||
|
||||
| Parameter | Before | After | Rationale |
|
||||
|-----------|--------|-------|-----------|
|
||||
| `shared_buffers` | 128 MB | **8 GB** | ~25% of RAM for PostgreSQL buffer cache |
|
||||
| `work_mem` | 4 MB | **64 MB** | Larger sorts/joins without disk spilling |
|
||||
| `maintenance_work_mem` | 64 MB | **1 GB** | Faster VACUUM, CREATE INDEX, ALTER |
|
||||
| `effective_cache_size` | 4 GB | **36 GB** | Planner knows OS cache is large |
|
||||
| `max_wal_size` | 1 GB | **8 GB** | Fewer checkpoints under heavy write load |
|
||||
| `checkpoint_completion_target` | 0.5 | **0.9** | Spread checkpoint I/O over more time |
|
||||
| `wal_buffers` | - | **16 MB** | WAL buffer sizing |
|
||||
| `random_page_cost` | 4.0 | **1.1** | SSD-appropriate random read cost |
|
||||
| `effective_io_concurrency` | 1 | **200** | SSD can handle many concurrent requests |
|
||||
| `max_connections` | 100 | **200** | Headroom for Celery, Quart, Dashboard, PgBouncer |
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
sudo -u postgres psql -d nexus_autoparts -c "SHOW shared_buffers;"
|
||||
```
|
||||
|
||||
## Backup
|
||||
|
||||
A backup of the previous config is stored at:
|
||||
`/etc/postgresql/17/main/postgresql.conf.backup.<timestamp>`
|
||||
|
||||
## pg_hba Adjustment for Monitoring
|
||||
|
||||
Added Docker network access for postgres-exporter:
|
||||
```
|
||||
host nexus_autoparts postgres 172.17.0.0/16 trust
|
||||
```
|
||||
35
docs/SYSTEMD_SERVICES.md
Normal file
35
docs/SYSTEMD_SERVICES.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Systemd Services — Nexus Autoparts
|
||||
|
||||
All production services are managed via systemd. Files are versioned in `systemd/`.
|
||||
|
||||
## Services
|
||||
|
||||
| Service | Description | Status |
|
||||
|---------|-------------|--------|
|
||||
| `nexus-pos.service` | Gunicorn POS (Flask), port 5001 | Active |
|
||||
| `nexus.service` | Dashboard (Flask), port 5000 | Active |
|
||||
| `nexus-quart.service` | Hypercorn async catalog, port 5002 | Active |
|
||||
| `nexus-celery.service` | Celery worker (4 prefork) | Active |
|
||||
| `nexus-mv-refresh.timer` | Daily MV refresh at 03:00 UTC | Active |
|
||||
| `nexus-cache-warm.timer` | Daily Redis cache warming at 04:00 UTC | Active |
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Reload all
|
||||
systemctl daemon-reload
|
||||
|
||||
# Restart POS
|
||||
systemctl restart nexus-pos.service
|
||||
|
||||
# View logs
|
||||
journalctl -u nexus-pos.service -f
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
sudo cp systemd/*.service systemd/*.timer /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now nexus-pos.service nexus-cache-warm.timer
|
||||
```
|
||||
11
systemd/nexus-cache-warm.service
Normal file
11
systemd/nexus-cache-warm.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Warm Redis cache for Nexus vehicle info
|
||||
After=postgresql.service redis-server.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=postgres
|
||||
WorkingDirectory=/home/Autopartes
|
||||
ExecStart=/usr/bin/python3 /home/Autopartes/scripts/warm_vehicle_cache.py --batch-size 10000 --ttl 7200
|
||||
StandardOutput=append:/var/log/nexus-pos/cache_warm.log
|
||||
StandardError=append:/var/log/nexus-pos/cache_warm.log
|
||||
9
systemd/nexus-cache-warm.timer
Normal file
9
systemd/nexus-cache-warm.timer
Normal file
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Daily Redis cache warming at 04:00 UTC (1h after MV refresh)
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 04:00:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
19
systemd/nexus-celery.service
Normal file
19
systemd/nexus-celery.service
Normal file
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=Nexus POS Celery Worker
|
||||
After=network.target postgresql.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=postgres
|
||||
WorkingDirectory=/home/Autopartes/pos
|
||||
Environment=MASTER_DB_URL=postgresql://postgres@/nexus_autoparts
|
||||
Environment=REDIS_URL=redis://localhost:6379/0
|
||||
Environment=PYTHONPATH=/home/Autopartes/pos
|
||||
ExecStart=/usr/bin/python3 -m celery -A celery_app worker --loglevel=info --concurrency=4 -n nexus-worker@%h
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
StandardOutput=append:/var/log/nexus-pos/celery.log
|
||||
StandardError=append:/var/log/nexus-pos/celery.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
10
systemd/nexus-mv-refresh.service
Normal file
10
systemd/nexus-mv-refresh.service
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Refresh Nexus part_vehicle_preview materialized view
|
||||
After=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=postgres
|
||||
ExecStart=/usr/bin/python3 /home/Autopartes/scripts/refresh_part_vehicle_preview.py
|
||||
StandardOutput=append:/var/log/nexus-pos/mv_refresh.log
|
||||
StandardError=append:/var/log/nexus-pos/mv_refresh.log
|
||||
9
systemd/nexus-mv-refresh.timer
Normal file
9
systemd/nexus-mv-refresh.timer
Normal file
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Daily refresh of part_vehicle_preview materialized view at 03:00
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 03:00:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
23
systemd/nexus-pos.service
Normal file
23
systemd/nexus-pos.service
Normal file
@@ -0,0 +1,23 @@
|
||||
[Unit]
|
||||
Description=Nexus POS (Gunicorn)
|
||||
After=network.target postgresql.service redis-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/home/Autopartes/pos
|
||||
ExecStart=/usr/local/bin/gunicorn -c gunicorn.conf.py "app:create_app()"
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
Environment=PYTHONPATH=/home/Autopartes/pos
|
||||
Environment=MASTER_DB_URL=postgresql://postgres@/nexus_autoparts
|
||||
Environment=TENANT_DB_URL_TEMPLATE=postgresql://postgres@/nexus_autoparts
|
||||
Environment=POS_JWT_SECRET=nexus-pos-jwt-secret-12345678901234567890123456789012
|
||||
Environment=REDIS_URL=redis://localhost:6379/0
|
||||
Environment=REDIS_ENABLED=true
|
||||
Environment=MEILI_URL=http://localhost:7700
|
||||
Environment=MEILI_ENABLED=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
16
systemd/nexus-quart.service
Normal file
16
systemd/nexus-quart.service
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Nexus Quart Async Catalog (hypercorn)
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/home/Autopartes/pos
|
||||
ExecStart=/usr/local/bin/hypercorn async_catalog:app --bind 0.0.0.0:5002
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
Environment=MASTER_DB_URL=postgresql://postgres@localhost/nexus_autoparts
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
17
systemd/nexus.service
Normal file
17
systemd/nexus.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Nexus Autoparts Dashboard
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/home/Autopartes/dashboard
|
||||
ExecStart=/usr/bin/python3 server.py
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
Environment=DATABASE_URL=postgresql://postgres@localhost/nexus_autoparts
|
||||
Environment=JWT_SECRET=nexus-dashboard-jwt-secret-12345678901234567890123456789012
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user