Appearance
Supported Languages & Frameworks
Infrly builds and runs your app for you — you don't write a Dockerfile yourself. Pick a runtime and Infrly prefills sensible install/build/start commands and a default port; override any of them if your app doesn't match the default shape.
| Runtime | Install command | Build command | Start command | Default port |
|---|---|---|---|---|
| Node.js | npm install (or yarn install / pnpm install, detected) | npm run build | npm start | 3000 |
| Python | pip install -r requirements.txt | (none) | uvicorn main:app --host 0.0.0.0 --port $PORT | 8000 |
| Go | go mod download | go build -o app . | ./app | 8080 |
| Java | (none — Maven handles it) | mvn clean package -DskipTests | java -jar target/*.jar | 8080 |
| Ruby | bundle install | (none) | bundle exec puma -b tcp://0.0.0.0:$PORT | 3000 |
| PHP | composer install --no-dev --optimize-autoloader | (none) | php -S 0.0.0.0:$PORT | 8000 |
| Rust | (none — Cargo handles it) | cargo build --release | ./target/release/app | 8080 |
Every default already reads the port from $PORT — see Build & Start Commands for why that matters and how to override any of these fields.
Supported runtime versions
Infrly reads the version your project asks for, builds with a matching official runtime image, and shows the choice at the top of every build log (for example Using Node.js 22 (from engines.node in package.json)). The same rules apply to Web Services, Static Sites and Cron Jobs.
| Runtime | Supported versions | Used when nothing is specified | Where Infrly looks (first match wins) |
|---|---|---|---|
| Node.js | 20, 22, 24, 26 | 22 | engines.node in package.json, .nvmrc, .node-version, .tool-versions |
| Python | 3.6 – 3.14 | 3.12 | .python-version, runtime.txt, requires-python or Poetry's python in pyproject.toml, Pipfile, .tool-versions |
| Java | 11, 17, 21, 25 | 21 | pom.xml (maven.compiler.release, java.version, maven.compiler.source/target, compiler plugin), Gradle toolchain / jvmToolchain / sourceCompatibility, .java-version, system.properties |
| Go | any go.mod version (built with Go 1.22 – 1.26) | 1.25 | go and toolchain in go.mod |
| Ruby | 3.1 – 3.4 | 3.3 | .ruby-version, ruby in Gemfile, Gemfile.lock, .tool-versions |
| PHP | 8.1 – 8.5 | 8.3 | config.platform.php or require.php in composer.json |
| Rust | latest stable | latest stable | rust-toolchain.toml / rust-toolchain is installed automatically |
How versions are chosen:
- Ranges (
">=18","^3.10","^7.3|^8.0") get the default version when it fits, otherwise the closest supported version that fits."20.x"means exactly Node.js 20. - Exact pins (
.python-version3.11.4) use that minor line with its latest patch. Ruby is the exception: an exact Ruby version (3.2.2) is used exactly, because Bundler requires it. - Java builds with the smallest supported JDK at or above your target (a
19target builds on JDK 21). - Go builds older
go.modversions with the current Go release, since newer Go compiles older code unchanged.
Unsupported versions stop the deployment before anything is built, with a message that says what was found, where, and what to use instead. For example:
Unsupported Node.js version: 18 (from engines.node in package.json). Infrly supports Node.js 20 and higher. Please update your project to a supported version.
The same check runs when you pick a repository in the dashboard, so you see the problem before creating the service. To fix it, update the version in the file named in the message, push, and deploy again.
Node.js: package managers and versions
Infrly supports npm, npx, Yarn (1 and 2+) and pnpm out of the box. When you pick a repository, it detects which one your project uses and prefills matching commands:
| Your repository has | Package manager | Install command | Build / start |
|---|---|---|---|
"packageManager": "pnpm@…" or pnpm-lock.yaml | pnpm | pnpm install | pnpm run build / pnpm run start |
"packageManager": "yarn@…" or yarn.lock | Yarn | yarn install | yarn run build / yarn run start |
package-lock.json, or nothing | npm | npm install | npm run build / npm run start |
- Exact versions: the
packageManagerfield inpackage.json(for example"pnpm@10.18.0"or"yarn@4.10.3") is honored exactly, through Node.js's built-in Corepack. Without it, Yarn 1 and the current pnpm are used. - Lockfiles are respected. The default install commands don't fail if your lockfile is slightly out of date; for strict, lockfile-only installs, set the install command to
npm ci,yarn install --frozen-lockfile(Yarn 1),yarn install --immutable(Yarn 2+) orpnpm install --frozen-lockfile. - npx works in any command, for example a build command of
npx vite buildor a start command ofnpx serve -s dist -l $PORT. Packages that aren't in your dependencies are downloaded automatically, without a prompt. - Node.js version: set
"engines": { "node": "…" }inpackage.json(or use.nvmrc). See Supported runtime versions: Node.js 18 and older can't be deployed. - Bun isn't supported as a build tool yet. Projects with a
bun.lockbare prefilled with npm commands instead.
Framework notes
- Node.js — the default start shape fits Express, Fastify, Koa, NestJS, or a custom
server.js, as long aspackage.jsonhas astartscript. Nuxt is detected automatically: as a Web Service it starts withnode .output/server/index.mjs; as a Static Site it builds with yourgeneratescript and publishes.output/public. A Next.js app needsnpm run buildto already produce a production server your start command runs (next start), not a static export — if you're exporting fully static HTML instead, deploy it as a Static Site rather than a Web Service. - Python — the default start command assumes an ASGI app object named
appinmain.py(the common FastAPI shape). Override it for Django (gunicorn myproject.wsgi -b 0.0.0.0:$PORT) or Flask (gunicorn app:app -b 0.0.0.0:$PORT) — both needgunicorn(or another WSGI/ASGI server) inrequirements.txtsince Flask/Django's own dev server isn't meant for production traffic. - Go — works unmodified with Gin, Echo, Fiber, or the standard library
net/http— whatever yourgo buildoutput binds to$PORT. - Java — Maven projects run the executable JAR in
target/. For Gradle, Infrly builds with./gradlew build -x test(makinggradlewexecutable first) and starts the Spring Boot JAR inbuild/libs/, skipping the-plain.jarGradle also produces. - Ruby — fits Rails and Sinatra out of the box via Puma. Infrly sets
RACK_ENV=productionandRAILS_ENV=productionby default (set your own value to override). A Rails app also needsSECRET_KEY_BASE, and usually its database migrated before serving traffic — see whether your framework needs a release/migration step in its start command. - PHP — the built-in
php -Sserver is fine for smaller Laravel/Symfony apps; higher-traffic apps typically wantphp-fpmbehind a real web server instead, which means a custom start command. - Rust — works with Actix Web, Axum, Rocket, or anything else that binds to
$PORT;cargo build --releaseis slower than a debug build but is what you want for anything actually serving traffic.
Something else entirely?
If your app doesn't fit any of these seven runtimes as-is, the most common workaround is wrapping it to match one — e.g. a compiled binary from another language can often still be started via a thin script under whichever runtime's start command shape fits closest. If that genuinely doesn't work for your stack, reach out — new runtime support is straightforward to add on Infrly's side.