Skip to main content

Deployment Requirements

Clue2App automatically detects and builds your applications. This guide covers the requirements for successful deployments.

Supported Languages​

Clue2App automatically detects and builds applications written in:

LanguageFrameworks
PythonFastAPI, Flask, Django, etc.
Node.jsExpress, Next.js, React, Vue, etc.
JavaSpring Boot, Quarkus, etc.
GoStandard library, Gin, Echo, etc.
.NET CoreASP.NET, Blazor, etc.

Project Structure​

Detection Files​

Clue2App needs specific files at the repository root to detect your application:

LanguageRequired File
Pythonrequirements.txt, pyproject.toml, or setup.py
Node.jspackage.json
Javapom.xml or build.gradle
Gogo.mod
.NET*.csproj or *.fsproj

Monorepo / Subdirectory Projects​

If your code is in a subdirectory (e.g., backend/), create wrapper files at the root:

Python Example​

my-repo/
├── requirements.txt # Points to backend
├── Procfile # Runs from backend
├── backend/
│ ├── requirements.txt # Actual dependencies
│ └── app/
│ └── main.py
└── frontend/
└── ...

Root requirements.txt:

-r backend/requirements.txt

Root Procfile:

web: cd backend && uvicorn app.main:app --host 0.0.0.0 --port 8000

Node.js Example​

my-repo/
├── package.json # Wrapper
├── Procfile # Runs from backend
├── backend/
│ ├── package.json
│ └── src/
└── frontend/
└── ...

Root package.json:

{
"name": "app-wrapper",
"scripts": {
"start": "cd backend && npm start"
}
}

Procfile​

A Procfile specifies how to run your application. It's optional for simple projects but recommended for:

  • Monorepo projects
  • Custom startup commands
  • Specific runtime configurations

Format:

web: <command to start your app>

Examples:

# Python FastAPI
web: uvicorn app.main:app --host 0.0.0.0 --port 8000

# Python Flask
web: gunicorn app:app --bind 0.0.0.0:8000

# Node.js
web: node server.js

# Java
web: java -jar target/app.jar

Static Sites & SPAs (React, Vue, Vite)​

Frontend apps built with Vite, Create React App, Vue CLI, etc. produce static files in a dist/ or build/ folder. These need a simple HTTP server at runtime.

Important: node_modules is not available at runtime

The Paketo buildpack prunes node_modules after the build step. Packages like serve, http-server, or anything in node_modules/.bin/ will not be available when the container starts. npx is also not on the PATH.

Solution: Create a server.js at the repo root using only Node.js built-in modules:

const { createServer } = require("http");
const { readFileSync, existsSync } = require("fs");
const { join, extname } = require("path");

const PORT = process.env.PORT || 8080;
const DIST = join(__dirname, "dist");

const MIME = {
".html": "text/html",
".js": "application/javascript",
".css": "text/css",
".json": "application/json",
".png": "image/png",
".jpg": "image/jpeg",
".svg": "image/svg+xml",
".ico": "image/x-icon",
".woff": "font/woff",
".woff2": "font/woff2",
};

createServer((req, res) => {
let filePath = join(DIST, req.url.split("?")[0]);

// SPA fallback — serve index.html for non-file routes
if (!existsSync(filePath) || filePath === DIST + "/") {
filePath = join(DIST, "index.html");
}

try {
const data = readFileSync(filePath);
const ext = extname(filePath);
res.writeHead(200, { "Content-Type": MIME[ext] || "application/octet-stream" });
res.end(data);
} catch {
res.writeHead(404);
res.end("Not Found");
}
}).listen(PORT, () => console.log(`Serving on port ${PORT}`));

The buildpack auto-detects server.js (and server.cjs, server.mjs) — no Procfile needed.

ESM projects

If your package.json has "type": "module", Node.js treats .js files as ESM and require() won't work. Name the file server.cjs instead to force CommonJS mode.

Build script

Make sure your package.json has a build script (e.g., "build": "vite build") so the buildpack generates the dist/ folder during the build step.

Port Configuration​

Your application must listen on the PORT environment variable (defaults to 8080):

Python:

import os
port = int(os.environ.get("PORT", 8080))

Node.js:

const port = process.env.PORT || 8080;

Java:

int port = Integer.parseInt(System.getenv().getOrDefault("PORT", "8080"));

Environment Variables​

Set environment variables via:

  • Console: App Settings → Environment Variables
  • CLI: c2a env set <app> KEY=value

Common variables:

VariablePurpose
DATABASE_URLDatabase connection string
SECRET_KEYApplication secret
NODE_ENVNode.js environment
LOG_LEVELLogging verbosity

Troubleshooting​

Build fails with "detection error"​

Cause: Required files not found at repository root.

Solution:

  1. Ensure detection files (requirements.txt, package.json, etc.) are at the repo root
  2. For subdirectory projects, create wrapper files as shown above

Build succeeds but app crashes​

Cause: Missing configuration or incorrect startup command.

Solution:

  1. Check app logs: c2a logs show <app-name>
  2. Verify Procfile command is correct
  3. Ensure all required environment variables are set

Build succeeds but app crashes with "command not found"​

Cause: The Procfile or start script references npx, serve, or another binary from node_modules. The Paketo buildpack prunes node_modules after building, so these are not available at runtime.

Solution:

  1. Don't use npx or node_modules/.bin/* in your Procfile
  2. For static sites, create a server.js using only Node.js built-in modules (see Static Sites & SPAs above)
  3. If you need a package at runtime, ensure your app entry point (e.g., server.js) uses require() — the buildpack keeps modules that are imported by the detected entry point

App not accessible​

Cause: App not listening on correct port.

Solution:

  1. Ensure your app reads the PORT environment variable
  2. Default to port 8080 if PORT is not set
  3. Bind to 0.0.0.0, not localhost

Best Practices​

  1. Keep dependencies minimal - Faster builds, smaller images
  2. Use a Procfile - Explicit is better than implicit
  3. Set PORT dynamically - Don't hardcode ports
  4. Use environment variables - Never commit secrets
  5. Test locally first - Ensure your app runs before deploying