v2-exece-docs

This commit is contained in:
IGNY8 VPS (Salman)
2026-03-23 10:30:51 +00:00
parent b94d41b7f6
commit e78a41f11c
15 changed files with 2218 additions and 707 deletions

View File

@@ -2,9 +2,10 @@
**Document ID:** 00C-igny8-production-migration
**Phase:** Phase 0: Production Migration
**Version:** 2.0
**Version:** 2.1
**Date:** 2026-03-23
**Status:** In Progress
**Source of Truth:** Codebase at `/data/app/igny8/`
**Related Docs:**
- 00A: GitHub Repository Consolidation (completed)
@@ -23,18 +24,29 @@
**Project Name:** igny8-app
**Compose File:** docker-compose.app.yml
#### Active Containers
#### Active Containers (Verified from docker-compose.app.yml)
**App containers (7 in docker-compose.app.yml):**
| Container | Service | Port (Host:Container) | Technology |
|-----------|---------|----------------------|------------|
| igny8_backend | REST API | 8011:8010 | Django >=5.2.7 + Gunicorn (4 workers, 120s timeout) |
| igny8_frontend | Web UI | 8021:5173 | Vite dev server (React ^19, Node 18) |
| igny8_marketing_dev | Marketing site | 8023:5174 | Vite dev server |
| igny8_celery_worker | Task worker | — | Celery (concurrency=4) |
| igny8_celery_beat | Task scheduler | — | Celery Beat |
| igny8_flower | Celery monitor | 5555:5555 | Flower |
**Shared infra containers (external to app compose, on igny8_net):**
| Container | Service | Port (Internal) | Technology |
|-----------|---------|----------------|------------|
| igny8_backend | REST API | 8010 | Django 4.2 + Gunicorn (4 workers, 120s timeout) |
| igny8_frontend | Web UI | 5173 → 8021 | Vite dev server |
| igny8_celery_worker | Task worker | N/A | Celery |
| igny8_celery_beat | Task scheduler | N/A | Celery Beat |
| igny8_postgres | Database | 5432 | PostgreSQL 16 |
| igny8_redis | Cache/Broker | 6379 | Redis 7 (DB 0) |
| postgres | Database | 5432 | PostgreSQL (version set by infra stack) |
| redis | Cache/Broker | 6379 | Redis (DB 0 for production) |
| caddy | Reverse proxy/SSL | 80, 443 | Caddy 2 |
| marketing | Render service | 8023 | Custom service |
| sites | Render service | 8024 | Custom service |
| portainer | Docker management | 9000 | Portainer CE |
| pgadmin | DB admin | 5050 | PgAdmin 4 |
| filebrowser | File management | 8080 | FileBrowser |
#### Database
- **Database Name:** igny8_db
@@ -61,7 +73,7 @@
- CELERY_BROKER_URL
- Django DEBUG, ALLOWED_HOSTS
**Important:** AI integration keys stored in database (GlobalIntegrationSettings table), NOT in env vars.
**Important:** AI integration keys stored in database (`IntegrationProvider` table: `igny8_integration_providers`, and `IntegrationSettings` table: `igny8_integration_settings`), NOT in env vars.
#### Networking
- **Primary Domain:** app.igny8.com (frontend)
@@ -77,9 +89,11 @@
- **Backup Automation:** Cron jobs on old VPS (backup-db.sh, backup-full.sh)
#### Health Check
- **Endpoint:** http://localhost:8010/api/v1/system/status/
- **Expected Response:** 200 OK with system status JSON
- **Endpoint:** http://localhost:8010/api/v1/system/status/ (inside container) or http://localhost:8011/api/v1/system/status/ (from host)
- **Expected Response:** 200 OK with system status JSON (timestamp, system resources, database, Redis, Celery status)
- **Permission:** AllowAny (public endpoint)
- **Frequency:** Manual or via monitoring
- **Docker healthcheck:** Configured in compose: 30s interval, 10s timeout, 3 retries
---
@@ -167,30 +181,60 @@ This migration is **not a direct cutover**. Instead, we run both VPS in parallel
The database schema itself does not change during migration. We use pg_dump and pg_restore to move the entire database from old VPS (PG 16) to new VPS (PG 18).
**Key Tables (not exhaustive):**
- `users` — User accounts
- `projects` — Projects/sites
- `stripe_subscriptions` — Payment records
- `integration_settings` — AI integration keys (GlobalIntegrationSettings)
- `wordpress_sync_logs` — Plugin sync history
- `celery_*` — Celery task tables
**Key Tables (verified from codebase — all use `igny8_` prefix convention):**
| Table | Purpose |
|-------|---------|
| `igny8_users` | User accounts (AUTH_USER_MODEL) |
| `igny8_tenants` | Multi-tenant accounts |
| `igny8_sites` | Sites within accounts |
| `igny8_subscriptions` | Subscription records |
| `igny8_plans` | Plan definitions |
| `igny8_content` | Content items |
| `igny8_tasks` | Writer tasks |
| `igny8_clusters` | Keyword clusters |
| `igny8_keywords` | Keywords |
| `igny8_content_ideas` | Content ideas |
| `igny8_images` | Generated images |
| `igny8_invoices` | Billing invoices |
| `igny8_payments` | Payment records |
| `igny8_webhook_events` | Stripe/PayPal webhooks |
| `igny8_site_integrations` | WordPress site connections |
| `igny8_sync_events` | WordPress sync history |
| `igny8_publishing_records` | Publish records |
| `igny8_ai_task_logs` | AI task audit trail |
| `igny8_automation_configs` | Automation settings |
| `igny8_automation_runs` | Automation run history |
| `plugins` / `plugin_versions` / `plugin_installations` / `plugin_downloads` | Plugin system |
| `igny8_integration_providers` / `igny8_integration_settings` | AI/payment provider keys |
**Note:** There is NO `stripe_subscriptions` table, NO `wordpress_sync_logs` table, NO `GlobalIntegrationSettings` table. These were errors in earlier doc versions.
**Important:** Do NOT manually migrate tables. Use pg_dump/pg_restore with custom format.
### 3.2 Health Check API
**Endpoint:** `GET http://localhost:8010/api/v1/system/status/`
**Expected Response:**
**Endpoint:** `GET /api/v1/system/status/` (AllowAny — no auth required)
**Actual response format** (verified from `igny8_core/modules/system/views.py:system_status`):
```json
{
"status": "ok",
"version": "1.8.4",
"database": "connected",
"redis": "connected",
"celery": "ok"
"timestamp": "2026-03-23T12:00:00.000000+00:00",
"system": {
"cpu": {"usage_percent": 12.5, "cores": 4, "status": "healthy"},
"memory": {"total_gb": 8.0, "used_gb": 3.2, "available_gb": 4.8, "usage_percent": 40.0, "status": "healthy"},
"disk": {"total_gb": 100.0, "used_gb": 35.0, "free_gb": 65.0, "usage_percent": 35.0, "status": "healthy"}
},
"database": {"connected": true, "version": "PostgreSQL 16.x ...", "size": "256 MB", "active_connections": 5, "status": "healthy"},
"redis": {"connected": true, "status": "healthy", "info": {}},
"celery": {"workers": ["celery@igny8_celery_worker"], "worker_count": 1, "tasks": {"active": 0, "scheduled": 0, "reserved": 0}, "status": "healthy"},
"processes": {},
"modules": {}
}
```
**Healthy indicators:** All `status` fields should be `"healthy"`, `database.connected` and `redis.connected` should be `true`, `celery.worker_count` should be ≥ 1.
Use this endpoint to verify both old and new VPS health before/after migration.
---
@@ -222,11 +266,11 @@ git checkout main # or appropriate branch
cp .env.example .env
# Update .env for new VPS:
# - DB_HOST=igny8_postgres (Docker internal hostname)
# - DB_HOST=postgres (Docker service name on igny8_net — infra container, not app container)
# - DB_NAME=igny8_db
# - DB_USER=igny8
# - DB_PASSWORD=<secure password>
# - REDIS_HOST=igny8_redis
# - REDIS_URL=redis://redis:6379/0 (Redis is also an infra container on igny8_net)
# - SECRET_KEY=<generate new>
# - ALLOWED_HOSTS=test-app.igny8.com,test-api.igny8.com,app.igny8.com,api.igny8.com,igny8.com
@@ -282,7 +326,7 @@ PGPASSWORD=<db-password> pg_restore --format=custom \
/tmp/igny8_db_backup.dump
# Verify restore completed
PGPASSWORD=<db-password> psql --host=localhost --username=igny8 --dbname=igny8_db -c "SELECT COUNT(*) FROM users;"
PGPASSWORD=<db-password> psql --host=localhost --username=igny8 --dbname=igny8_db -c "SELECT COUNT(*) FROM igny8_users;"
# Run ANALYZE on all tables to update statistics
PGPASSWORD=<db-password> psql --host=localhost --username=igny8 --dbname=igny8_db -c "ANALYZE;"
@@ -315,16 +359,15 @@ On new VPS:
```bash
cd /data/app/igny8
# Copy docker-compose file (create if needed)
# Ensure it contains:
# - igny8_backend (Django)
# - igny8_frontend (Vite)
# - igny8_celery_worker
# - igny8_celery_beat
# - igny8_postgres (PostgreSQL 18)
# - igny8_redis
# - caddy
# - marketing, sites (if needed)
# docker-compose.app.yml should contain these app containers:
# - igny8_backend (Django + Gunicorn)
# - igny8_frontend (Vite/React)
# - igny8_marketing_dev (Vite marketing site)
# - igny8_celery_worker (Celery)
# - igny8_celery_beat (Celery Beat)
# - igny8_flower (Flower monitor)
# NOTE: postgres, redis, caddy are INFRA containers — NOT in app compose.
# They must already be running on igny8_net (provisioned in 00B).
# Build and start
docker compose -f docker-compose.app.yml build
@@ -355,22 +398,14 @@ curl -I https://test-api.igny8.com
#### Step 1.7: Run Health Checks on Test Subdomains
```bash
# Health check via test API subdomain
curl -H "Host: test-api.igny8.com" http://localhost:8010/api/v1/system/status/
# Health check via test API subdomain (port 8011 is the host-mapped backend port)
curl -H "Host: test-api.igny8.com" http://localhost:8011/api/v1/system/status/
# Or if DNS is live
curl https://test-api.igny8.com/api/v1/system/status/
```
**Expected Response:**
```json
{
"status": "ok",
"version": "1.8.4",
"database": "connected",
"redis": "connected",
"celery": "ok"
}
**Verify response:** `database.connected` = true, `redis.connected` = true, `celery.worker_count` ≥ 1, all `status` fields = "healthy". See Section 3.2 for full response format.
```
#### Step 1.8: Manual Testing on Test Subdomains