20 KiB
Sites & Site Builder Removal Guide
Version: 1.0
Date: November 29, 2025
Purpose: Complete guide to remove separate sites/site-builder containers and integrate functionality into main frontend app
Executive Summary
This document provides a safe, step-by-step process to:
- Remove the
/sites/container and folder - Remove the
/site-builder/folder (already empty/deprecated) - Integrate Sites Renderer and Site Builder features into the main
/frontend/application - Update all affected components, configurations, and documentation
Current State:
- 3 separate containers:
igny8_frontend,igny8_sites,igny8_marketing_dev - Site Builder UI in separate
/sites/container (port 8024) - Sites Renderer in separate
/sites/container (port 8024)
Target State:
- 2 containers:
igny8_frontend,igny8_marketing_dev - Site Builder UI integrated into main frontend
- Sites Renderer integrated into main frontend
- Single unified application on port 8021
Impact Analysis
Features That Will Be Affected
1. Site Blueprint Management (Site Builder)
Current Location: /sites/src/builder/
Current Routes: /builder/* (separate container)
Functionality:
- Site structure wizard
- Blueprint creation and management
- Preview canvas for site layouts
- Blueprint history dashboard
Backend Dependencies:
- API:
/api/v1/site-builder/blueprints/ - Module:
backend/igny8_core/modules/site_builder/ - Business Logic:
backend/igny8_core/business/site_building/
Impact: Medium - Needs route integration into main app
2. Sites Renderer (Public Site Viewing)
Current Location: /sites/src/pages/SiteRenderer.tsx
Current Routes: /:siteSlug/:pageSlug? (separate container)
Functionality:
- Loads site definitions from
/data/app/sites-data/ - Renders published sites for public viewing
- No authentication required
Backend Dependencies:
- API:
/api/v1/publisher/sites/{site_id}/definition/ - Service:
backend/igny8_core/business/publishing/services/adapters/sites_renderer_adapter.py - Data:
/data/app/sites-data/clients/{site_id}/v{version}/
Impact: High - Public-facing feature, needs careful route handling
3. Backend Modules (Keep These)
Modules to Keep:
backend/igny8_core/
├── modules/
│ ├── site_builder/ ✅ KEEP (API endpoints)
│ └── publisher/ ✅ KEEP (publishing logic)
└── business/
├── site_building/ ✅ KEEP (business logic)
└── publishing/ ✅ KEEP (renderer adapter)
Rationale: Backend functionality is used by the main frontend app, just changing the UI container.
Removal & Integration Plan
Phase 1: Preparation & Backup
Step 1.1: Create Backup
# Backup current state
cd /data/app/igny8
tar -czf backup-sites-$(date +%Y%m%d-%H%M%S).tar.gz sites/ site-builder/
# Backup docker-compose
cp docker-compose.app.yml docker-compose.app.yml.backup
# Verify backup
ls -lh backup-sites-*.tar.gz
Step 1.2: Document Current Routes
# Document current running containers
docker ps | grep igny8 > current-containers.txt
# Test current site builder access
curl -I http://localhost:8024/builder/
# Test current sites renderer
curl -I http://localhost:8024/
Phase 2: Frontend Integration
Step 2.1: Copy Site Builder Components to Frontend
Source: /sites/src/builder/
Destination: /frontend/src/pages/Sites/
cd /data/app/igny8
# Create target directory
mkdir -p frontend/src/pages/Sites/Builder
# Copy builder components
cp -r sites/src/builder/pages/* frontend/src/pages/Sites/Builder/
cp -r sites/src/builder/components/* frontend/src/components/sites/builder/
# Copy shared types if needed
cp sites/src/types/index.ts frontend/src/types/siteBuilder.types.ts
Files to Copy:
sites/src/builder/
├── pages/
│ ├── wizard/
│ │ └── WizardPage.tsx → frontend/src/pages/Sites/Builder/Wizard.tsx
│ ├── preview/
│ │ └── PreviewCanvas.tsx → frontend/src/pages/Sites/Builder/Preview.tsx
│ └── dashboard/
│ └── SiteDashboard.tsx → frontend/src/pages/Sites/Builder/Dashboard.tsx
└── components/
└── layout/
└── BuilderLayout.tsx → frontend/src/components/sites/BuilderLayout.tsx
Step 2.2: Copy Sites Renderer to Frontend
Source: /sites/src/pages/SiteRenderer.tsx
Destination: /frontend/src/pages/Sites/
# Copy renderer components
cp sites/src/pages/SiteRenderer.tsx frontend/src/pages/Sites/PublicSiteRenderer.tsx
cp sites/src/loaders/loadSiteDefinition.ts frontend/src/services/siteRenderer.api.ts
cp -r sites/src/utils/* frontend/src/utils/siteRenderer/
Files to Copy:
sites/src/
├── pages/
│ └── SiteRenderer.tsx → frontend/src/pages/Sites/PublicSiteRenderer.tsx
├── loaders/
│ └── loadSiteDefinition.ts → frontend/src/services/siteRenderer.api.ts
└── utils/
├── layoutRenderer.tsx → frontend/src/utils/siteRenderer/layoutRenderer.tsx
├── pageTypeRenderer.tsx → frontend/src/utils/siteRenderer/pageTypeRenderer.tsx
└── templateEngine.tsx → frontend/src/utils/siteRenderer/templateEngine.tsx
Step 2.3: Update Frontend Routes
File: /frontend/src/App.tsx
Add these imports:
// Site Builder pages
const SiteBuilderWizard = lazy(() => import("./pages/Sites/Builder/Wizard"));
const SiteBuilderPreview = lazy(() => import("./pages/Sites/Builder/Preview"));
const SiteBuilderDashboard = lazy(() => import("./pages/Sites/Builder/Dashboard"));
// Public Sites Renderer
const PublicSiteRenderer = lazy(() => import("./pages/Sites/PublicSiteRenderer"));
Add these routes:
{/* Site Builder Routes - Protected */}
<Route
path="/sites/builder"
element={
<ProtectedRoute>
<ModuleGuard module="site_builder">
<SiteBuilderWizard />
</ModuleGuard>
</ProtectedRoute>
}
/>
<Route
path="/sites/builder/preview"
element={
<ProtectedRoute>
<ModuleGuard module="site_builder">
<SiteBuilderPreview />
</ModuleGuard>
</ProtectedRoute>
}
/>
<Route
path="/sites/builder/dashboard"
element={
<ProtectedRoute>
<ModuleGuard module="site_builder">
<SiteBuilderDashboard />
</ModuleGuard>
</ProtectedRoute>
}
/>
{/* Public Sites Renderer - No Auth Required */}
<Route path="/sites/view/:siteSlug/:pageSlug?" element={<PublicSiteRenderer />} />
Note: Public renderer routes changed from /:siteSlug/* to /sites/view/:siteSlug/* to avoid route conflicts.
Step 2.4: Update API Client for Sites Data
File: /frontend/src/services/siteRenderer.api.ts
Update the API URL resolution:
function getApiBaseUrl(): string {
// Use environment variable
const envUrl = import.meta.env.VITE_API_URL || import.meta.env.VITE_BACKEND_URL;
if (envUrl) {
return envUrl.endsWith('/api') ? envUrl : `${envUrl}/api`;
}
// Auto-detect based on current origin
if (typeof window !== 'undefined') {
const origin = window.location.origin;
// If accessing via IP, use backend port 8011
if (/^\d+\.\d+\.\d+\.\d+/.test(origin) || origin.includes('localhost')) {
return origin.replace(':8021', ':8011') + '/api';
}
}
// Production: use subdomain
return 'https://api.igny8.com/api';
}
Step 2.5: Update Navigation Menu
File: /frontend/src/components/sidebar/AppSidebar.tsx or navigation component
Add Site Builder menu item:
{
title: "Site Builder",
icon: <LayoutGrid className="h-5 w-5" />,
items: [
{ title: "New Blueprint", path: "/sites/builder" },
{ title: "Preview", path: "/sites/builder/preview" },
{ title: "History", path: "/sites/builder/dashboard" },
],
}
Phase 3: Docker Configuration Updates
Step 3.1: Update docker-compose.app.yml
File: /docker-compose.app.yml
Remove the igny8_sites service:
# REMOVE THIS ENTIRE SERVICE:
# igny8_sites:
# image: igny8-sites-dev:latest
# container_name: igny8_sites
# restart: always
# ports:
# - "0.0.0.0:8024:5176"
# environment:
# VITE_API_URL: "https://api.igny8.com/api"
# SITES_DATA_PATH: "/sites"
# volumes:
# - /data/app/igny8/sites:/app:rw
# - /data/app/sites-data:/sites:ro
# - /data/app/igny8/frontend:/frontend:ro
# networks: [igny8_net]
Update igny8_frontend service to access sites-data:
igny8_frontend:
image: igny8-frontend-dev:latest
container_name: igny8_frontend
restart: always
ports:
- "0.0.0.0:8021:5173"
environment:
VITE_BACKEND_URL: "https://api.igny8.com/api"
SITES_DATA_PATH: "/sites" # ADD THIS
volumes:
- /data/app/igny8/frontend:/app:rw
- /data/app/sites-data:/sites:ro # ADD THIS - Read-only access to sites data
depends_on:
igny8_backend:
condition: service_healthy
networks: [igny8_net]
Step 3.2: Update Vite Configuration
File: /frontend/vite.config.ts
Add environment variable for sites data path:
export default defineConfig({
// ... existing config
define: {
'import.meta.env.SITES_DATA_PATH': JSON.stringify(
process.env.SITES_DATA_PATH || '/sites'
),
},
// ... rest of config
});
Phase 4: Backend Updates (Minor)
Step 4.1: Update CORS Settings (if needed)
File: /backend/igny8_core/settings.py
Verify CORS allows frontend port:
CORS_ALLOWED_ORIGINS = [
'http://localhost:5173', # Frontend dev server
'http://localhost:8021', # Frontend external port
'https://app.igny8.com',
# Remove: 'http://localhost:8024', # Old sites container
]
Step 4.2: Update Site Definition API (Optional Enhancement)
File: /backend/igny8_core/modules/publisher/views.py
No changes required - API already works, just being called from different container.
Optional: Add CORS header for public site renderer if needed:
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
@api_view(['GET'])
@permission_classes([AllowAny]) # Public endpoint
def get_site_definition(request, site_id):
# ... existing code
Phase 5: Testing & Verification
Step 5.1: Build Updated Frontend
cd /data/app/igny8/frontend
# Install any new dependencies (if added)
npm install
# Build to verify no errors
npm run build
# Rebuild Docker image
cd /data/app/igny8/frontend
docker build -t igny8-frontend-dev:latest -f Dockerfile.dev .
Step 5.2: Stop Old Container
# Stop and remove sites container
docker stop igny8_sites
docker rm igny8_sites
# Verify it's stopped
docker ps | grep sites
Step 5.3: Start Updated Stack
cd /data/app/igny8
# Start with updated docker-compose
docker compose -f docker-compose.app.yml up -d igny8_frontend
# Check logs
docker logs -f igny8_frontend
Step 5.4: Test Functionality
Test Site Builder:
# Test builder routes (should require auth)
curl -I http://localhost:8021/sites/builder
# Test in browser:
# http://localhost:8021/sites/builder (wizard)
# http://localhost:8021/sites/builder/preview
# http://localhost:8021/sites/builder/dashboard
Test Sites Renderer:
# Test public site renderer
curl -I http://localhost:8021/sites/view/test-site
# Test in browser:
# http://localhost:8021/sites/view/{siteSlug}
# http://localhost:8021/sites/view/{siteSlug}/{pageSlug}
Test Existing API:
# Verify site builder API still works
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://localhost:8011/api/v1/site-builder/blueprints/
# Verify site definition API
curl http://localhost:8011/api/v1/publisher/sites/1/definition/
Phase 6: Cleanup
Step 6.1: Remove Folders (After Verification)
Only after confirming everything works:
cd /data/app/igny8
# Remove sites folder
rm -rf sites/
# Remove site-builder folder (already empty)
rm -rf site-builder/
# Remove empty frontend module
rm -rf frontend/src/modules/siteBuilder/
# Verify removal
ls -la | grep -E "site-builder|sites"
Step 6.2: Remove Docker Image (Optional)
# Remove unused sites image
docker rmi igny8-sites-dev:latest
# Verify
docker images | grep sites
Step 6.3: Clean Up Build Instructions
File: /docker-compose.app.yml (comments at top)
Remove this line:
# Remove:
# cd /data/app/igny8/sites && docker build -t igny8-sites-dev:latest -f Dockerfile.dev .
Phase 7: Update Documentation
Step 7.1: Update Files List
Files to update:
-
README.md
- Remove references to
/sites/container - Update port mapping (remove 8024)
- Update build instructions
- Remove references to
-
CHANGELOG.md
- Add entry: "Merged Sites & Site Builder into main frontend app"
-
docs/MASTER_REFERENCE.md
- Update architecture diagram
- Remove igny8_sites container reference
- Update route documentation
-
docs/API-COMPLETE-REFERENCE.md
- Update base URLs if needed
- Verify endpoint documentation
Step 7.2: Update Architecture Diagram
In MASTER_REFERENCE.md, update:
OLD:
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Frontend (8021) │ │ Sites (8024) │ │ Backend (8011) │
└──────────────────┘ └──────────────────┘ └──────────────────┘
NEW:
┌──────────────────┐ ┌──────────────────┐
│ Frontend (8021) │ │ Backend (8011) │
│ - Main App │ │ - Django API │
│ - Site Builder │ │ - Celery │
│ - Site Renderer │ │ │
└──────────────────┘ └──────────────────┘
Files & Folders Impact Summary
Files to Modify
| File | Action | Reason |
|---|---|---|
/frontend/src/App.tsx |
UPDATE | Add site builder and renderer routes |
/frontend/src/services/siteRenderer.api.ts |
CREATE | Site renderer API client |
/frontend/src/pages/Sites/Builder/ |
CREATE | Copy from sites/src/builder/ |
/frontend/src/components/sites/builder/ |
CREATE | Builder components |
/frontend/vite.config.ts |
UPDATE | Add SITES_DATA_PATH env var |
/docker-compose.app.yml |
UPDATE | Remove igny8_sites service |
/backend/igny8_core/settings.py |
VERIFY | CORS settings (minor) |
/README.md |
UPDATE | Architecture docs |
/docs/MASTER_REFERENCE.md |
UPDATE | Remove sites container refs |
Files to Delete (After Verification)
| File/Folder | Safe to Delete | Notes |
|---|---|---|
/sites/ |
✅ YES | After copying to frontend |
/site-builder/ |
✅ YES | Already empty |
/frontend/src/modules/siteBuilder/ |
✅ YES | Empty folders |
docker-compose.app.yml.backup |
✅ YES | After successful migration |
backup-sites-*.tar.gz |
⚠️ KEEP | Keep for 30 days as rollback |
Backend Files - NO CHANGES NEEDED
These stay exactly as they are:
backend/igny8_core/
├── modules/
│ ├── site_builder/ ✅ KEEP - No changes
│ └── publisher/ ✅ KEEP - No changes
├── business/
│ ├── site_building/ ✅ KEEP - No changes
│ └── publishing/ ✅ KEEP - No changes
└── api/
└── wordpress_publishing.py ✅ KEEP - No changes
Rationale: Backend APIs remain unchanged; only the frontend UI container changes.
Rollback Plan
If issues occur, rollback is simple:
Option 1: Quick Rollback (Docker)
# Restore backup docker-compose
cp docker-compose.app.yml.backup docker-compose.app.yml
# Restart sites container
docker compose -f docker-compose.app.yml up -d igny8_sites
# Verify
docker ps | grep sites
curl -I http://localhost:8024/
Option 2: Full Rollback (Restore Files)
# Extract backup
cd /data/app/igny8
tar -xzf backup-sites-YYYYMMDD-HHMMSS.tar.gz
# Rebuild image
cd sites
docker build -t igny8-sites-dev:latest -f Dockerfile.dev .
# Restart
docker compose -f docker-compose.app.yml up -d igny8_sites
Migration Checklist
Pre-Migration:
- Backup
/sites/folder - Backup
/docker-compose.app.yml - Document current container ports
- Test current site builder functionality
- Test current sites renderer functionality
Migration Steps:
- Copy site builder components to
/frontend/src/pages/Sites/Builder/ - Copy sites renderer to
/frontend/src/pages/Sites/PublicSiteRenderer.tsx - Copy utilities to
/frontend/src/utils/siteRenderer/ - Update
/frontend/src/App.tsxwith new routes - Create
/frontend/src/services/siteRenderer.api.ts - Update
/frontend/vite.config.ts - Update
/docker-compose.app.yml(remove igny8_sites, update igny8_frontend) - Rebuild frontend Docker image
- Stop igny8_sites container
- Start updated igny8_frontend container
Testing:
- Test site builder wizard at
/sites/builder - Test site builder preview at
/sites/builder/preview - Test site builder dashboard at
/sites/builder/dashboard - Test public site renderer at
/sites/view/{siteSlug} - Verify API calls work from frontend
- Check browser console for errors
- Test with authenticated user
- Test without authentication (public renderer)
Post-Migration:
- Verify all tests pass
- Update documentation (README, MASTER_REFERENCE)
- Remove
/sites/folder - Remove
/site-builder/folder - Remove empty
/frontend/src/modules/siteBuilder/ - Remove Docker image
igny8-sites-dev:latest - Keep backup for 30 days
- Update portable package documentation
FAQ
Q: Will this break existing site blueprints?
A: No. Backend database and APIs remain unchanged. Only the UI container changes.
Q: What about published sites in /data/app/sites-data/?
A: They remain accessible. The frontend will mount /sites-data and load from there.
Q: Do I need to update WordPress integration?
A: No. WordPress talks to backend API, which doesn't change.
Q: What if I want to keep sites as separate container?
A: Keep current setup. This migration is optional for simplification.
Q: Will public site URLs change?
A: Yes, from http://localhost:8024/:siteSlug to http://localhost:8021/sites/view/:siteSlug. Update any hardcoded links.
Q: Can I run both containers during transition?
A: Yes, for testing. Run sites on 8024 and updated frontend on 8021, compare functionality.
Support & Troubleshooting
Issue: Routes not working after migration
Solution: Check route order in App.tsx. Public renderer routes should be after protected routes.
Issue: API calls failing
Solution: Verify VITE_BACKEND_URL in environment and check CORS settings.
Issue: Sites data not loading
Solution: Verify /data/app/sites-data is mounted in docker-compose frontend service.
Issue: Build errors
Solution: Run npm install to ensure dependencies match between sites and frontend.
Timeline Estimate
| Phase | Time | Complexity |
|---|---|---|
| Phase 1: Preparation | 30 min | Low |
| Phase 2: Frontend Integration | 2-3 hours | Medium |
| Phase 3: Docker Updates | 30 min | Low |
| Phase 4: Backend Updates | 15 min | Low |
| Phase 5: Testing | 1-2 hours | Medium |
| Phase 6: Cleanup | 15 min | Low |
| Phase 7: Documentation | 1 hour | Low |
| Total | 5-7 hours | Medium |
End of Document