Laravel images no longer bake config:cache at build time, which ignored
K8s DB env vars. Add DB_CONNECTION, clear config on boot, generate APP_KEY
when missing, run migrations, and rebuild caches at container start.
Co-authored-by: Cursor <cursoragent@cursor.com>
Set Laravel DB env vars in Helm and Kubernetes, fix default port to 80 with a storage-aware entrypoint, and let users upload a .env file during deploy.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Replace port-forward/netcat PVC upload with kubectl cp for integrity
- Add build cancellation API and session cleanup; deploy catches cancel
- Default port 80 for WordPress, PHP, and Laravel on create
- Build progress modal with cancel; Helm/K8s adjustments for deployments
- Update build and kubernetes specs
Co-authored-by: Cursor <cursoragent@cursor.com>
Add admin endpoints for stack deploy/status and user-facing logs
query API. Register controllers and service in KubernetesModule.
Co-authored-by: Cursor <cursoragent@cursor.com>
Deploy and manage central Elasticsearch + Kibana via K8s API, with
health checks, credentials, and per-user log query helpers.
Co-authored-by: Cursor <cursoragent@cursor.com>
Users can assign a custom domain to their app with automatic SSL via
cert-manager. Includes DNS verification flow (CNAME check), Persian
instructions, admin-configurable pricing via PlatformSetting, and
integration into the deploy wizard cost calculation.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add helm/kubectl binaries and chart directory to backend Dockerfile
- Extend Helm templates for MongoDB/MariaDB database support (env vars, probes, ports)
- Add Redis and RabbitMQ Helm templates (deployment, service, secret, PVC)
- Add generic app-storage PVC and Fluent Bit sidecar with ES authentication
- Fix imagePullSecrets in K8s API fallback, prevent secret regeneration on redeploy
- Clean up Redis/RabbitMQ/FluentBit resources on app deletion without removing shared secrets
- Fix HelmService chartPath resolution for production Docker builds
Co-authored-by: Cursor <cursoragent@cursor.com>
- Job containers now sleep 120s after completing dump/archive
- This allows exec to retrieve files before container exits
- Wait for DUMP_DONE/ARCHIVE_DONE marker before attempting exec
- Cleanup job immediately after retrieval
- Fix Helm registry-pull-secret ownership conflict with lookup
- deployApplication now tries Helm first, falls back to direct K8s API
- Restored all private methods: ensureNamespace, applySecret, applyDeployment,
applyService, applyIngress, applyWordPressPvc, deployDatabase, createDbSecret, createPVC
- Added ManifestContext interface
- Added DATABASE_URL env var, PGDATA, health probes for DB, ingressClassName
- Add revisionHistoryLimit: 10 and change-cause annotation to K8s deployments
- Add getDeploymentRevisions() to list ReplicaSet revision history
- Add rollbackDeploymentRevision() using K8s API (instant, no rebuild)
- Refactor snapshot rollback: use K8s revision for app, keep file-based DB/wp-content restore
- Add GET /snapshots/applications/:appId/revisions endpoint
- Add POST /snapshots/applications/:appId/revisions/:rev/rollback endpoint
- Add K8sRevision and K8sRevisionData types to frontend
- Redesign UI with two tabs: K8s Revisions (instant) + File Snapshots (full backup)
- K8s Revisions tab shows deployment history with one-click instant rollback
- File Snapshots tab retains download, DB restore, and wp-content restore
- Add AppSnapshot entity with type (pre_deploy/manual), status tracking, and file paths
- Add SnapshotsService with create, capture, rollback, prune (max 10), and download logic
- Add SnapshotsController with REST endpoints for CRUD, rollback, and file downloads
- Add K8s methods: exportDatabaseDump, archiveWpContent, restoreWpContent
- Auto-create pre-deploy snapshots before each deployment for rollback safety
- Support downloading current live state (source, wp-content, database) without snapshots
- Add snapshot management UI in app detail page with create, rollback, download, delete
- Wire circular dependencies with forwardRef between Deployments and Snapshots modules
- Add dbStorageSize column to Application entity (default: 1Gi)
- Add dbStorageSize to CreateApplicationDto, frontend types
- Use dynamic storage size in K8s deployDatabase instead of hardcoded 5Gi
- Deploy page: storage size selector with +/- buttons (min 1GB, max 100GB)
- Auto-suggest storage based on DB dump file size (3x dump size, min 1GB)
- Show DB storage in Review step
- App detail: Database Storage section with expand button
- GET /applications/:id/db-storage — read current PVC size from K8s
- PATCH /applications/:id/db-storage — expand PVC (only increase, no shrink)
- PVC resize uses JSON patch on K8s API
Backend:
- Add runtimeVersion, phpVersion, dbVersion columns to Application entity
- Add version fields to CreateApplicationDto with validation
- Node.js Dockerfile: use selected version (22/20/18/16) instead of hardcoded 20
- Laravel Dockerfile: use selected PHP version (8.4/8.3/8.2/8.1) instead of 8.3
- WordPress Dockerfile: use selected WP version (6.7/6.6/6.5/6.4) + PHP version
- K8s deployDatabase(): use selected DB version instead of hardcoded postgres:16/mysql:8.0
- K8s restoreDatabaseDump(): match DB image version for restore jobs
- Add dbVersion to ManifestContext interface
Frontend:
- Add runtimeVersion, phpVersion, dbVersion to Application and CreateApplicationDto
- Deploy page: Node.js version dropdown (22/20/18/16)
- Deploy page: Laravel PHP version dropdown (8.4/8.3/8.2/8.1)
- Deploy page: WordPress version + PHP version dropdowns
- Deploy page: PostgreSQL version dropdown (17/16/15/14)
- Deploy page: MySQL version dropdown (9.0/8.4/8.0/5.7)
- Deploy page: auto-set default versions on runtime/DB selection
- Review step: show selected versions
- App detail page: display runtime + DB versions in config and header
Backend:
- Add WORDPRESS to AppRuntime enum
- Add wordpressDockerfile() using wordpress:6-php8.3-apache base image
with custom theme/plugin/wp-content merge support
- Add WordPress-specific K8s env vars (WORDPRESS_DB_HOST, WORDPRESS_DB_USER,
WORDPRESS_DB_PASSWORD, WORDPRESS_DB_NAME, WORDPRESS_TABLE_PREFIX)
- Create wp-content PersistentVolumeClaim (2Gi) for WordPress deployments
- Mount wp-content PVC in deployment container at /var/www/html/wp-content
Frontend:
- Add 'wordpress' to runtime type unions (Application, CreateApplicationDto)
- Add WordPress runtime card in deploy page (port 80, blue icon)
- Auto-select MySQL database when WordPress is chosen, disable other DB options
- Show Persian hint 'وردپرس به MySQL نیاز دارد' when WordPress selected
- Update all runtime icon colors across dashboard, apps, admin/apps pages
to show blue-600 for WordPress
Backend:
- Add dbUsername/dbPassword columns to Application entity
- Add optional DB credential fields to CreateApplicationDto
- Auto-generate dbPassword (crypto.randomBytes) and default dbUsername='appuser'
when databaseType != 'none' on app creation
- Store both username and password in K8s DB secret (was password-only)
- Read DB_USER/POSTGRES_USER/MYSQL_USER from secretKeyRef instead of hardcoded
- New restoreDatabaseDump() in KubernetesService: creates K8s Job with
psql/mysql client to restore uploaded SQL dump, waits for completion,
returns logs
- New POST /applications/:id/db-upload endpoint with 500MB file limit
Frontend:
- Add dbUsername/dbPassword to Application and CreateApplicationDto types
- Deploy page: show username/password fields when database is selected,
with generate-random-password button and show/hide toggle
- App detail page: new Database section with connection info (host, port,
db name, username, password with copy-to-clipboard), SQL dump upload
area with drag-and-drop, and restore output logs display
Security:
- Database remains ClusterIP only (no external exposure)
- Credentials stored in K8s Secrets (base64-encoded)
- Dump file uploaded as temporary K8s Secret, auto-cleaned after restore
Most user apps (e.g. Next.js) don't have a /health endpoint, causing
liveness/readiness probes to fail with 404 and crash-loop the pods.
TCP socket probes just check if the port is open, which works universally.
- Backend: getPreviewInfo() in KubernetesService auto-patches ClusterIP
service to NodePort for direct external access
- Backend: GET /applications/:id/preview endpoint returns access URL
with nodePort, host IP (extracted from kubeconfig), and ingress URL
- Frontend: '🌐 Preview' button on app detail page (visible when running)
opens the deployed app in a new browser tab via NodePort URL
- Tested: service patched to NodePort 30107 successfully
- Backend: getResourceUsage() method in KubernetesService fetches real-time
CPU/Memory metrics from K8s metrics-server API per pod
- Backend: updateResources() method patches live K8s deployments with new
CPU/Memory requests+limits and replica count
- Backend: GET /applications/:id/resources endpoint for monitoring
- Backend: PATCH /applications/:id/resources endpoint for scaling
- Backend: ScaleResourcesDto with validation for resource fields
- Frontend: Resource monitoring card with per-pod CPU/Memory progress bars
(color-coded: green < 50%, yellow < 80%, red > 80%)
- Frontend: Pod status table showing phase, readiness, restarts
- Frontend: Scaling controls for CPU request/limit, memory request/limit,
and replicas with +/- buttons
- Frontend: Auto-refresh metrics every 5 seconds when monitoring is open
- Frontend: parseCpuToMillicores/parseMemoryToMi helpers for metric parsing