Skip to content

Buildpacks Detection

When you git push paas main, the PaaS Runtime control plane analyses the repository root to pick the right Paketo buildpack. No configuration needed for standard projects.

Detection flow

sequenceDiagram
  participant D as Developer
  participant F as Forgejo
  participant CP as Control Plane
  participant LD as language_detector
  participant TK as Tekton
  participant PK as Paketo

  D->>F: git push paas main
  F->>CP: webhook push event
  CP->>LD: detect_language(repo_path)
  LD-->>CP: DetectionResult { buildpack, indicator_file }
  CP->>TK: PipelineRun (buildpack-image param)
  TK->>PK: paketo build with detected buildpack
  PK-->>TK: OCI image
  TK-->>CP: image URL

Supported languages

Language Indicator file Buildpack image
Node.js package.json paketobuildpacks/nodejs
Python requirements.txt or pyproject.toml paketobuildpacks/python
Go go.mod paketobuildpacks/go
Rust Cargo.toml paketocommunity/rust
Ruby Gemfile paketobuildpacks/ruby
PHP composer.json paketobuildpacks/php
Java pom.xml or build.gradle paketobuildpacks/java
Elixir mix.exs paketobuildpacks/elixir

Detection is ordered: if a monorepo has both package.json and requirements.txt, Node.js wins. Use paas.toml to override this.

Force Dockerfile

If a Dockerfile is present at the repository root, buildpack detection is skipped entirely. The Kaniko builder uses your Dockerfile directly.

# Dockerfile at repo root → buildpacks bypassed
FROM node:20-alpine
COPY . .
RUN npm ci && npm run build
CMD ["node", "dist/server.js"]

Override via paas.toml

Create a paas.toml at the repository root and specify the buildpack:

[build]
buildpack = "paketobuildpacks/python"

The override wins over automatic detection. Use it when:

  • your monorepo's auto-detected language is wrong
  • you want to pin a specific buildpack version
  • you use a custom/community buildpack

Custom buildpacks (Rust)

Rust is not in the official Paketo registry. PaaS Runtime uses the community buildpack paketocommunity/rust. No extra configuration needed — just commit a Cargo.toml.

# paas.toml — explicitly pin the Rust buildpack
[build]
buildpack = "paketocommunity/rust"

Note — Phase 2: If paketocommunity/rust maintenance stalls, the fallback is Nixpacks (nixpacks build . --name myapp). Nixpacks auto-detects Rust via Cargo.toml and generates a Dockerfile automatically. Configure it with:

[build]
buildpack = "nixpacks"

Nixpacks is already supported in the BuildMethod::Kaniko pipeline path (it generates the Dockerfile, then Kaniko builds the image), so no infrastructure change is needed to switch.

Troubleshooting — "No buildpack matched"

If none of the indicator files are found, the build fails before any Tekton resources are created:

No buildpack matched. Add a Dockerfile or specify [build] buildpack in paas.toml.
Detected files: README.md, .gitignore, Makefile

Common causes:

  • Missing package.json, go.mod, etc. — did you forget to commit it?
  • Monorepo without a root-level indicator — add a paas.toml override
  • Framework that uses a non-standard file (e.g. poetry.lock alone) — add pyproject.toml

Language detection scope

Detection runs server-side only, in the control plane build planner (service.rs::start_build in crates/build). The paas CLI does not run detection locally — it submits the git URL to the API and the backend handles the rest, after Tekton checks out the workspace.

For local feedback before pushing, run:

ls package.json go.mod Cargo.toml requirements.txt 2>/dev/null

or run the unit tests in crates/build (cargo test -p paas-build) which cover all 8 supported languages plus the priority rules above.