The strongly.manifest.yaml File
The manifest file provides declarative configuration for building and deploying your application. It must be placed in your project root alongside the Dockerfile.
Basic Structure
# strongly.manifest.yaml (place in project root)
version: "1.0"
type: nodejs # react, nodejs, flask, rshiny, mcp_server, static, fullstack, custom
name: my-app
description: Brief description of your application
author: Your Name or Organization
homepage: https://github.com/yourorg/my-app
license: MIT
icon: "https://example.com/icon.png"
tags:
- api
- backend
ports:
- port: 3000
name: http
expose: true
target_port: 3000 # Optional: if different from port
env:
- name: NODE_ENV
value: "production"
required: true
- name: DATABASE_URL
value: "" # User must provide
required: true
secret: true # Stored as Kubernetes Secret
description: PostgreSQL connection string
inject_as: env # How to inject: 'env' (default), 'file', 'config'
runtime:
command: ["node", "server.js"]
working_dir: /app
health_check_path: /health
readiness_check_path: /ready # Defaults to health_check_path if not set
startup_timeout: 60 # Startup timeout in seconds
health_check:
path: /health
initial_delay: 15
period: 30
resources:
cpu_request: "100m"
memory_request: "256Mi"
cpu_limit: "500m"
memory_limit: "512Mi"
ephemeral_storage: "1Gi" # Optional: ephemeral storage limit
gpu: 1 # Optional: number of GPUs required
Application Types
The type field determines default configuration and runtime behavior:
| Type | Default Port | Use Case | Special Features |
|---|---|---|---|
react | 3000 | React/Vue SPA with client-side routing | Nginx-based serving, SPA fallback |
nodejs | 3000 | Node.js APIs, Express, NestJS | Standard Node.js runtime |
flask | 5000 | Python Flask/FastAPI applications | Python WSGI/ASGI support |
rshiny | 3838 | R Shiny interactive dashboards | R Shiny server runtime |
static | 80 | Static HTML/CSS/JS sites | Nginx static file serving |
fullstack | 3000, 8000 | Monorepo with frontend + backend | Multiple port exposure |
mcp_server | 8080 | MCP protocol tool servers | MCP-specific configurations |
custom | 8080 | Any other application type | No special defaults |
Configuration Sections
Ports
Define which ports your application listens on:
ports:
- port: 3000
name: http
expose: true # Expose externally via ingress
target_port: 3000 # Optional: target port if different from port
- port: 8080
name: metrics
expose: false # Internal only
Fields:
port: Port number (1-65535)name: Friendly name for the port (default: "http")expose: Whether to expose externally (default: true)target_port: Target port if different fromport(optional)
Environment Variables
Define runtime configuration with proper metadata:
env:
# Regular environment variable
- name: API_URL
value: "https://api.example.com"
required: false
description: Backend API endpoint
inject_as: env # How to inject: 'env' (default), 'file', 'config'
# Secret (passwords, API keys, tokens)
- name: API_KEY
value: "" # Must be provided by user
required: true
secret: true # Encrypted in Kubernetes
description: Third-party API key
# Build-time variable
- name: REACT_APP_VERSION
value: "1.0.0"
buildtime: true # Passed as Docker build arg
description: App version
Fields:
name: Variable name (uppercase with underscores)value: Default value (can be empty for required vars)required: Whether variable must have a value (default: false)secret: Store as Kubernetes Secret (default: false)buildtime: Pass to Docker build as ARG (default: false)description: User-friendly descriptioninject_as: How to inject the variable -env(default),file, orconfig
Variables marked as secret: true are stored in Kubernetes Secrets and encrypted at rest. Use this for passwords, API keys, and tokens.
React/Static App Configuration
For React and static applications, configure nginx serving:
type: react
static:
root: /app/build
index: index.html
spa: true # Fallback to index.html for client-side routing
config_file: /app/build/config.js
config_placeholder: __APP_CONFIG__
build:
args:
NODE_ENV: production
output_dir: /app/build
Static Fields:
root: Directory containing built static filesindex: Index file name (default: index.html)spa: Enable SPA routing fallback (default: true for react)config_file: Runtime config injection file pathconfig_placeholder: Placeholder to replace with config
Health Checks
Your app must expose a health endpoint for Kubernetes liveness and readiness probes:
health_check:
path: /health
port: 3000
initial_delay: 10 # Seconds before first check
period: 30 # Check every 30 seconds
timeout: 3
failure_threshold: 3
Implementation Example (Express.js):
app.get('/health', (req, res) => {
res.status(200).json({ status: 'ok' });
});
Implementation Example (Flask):
@app.route('/health')
def health():
return {'status': 'ok'}, 200
Health checks are mandatory. If your app doesn't respond to health checks, Kubernetes will continuously restart it.
Runtime Configuration
Customize the container runtime:
runtime:
command: ["node", "dist/server.js"]
working_dir: /app
health_check_path: /health
readiness_check_path: /ready # Defaults to health_check_path
startup_timeout: 60 # Startup timeout in seconds (default: 60)
user: appuser # User to run as (if not set in Dockerfile)
Fields:
command: Override container CMD (string or array format)working_dir: Working directory (default: /app)health_check_path: Health check endpoint path (default: /health)readiness_check_path: Readiness check path (defaults tohealth_check_path)startup_timeout: Startup timeout in seconds (default: 60)user: User to run as (optional)
Resource Requirements
Set CPU and memory limits to ensure stable performance:
resources:
cpu_request: "100m" # 0.1 CPU cores (default)
memory_request: "256Mi" # 256 MiB (default)
cpu_limit: "500m" # 0.5 CPU cores (default)
memory_limit: "512Mi" # 512 MiB (default)
ephemeral_storage: "1Gi" # Optional: ephemeral storage limit
gpu: 1 # Optional: number of GPUs required
Default Resource Values:
| Field | Default |
|---|---|
cpu_request | 100m |
memory_request | 256Mi |
cpu_limit | 500m |
memory_limit | 512Mi |
ephemeral_storage | not set |
gpu | not set |
Recommended Resources by App Type:
| App Type | CPU Request | Memory Request | CPU Limit | Memory Limit |
|---|---|---|---|---|
| React/Static | 50m | 128Mi | 200m | 256Mi |
| Node.js API | 100m | 256Mi | 500m | 512Mi |
| Flask API | 200m | 512Mi | 1000m | 1Gi |
| Heavy Processing | 500m | 1Gi | 2000m | 2Gi |
1000m= 1 CPU core500m= 0.5 CPU cores100m= 0.1 CPU cores
Proxy Configuration
Configure ingress proxy behavior:
proxy:
websocket: true # Enable WebSocket support
timeout: 30 # Request timeout in seconds (default: 30)
preserve_host: false # Preserve original host header
rewrite_paths: # Path rewriting rules
"/api": "/api/v1"
headers: # Additional headers to add
X-App-Version: "1.0.0"
Fields:
websocket: Enable WebSocket proxying (default: false)timeout: Proxy timeout in seconds (default: 30)preserve_host: Preserve original host header (default: false)rewrite_paths: Path rewriting rules (optional)headers: Additional headers to add (optional)
MCP Configuration
For MCP server applications (type: mcp_server):
mcp:
protocol_version: "1.0"
transport: http # 'http', 'stdio', 'sse'
capabilities:
- tools
- prompts
- resources
authentication_required: true
tools:
- name: example_tool
description: An example tool
parameters:
type: object
properties:
input:
type: string
required: [input]
prompts:
- name: analyze_data
description: Analyzes data
arguments:
- name: data_source
required: true
resources:
- uri: "mcp://data/*"
name: "Data Resource"
description: "Access to data resources"
Complete Examples
Node.js API
version: "1.0"
type: nodejs
name: user-api
description: REST API for user management
author: Acme Corp
tags: [nodejs, api, backend]
ports:
- port: 3000
name: http
expose: true
env:
- name: NODE_ENV
value: "production"
required: true
- name: DATABASE_URL
value: ""
required: true
secret: true
description: PostgreSQL connection string
- name: JWT_SECRET
value: ""
required: true
secret: true
description: Secret for JWT signing
runtime:
command: ["node", "dist/server.js"]
working_dir: /app
health_check_path: /health
health_check:
path: /health
initial_delay: 15
period: 30
proxy:
websocket: true
timeout: 30
resources:
cpu_request: "100m"
memory_request: "256Mi"
cpu_limit: "500m"
memory_limit: "512Mi"
React SPA
version: "1.0"
type: react
name: admin-dashboard
description: Admin dashboard SPA
author: Acme Corp
tags: [react, frontend]
ports:
- port: 3000
name: http
expose: true
static:
root: /app/build
index: index.html
spa: true
config_file: /app/build/config.js
config_placeholder: __APP_CONFIG__
build:
args:
NODE_ENV: production
REACT_APP_VERSION: "1.0.0"
output_dir: /app/build
env:
- name: REACT_APP_API_URL
value: "https://api.acme.com"
buildtime: true
description: Backend API endpoint
health_check:
path: /
initial_delay: 5
period: 30
resources:
cpu_request: "50m"
memory_request: "128Mi"
cpu_limit: "200m"
memory_limit: "256Mi"
Flask API
version: "1.0"
type: flask
name: ml-api
description: Machine learning inference API
author: Data Team
tags: [python, flask, ml]
ports:
- port: 5000
name: http
expose: true
env:
- name: FLASK_ENV
value: "production"
required: true
- name: MODEL_PATH
value: "/app/models/model.pkl"
description: Path to ML model file
- name: REDIS_URL
value: ""
required: true
secret: true
description: Redis cache connection string
runtime:
command: ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
working_dir: /app
health_check_path: /health
health_check:
path: /health
port: 5000
initial_delay: 20
period: 30
timeout: 5
resources:
cpu_request: "200m"
memory_request: "512Mi"
cpu_limit: "1000m"
memory_limit: "1Gi"
R Shiny Dashboard
version: "1.0"
type: rshiny
name: analytics-dashboard
description: Interactive R Shiny analytics dashboard
author: Data Team
tags: [rshiny, analytics, dashboard]
ports:
- port: 3838
name: http
expose: true
env:
- name: SHINY_LOG_LEVEL
value: "INFO"
description: Shiny log level
runtime:
working_dir: /app
health_check_path: /health
health_check:
path: /
initial_delay: 15
period: 30
resources:
cpu_request: "200m"
memory_request: "512Mi"
cpu_limit: "1000m"
memory_limit: "1Gi"
MCP Server
version: "1.0"
type: mcp_server
name: my-mcp-server
description: MCP server providing custom tools
author: Your Organization
homepage: https://github.com/yourorg/mcp-server
license: MIT
tags: [mcp, tools]
ports:
- port: 8080
name: http
expose: true
env:
- name: LOG_LEVEL
value: "info"
description: Logging level
runtime:
command: ["python", "server.py"]
working_dir: /app
health_check_path: /health
startup_timeout: 60
health_check:
path: /health
initial_delay: 10
period: 30
resources:
cpu_request: "100m"
memory_request: "256Mi"
cpu_limit: "500m"
memory_limit: "512Mi"
mcp:
protocol_version: "1.0"
transport: http
capabilities: [tools, prompts, resources]
authentication_required: true
tools:
- name: example_tool
description: An example tool that processes data
parameters:
type: object
properties:
input:
type: string
description: Input data to process
required: [input]
Validation
The platform validates your manifest during deployment. Common errors:
- Missing required fields: version, type
- Invalid type: Must be one of the supported types
- Invalid port: Must be 1-65535
- Invalid resource format: Must use Kubernetes format (e.g., "500m", "1Gi")
- Secret without value: Required secrets need values (or user must provide)