Custom Dockerfile Runtime Deployment (F2.5)
Feature: F2.5 — Custom Dockerfile Deployment
Status: Completed
Package: System Layer (build_manager.py,docker_manager.py,docker.yml), Fastify API (modules/dockerfile,modules/build), Dashboard (components/projects/DockerfilePanel), Shared (schemas/dockerfile)
1. Overview
Vexlyx enables developers to deploy custom containerized applications using an explicit Dockerfile and optional .dockerignore, offering maximum flexibility for bespoke stacks, multi-stage pipelines, and custom base images (Alpine, Debian, Scratch, Ubuntu, etc.).
Key capabilities include:
- Priority Detection: If a project contains a
Dockerfile(or is created as typeDOCKER), Vexlyx automatically prioritizes nativedocker buildover standard buildpack heuristics. - Native
docker buildPipeline: Executesdocker build --progress=plain -t <imageName> -f Dockerfile .with live step-by-step log streaming via WebSockets. - Build-time Argument Injection: Injects all project environment variables automatically as
--build-arg KEY=VAL. - Automatic
.dockerignoreSupport: Placed directly in the project directory so Docker excludes sensitive or unneeded build artifacts (node_modules,.git,.env). - Smart Directive Parsing: Automatically parses
FROM,EXPOSEport(s),HEALTHCHECK, andENTRYPOINT/CMDfrom the Dockerfile. - Port Auto-Wiring: Uses the first exposed port (e.g.
8080,3000,80) to configure Traefik reverse proxy routing and container ports. - Interactive Code Editor: High-contrast, monospace editor with line numbers, template insertion, and file upload capabilities in the dashboard.
- Pre-configured Starter Presets: 1-click starter templates for Node.js (Multi-stage), Python (FastAPI / Uvicorn), Go (Alpine Minimal), Rust (Slim Binary), Static Website / SPA (Nginx), Bun, and PHP 8.3.
2. Architecture & Execution Flow
┌─────────────────────────────────────────────────────────────┐
│ Git Repository or Dashboard Dockerfile Editor / Upload │
└────────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Framework Detection & Directive Inspection │
│ (`build_manager.py plan` / `dockerfile-get`) │
│ - Checks for Dockerfile, dockerfile, Dockerfile.prod │
│ - Extracts `FROM <base_image>` │
│ - Extracts `EXPOSE <port>` (e.g. 8080, 3000/tcp) │
│ - Extracts `HEALTHCHECK` directive │
└────────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Native Docker Build Phase (`build_manager.py build`) │
│ - Command: `docker build --progress=plain -t <img_name> .` │
│ - Build args: `--build-arg KEY=VAL` from environment vars │
│ - Build context: Full project root with `.dockerignore` │
│ - Streams step logs line-by-line via Socket.io to panel │
└────────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Container Orchestration (`docker_manager.py deploy`) │
│ - Template: `system/templates/docker-compose/docker.yml` │
│ - Target port: Auto-detected EXPOSE port (or user override)│
│ - Traefik Router & Service load balancer configured │
│ - Health check probe enabled on container network │
└─────────────────────────────────────────────────────────────┘3. System Layer Details
1. Directive Parsing (parse_dockerfile_info)
Located in system/python/build_manager.py:
FROM: Resolves base image for inspection in the dashboard.EXPOSE: Handles single or multiple space-delimited ports, including protocol notations (e.g.EXPOSE 80/tcp 443/tcp 3000->[80, 443, 3000]).HEALTHCHECK: Extracts custom container health checks.ENTRYPOINT&CMD: Identifies runtime process instructions.
2. Native docker build Execution
When find_dockerfile(project_path) resolves a Dockerfile:
docker buildis executed with--progress=plainfor clean, unbuffered logging.- Build-time environment variables are mapped to
--build-arg. - Standard output and error streams are captured, parsed, and pushed to
log_line(...). - Successful build signals
{"done": true, "imageName": image_name}.
3. Dockerfile CRUD Commands
dockerfile-get:json{ "command": "dockerfile-get", "projectDir": "/var/vexlyx/projects/<id>" }Returns
{ success, hasDockerfile, hasDockerignore, dockerfile, dockerignore, exposedPorts, healthCheck, baseImage }.dockerfile-save:json{ "command": "dockerfile-save", "projectDir": "/var/vexlyx/projects/<id>", "dockerfile": "...", "dockerignore": "..." }Safely writes files to disk, parses directives, and returns status metadata.
4. Docker Compose Template (docker.yml)
Located at system/templates/docker-compose/docker.yml:
name: "vexlyx-{{service_name}}"
services:
app:
image: "{{image_name}}"
restart: unless-stopped
environment:
PORT: "{{container_port}}"
HOST: "0.0.0.0"
{{env_block}}
ports:
- "{{host_port}}:{{container_port}}"
deploy:
resources:
limits:
memory: "{{memory_limit}}"
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:{{container_port}}/health || wget -qO- http://localhost:{{container_port}}/ || curl -fs http://localhost:{{container_port}}/ || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
labels:
- "traefik.enable=true"
- "traefik.http.routers.{{service_name}}.rule=Host(`{{hostname}}`)"
- "traefik.http.routers.{{service_name}}.entrypoints=web"
- "traefik.http.services.{{service_name}}.loadbalancer.server.port={{container_port}}"
networks:
default:
external: true
name: traefik-net4. API Endpoints
All endpoints are authenticated with session cookies (app.requireAuth):
1. GET /api/projects/:id/dockerfile
Returns current Dockerfile, .dockerignore, and parsed metadata:
{
"hasDockerfile": true,
"hasDockerignore": true,
"filename": "Dockerfile",
"dockerfile": "FROM node:20-alpine\nWORKDIR /app\n...",
"dockerignore": "node_modules\n.git\n.env\n",
"exposedPorts": [3000],
"healthCheck": null,
"baseImage": "node:20-alpine",
"entrypoint": null,
"cmd": "[\"npm\", \"start\"]"
}2. PUT /api/projects/:id/dockerfile
Saves or updates Dockerfile and .dockerignore content, auto-updating the project's internal port if syncPort is requested:
{
"dockerfile": "FROM python:3.11-slim\nWORKDIR /app\nEXPOSE 8080\n...",
"dockerignore": ".venv\n__pycache__\n",
"syncPort": true,
"port": 8080
}3. GET /api/projects/:id/dockerfile/templates
Returns the catalog of 7 production-grade starter templates (Node.js, Python FastAPI, Go, Rust, Nginx SPA, Bun, PHP 8.3).
5. Dashboard User Interface
The DockerfilePanel (components/projects/DockerfilePanel.tsx) provides:
- Interactive Tabs: Seamless switching between
Dockerfileand.dockerignore. - Monospace Code Editor: Dark theme code editor with dynamic line numbers and character counters.
- Template Selector: Dropdown to insert pre-configured templates with one click.
- File Upload: Direct file picker for uploading existing
Dockerfileor.dockerignorefiles. - Directive Banner: Displays detected Base Image, Exposed Port(s), and Health Check status.
- Container Port Field: Real-time port configuration synced with Traefik routing.
- Save & Quick Deploy: Trigger immediate build execution with live terminal log streaming.
6. How to Test
Run the automated test suite:
# Custom Dockerfile runtime tests
python tests/test_dockerfile_runtime.py
# Multi-project isolation verification
python tests/test_multi_project_isolation.py
# Full monorepo verification
pnpm typecheck
pnpm lint
pnpm build