Choose the best runtime from the options below based on the user's request, then generate code following that runtime's rules.
Selection guide: static pages or games → static, Python scripts → python, Node-based tools → node, PHP forms → php.
Deploy environment constraints
ChatGPT, Claude, and Gemini chat interfaces restrict outbound HTTP requests, so POST /deploy cannot be executed from those environments. Generate code only and let the user upload the ZIP via Console.
AI tools with local execution environments such as Codex and Claude Code can deploy directly using an API key.
Static HTML / CSS / JavaScript
Required files
- index.html
- style.css
- script.js
Rules
- The current runtime image is based on python:3.12-alpine
- Keep explanations minimal and return the app file by file
- Do not depend on external CDNs or build tools
- Make sure index.html can live at the ZIP root
- Blue treats startup as successful when it can open a localhost TCP connection to the assigned port. No specific HTTP body or status code is required
- Prefer a one-page app with visible motion or interaction
- Do not assume persistent writable storage for the static runtime. Package images and assets inside the ZIP
Output contract
FILE: index.html
```html
...
```
FILE: style.css
```css
...
```
FILE: script.js
```javascript
...
```
Python app.py + requirements.txt
Rules
- The current runtime image is based on python:3.12-slim
- Use app.py as the entry file
- Include requirements.txt
- Listen on the PORT environment variable
- Blue treats startup as successful when it can open a localhost TCP connection to the assigned port. No specific HTTP body or status code is required
- Treat the container root filesystem as ephemeral. Put SQLite databases and other app data under /workspace/data (files inside /workspace/code may be accessible over HTTP)
- Prefer a small Flask app or a standard-library-only app for the first pass
Output contract
FILE: app.py
```python
...
```
FILE: requirements.txt
```text
...
```
Node package.json + server.js
Rules
- The current runtime image is based on node:22-bookworm-slim
- Include a start script in package.json
- Make server.js listen on the PORT environment variable
- Blue treats startup as successful when it can open a localhost TCP connection to the assigned port. No specific HTTP body or status code is required
- Treat the container root filesystem as ephemeral. Put SQLite databases and other app data under /workspace/data (files inside /workspace/code may be accessible over HTTP)
- Start small, but it is fine to use Express or similar libraries when the app needs them
- Do not assume node_modules is bundled in the ZIP
Output contract
FILE: package.json
```json
...
```
FILE: server.js
```javascript
...
```
PHP index.php
Required files
- index.php
- Optional style.css
Rules
- The current runtime image is based on php:8.3-cli
- Put index.php at the root or in public/
- Blue treats startup as successful when it can open a localhost TCP connection to the assigned port. No specific HTTP body or status code is required
- Treat the container root filesystem as ephemeral. Put SQLite databases and other app data under /workspace/data (files inside /workspace/code may be accessible over HTTP)
- Prefer a small, readable app centered on one main file
- Avoid frameworks and composer for the first pass
- Make sessions or form submission visible in the UI when relevant
Output contract
FILE: index.php
```php
...
```
FILE: style.css
```css
...
```
Deploy API
If you have an API key, deploy the ZIP directly. Otherwise the user uploads via Console.
curl -X POST https://blue.sola.inc/deploy \
-H "X-API-Key: sk_xxxxx" \
-F "name=my-app" \
-F "file=@app.zip"
Response example
{
"app_id": "app-xxxxx",
"state": "RUNNING",
"url": "https://app-xxxxx.blue.sola.inc",
"runtime": "python",
"visibility": "password_casual",
"generated_password": "Ab3x",
"failed_step": null,
"reason": null,
"next_action": null,
"logs": ["app started on port 40001"]
}
Log retrieval
If startup fails: GET https://blue.sola.inc/apps/{app_id}/logs to fetch logs, then fix and redeploy using the same app_id.
Redeploy (update an existing app) — IMPORTANT
When a deploy fails or you need to fix code, always redeploy to the same app_id. Do NOT create a new app.
curl -X POST https://blue.sola.inc/deploy \
-H "X-API-Key: sk_xxxxx" \
-F "name=my-app" \
-F "app_id=app-001" \
-F "file=@app.zip"
When app_id is specified, the existing app is stopped → redeployed with new code → published at the same URL. The app_id is included in the initial deploy response.
Always save the app_id from the initial deploy response and reuse it for all subsequent deploys.
Error handling
When a deploy fails, check these fields in the response:
- failed_step: Which step failed (upload / security_scan / detect / start / proxy_register)
- reason: Error cause (e.g. "healthcheck timeout")
- next_action: Recommended next step
- logs: Container startup logs (error details appear here)
Log retrieval: GET https://blue.sola.inc/apps/{app_id}/logs
Important guidelines:
- Do NOT create a new app — always redeploy to the same app_id
- Read the logs before retrying — check logs in the response or GET /apps/{app_id}/logs to identify the error before fixing the code
- Runtime changes are fine when justified — switching to a better-suited runtime is OK, but the same error rarely goes away just by switching runtimes. Fix the code first based on the logs
Common failure causes:
- healthcheck timeout: App is not listening on the port specified by PORT env var
- detect failure: Required entry file (index.html, app.py, package.json, index.php) not at ZIP root
- Dependency install failure: Non-existent packages in requirements.txt or package.json
Resource limits
- Memory: 128MB–512MB depending on plan (process killed if exceeded)
- Startup timeout: App must start listening within 10 seconds
- Disk: Code 20–400MB, Data 40–800MB (varies by plan)
- CPU: 0.25–1.0 cores (varies by plan)
Heavy frameworks and many dependencies can cause startup timeouts or memory limits. Start with minimal dependencies.
Security scanning
An automatic security scan runs on every deploy.
- Blocked (deploy rejected): Reverse shells, system file access (/etc/passwd etc.), crypto miners, environment variable exfiltration patterns
- Warning (deploy continues): eval() and dynamic code execution, file write operations, hostname or memory probing
If malware or malicious code is detected, the deploy may be blocked. Remove the flagged code and redeploy.
Detections inside dependency directories (node_modules, vendor, .venv) are downgraded to "info" level and will not block deployment.
File handling
- .env files: .env, .env.local etc. are not publicly accessible. However, a warning is shown during deploy. Avoid including secrets.
- DB files: .db, .sqlite etc. trigger a deploy warning. Use /workspace/data for persistent data.
- Auto-cleanup: .git, __MACOSX, __pycache__, .DS_Store and similar junk files are automatically removed on extraction.
- Flattening: If the ZIP contains a single root folder, it is automatically flattened (e.g. my-app/index.html → index.html).
Common rules
Blue checks startup by TCP connection to the assigned port. No specific HTTP response is required.
The container root filesystem is ephemeral. Persist data under /workspace/data.
Default visibility is password_casual (password required to view). The deploy response includes a generated_password — share it with the user.
Automatic runtime detection: You do not need to specify a runtime. Blue automatically detects the best runtime from uploaded files (index.html → static, app.py → python, package.json → node, index.php → php).
App naming: Use lowercase letters, digits, and hyphens for the name parameter (e.g. my-todo-app). Spaces and non-ASCII characters are automatically converted to hyphens.