Supported Frameworks, Languages & Build Methods
Temps deploys Next.js, Vite, React, Node.js, Python, Go, Rust, Java, .NET, PHP, Ruby and anything with a Dockerfile. It auto-detects Next.js, Vite, Rsbuild, Docusaurus, Rust, Go, Python, Java, a Dockerfile or a Compose file from your repository; for everything else (Create React App, Express, NestJS, Astro, Nuxt, Laravel, Rails…) you choose a preset once and Temps builds it, usually with Autopack, its built-in builder. You can also deploy a pre-built Docker image or a static bundle.
This guide describes how the nightly release channel builds your app, using the Autopack builder. Beta (v0.1.0-beta.56) also builds with Autopack, but some details below may differ. Earlier releases and the stable channel build with Nixpacks and behave differently. To run nightly, see Release channels.
Build methods
Temps offers four ways to get your application running:
- Name
Git push (auto-detected)- Type
- Default
- Description
Push code to a connected Git repository. Temps detects your framework from repository files (or uses the preset you chose), generates a Dockerfile, builds a container image, and deploys it.
- Name
Dockerfile- Type
- Full control
- Description
Add a
Dockerfileto your repository root. Temps uses it directly instead of generating one. Supports multi-stage builds, BuildKit caching (--mount=type=cache), custom build arguments, and custom Dockerfile paths for monorepos.
- Name
Docker image- Type
- Pre-built
- Description
Deploy a pre-built image from Docker Hub, GitHub Container Registry, or any OCI registry. You can also upload an image directly via
docker save. No build step — Temps pulls the image and starts a container.
- Name
Static files- Type
- No runtime
- Description
Upload a
.tar.gzor.zipbundle of pre-built static files. Temps serves them directly from the proxy — no container runs at runtime.
For details on each method, see Docker Containers. The deployment pipeline explains what happens after the build.
How framework detection works
Temps uses two mechanisms, and it helps to know which one you're relying on.
1. Preset detection (repository files). When you connect a repository, Temps scans each directory for known filenames and reports every preset that matches, so you can pick when more than one applies — a repo with both a Dockerfile and a next.config.ts offers you both. Matches are ordered by priority:
- Docker Compose — a recognised compose file (
docker-compose.yml,compose.yaml, …) - Dockerfile
- Framework config files —
docusaurus.config.js/.ts,next.config.js/.mjs/.ts,vite.config.js/.ts,rsbuild.config.ts - Language manifests —
Cargo.toml,go.mod,requirements.txt/pyproject.toml/setup.py/Pipfile,pom.xml/build.gradle/build.gradle.kts nixpacks.toml— offers the Autopack (auto-detect) presetindex.html— only when nothing above matched, offers the static preset (nixpacks-static)
A package.json, composer.json, Gemfile, mix.exs or .csproj on its own isn't a detection signal. If nothing matches, the build fails with Could not auto-detect project type from files… Please specify a preset explicitly — there is no silent fallback. You then pick a preset yourself. The selectable set is:
nextjs, vite, react-app, rsbuild, docusaurus, rust, go, python, java, docker-compose, dockerfile, custom, autopack, and nixpacks plus its per-language variants nixpacks-node, nixpacks-python, nixpacks-rust, nixpacks-go, nixpacks-java, nixpacks-php, nixpacks-ruby, nixpacks-deno, nixpacks-elixir, nixpacks-csharp, nixpacks-dart and nixpacks-static.
Every preset except nextjs, vite, react-app, rsbuild, docusaurus, docker-compose, dockerfile and custom builds with Autopack, which generates a container image from your source without a Dockerfile. That includes rust, go, python and java. The nixpacks-* slugs are older names kept for existing projects; the dashboard shows them as Autopack (Node.js), Autopack (PHP) and so on. autopack and nixpacks let Autopack choose the language itself.
There is no dedicated, selectable preset for Astro, Nuxt, Remix, NestJS, Express, SvelteKit, Angular, Rails or Laravel. Those frameworks deploy through a language preset — usually nixpacks-node, nixpacks-php or nixpacks-ruby — and Autopack derives the install, build and start commands from your project files. If it picks the wrong start command, set one with a web: line in a Procfile (or [start] cmd in nixpacks.toml).
2. Node framework detection (package.json dependencies). Within an Autopack (Node.js) build, Autopack reads your dependencies to recognise the framework, checking next, nuxt, @remix-run/node or @remix-run/serve, @sveltejs/kit, astro, @nestjs/core, @angular/core, react-scripts and vite in that order. It starts the app with the first of: a Procfile web: line, your start script, the main file in package.json, or a common entry file such as server.js or index.js. Create React App, Vite and Astro builds without a server adapter or a start script are served as static sites from inside your app's container instead.
Deploy guides
Step-by-step tutorials for each framework: Next.js, React, Vue.js, Angular, Astro, SvelteKit, Remix, Docusaurus, Node.js, Django, FastAPI, Laravel, Ruby on Rails, Go, Rust, Java, .NET, Elixir.
Framework presets
Presets are framework-specific build configurations. When Temps detects a framework from repository files, it selects the matching preset to generate an optimised Dockerfile. You can also select a preset manually when creating a project.
JavaScript and TypeScript
Only four JavaScript presets are detected from repository files. Everything else in this table has no file signal — a bare package.json does not select a preset on its own — so choose the preset shown.
| Framework | How it builds | Detection |
|---|---|---|
| Next.js | nextjs preset, Node.js server (SSR) on PORT (3000 by default) | next.config.js, .mjs, .ts |
| Vite (React, Vue) | vite preset, static | vite.config.js, .ts |
| Rsbuild | rsbuild preset, static | rsbuild.config.ts |
| Docusaurus | docusaurus preset, static | docusaurus.config.js, .ts |
| Create React App | choose the react-app preset, static | not detected |
| Vue CLI | choose the vite preset, static | not detected |
| Astro | static: choose vite (serves dist/); on-demand: nixpacks-node + Procfile web: node ./dist/server/entry.mjs | not detected |
| Nuxt | choose nixpacks-node, server (SSR) | not detected |
| Remix, SvelteKit | choose nixpacks-node for SSR | a vite.config makes them detect as the static Vite preset |
| Angular | static: choose vite + .temps.yaml build.output_dir: dist/<project>/browser; SSR: nixpacks-node + Procfile web: node dist/<project>/server/server.mjs | not detected |
| NestJS, Express, plain Node.js | choose nixpacks-node, server | not detected |
Static presets (vite, react-app, rsbuild, docusaurus) are served by the Temps proxy, with no container running. Static Astro and Create React App builds under nixpacks-node are served by a web server inside your app's container instead; an Angular build is only served that way when build.output_dir is set, and otherwise runs its start script. Server apps listen on the PORT Temps sets, which is 3000 unless you change the project's port.
Remix and SvelteKit repositories contain a vite.config, so they are detected as the static Vite preset (no server-side rendering). For SSR, switch the project to the nixpacks-node preset.
Python
Any of requirements.txt, pyproject.toml, setup.py or Pipfile selects the single python preset (default port 8000). There is no separate Django, Flask or FastAPI preset — all three deploy through python, which builds with Autopack and picks the start command from your code:
| Condition | Start command |
|---|---|
a Procfile web: line | that command |
manage.py and a <project>/wsgi.py (Django) | gunicorn <project>.wsgi:application, binding PORT |
FastAPI( or Starlette( in main.py, app.py, asgi.py, wsgi.py or server.py | uvicorn <module>:app, binding PORT |
Flask( in one of those files | gunicorn <module>:app, binding PORT |
main.py, app.py, server.py or bot.py | python <file> |
Gunicorn and Uvicorn are added to the build when your dependencies don't include them. If the generated start command isn't the one you want, set it with a web: line in a Procfile. The Python version comes from .python-version, runtime.txt or requires-python in pyproject.toml, and defaults to 3.12.
Temps does not run database migrations for you. Run them as a one-off step (for example from your CI job or a shell on the server) rather than chaining them into the start command.
Go, Rust and Java
| Language | Preset | Build | Preset default port | Detection |
|---|---|---|---|---|
| Go | go | go build with CGO_ENABLED=0; Go version from go.mod | 8080 | go.mod |
| Rust | rust | cargo build --release (with --locked when Cargo.lock is committed); toolchain from rust-toolchain.toml | 8080 | Cargo.toml |
| Java | java | mvn -B -DskipTests package or gradle --no-daemon -x test build (or the wrapper) | 8080 | pom.xml, build.gradle, build.gradle.kts |
If your app listens on a different port, set the project's port in its settings.
PHP
Temps does not auto-detect PHP projects — neither composer.json nor index.php is a preset detection signal. Select the Autopack (PHP) preset (nixpacks-php) on the project before deploying.
With nixpacks-php selected, Autopack recognises composer.json or index.php and serves the app with FrankenPHP (document root public/ when present). The PHP version comes from require.php in composer.json and defaults to 8.3; extensions come from the ext-* entries. Laravel deploys through the same preset, with its Vite assets built; there is no separate Laravel preset.
Ruby
Temps does not auto-detect Ruby projects — a Gemfile is not a preset detection signal. Select the Autopack (Ruby) preset (nixpacks-ruby) on the project before deploying.
With nixpacks-ruby selected, Autopack detects the Gemfile. Rails apps deploy through the same preset and start with bundle exec rails server -b 0.0.0.0 -p ${PORT:-3000}; other Rack apps, such as Sinatra, start from config.ru with bundle exec rackup. The Ruby version comes from .ruby-version or the ruby line in your Gemfile, and defaults to 3.3.
Elixir and .NET
Neither is auto-detected. Choose Autopack (Elixir) (nixpacks-elixir) to build a mix release — see Deploy Elixir — or Autopack (C# / .NET) (nixpacks-csharp) to build with dotnet publish — see Deploy .NET.
Special presets
| Preset | Slug | Description |
|---|---|---|
| Dockerfile | dockerfile | Uses the Dockerfile in your repository as-is |
| Autopack (auto-detect) | autopack (or the older nixpacks) | Lets Autopack detect the language and build it |
| Static site | nixpacks-static | Deploys the files in your repository as they are, with no build step |
| Docker Compose | docker-compose | Deploys a docker-compose.yml / compose.yaml stack directly — see Docker Compose below |
Docker Compose
Temps deploys docker-compose.yml / compose.yaml stacks directly via the docker-compose preset — this is a first-class deployment method, not a workaround.
Select the Docker Compose preset when creating a project and point it at a repository containing a compose file (or paste one inline for a manual project). On deploy, Temps:
- Reads the compose file from your repo (or the inline content) and merges in your project's environment variables
- Builds any services with a
build:directive, then runsdocker compose upin an isolated project namespace per environment - Discovers the resulting containers and tracks all of them against the deployment — one project can run multiple containers, not just one
- Exposes each service that publishes a port through the Temps proxy; internal-only services (e.g. a database with no published port) stay off the public network
- Applies a Temps-only override you set in the project's Docker Compose settings, so you don't have to edit the compose file in your repo (
docker-compose.temps-override.ymland the otherdocker-compose.temps-*.ymlnames are reserved for files Temps generates)
Compose deployments go through the same pipeline as every other preset — Git push deploys, environment variables, and deployment history all apply. Compose files are validated against a security policy before use (host bind mounts and paths are confined to the checkout). Named volumes in a Compose project are the way to keep data on disk; single-container apps have no persistent volumes.
For the full walkthrough (environment variables, ports and domains, volumes, the security policy and redeploys), see Deploy a Docker Compose stack. For single-container deploys, see Docker Containers.
Autopack languages
For languages without a first-class preset, Temps uses Autopack, its built-in builder, to detect, build, and package your application. Autopack supports 24 ecosystems:
- Node.js
- Deno
- Python
- Ruby
- PHP
- Elixir
- Gleam
- Java
- Scala
- Clojure
- C# and F# (.NET)
- Haskell
- Swift
- Dart
- Crystal
- Zig
- Go
- Rust
- C and C++
- COBOL
- Lunatic
- Procfile apps
- Shell scripts
- Static files
Node.js, Python, Rust, Go, Java, PHP, Ruby, Deno, Elixir, C# / .NET, Dart and static files each have a preset you can select (nixpacks-node, nixpacks-python, and so on, shown as Autopack (Node.js) and so on). The other languages build through the Autopack (auto-detect) preset (autopack).
Autopack reads optional configuration from your repository root: autopack.json, then railpack.json, then nixpacks.toml.
Package managers
Temps detects your Node.js package manager from the lock file:
| Package manager | Lock file |
|---|---|
| npm | package-lock.json |
| Yarn | yarn.lock |
| pnpm | pnpm-lock.yaml |
| Bun | bun.lockb or bun.lock |
Under Autopack (Node.js), the packageManager field in package.json also counts, and dependencies install with the lock file enforced (for example npm ci). The Node.js version comes from .nvmrc, .node-version or engines.node in package.json, and defaults to 24.
Monorepo tools
Temps detects and supports these monorepo build tools:
| Tool | Detection | Behavior |
|---|---|---|
| Turborepo | turbo.json | Runs npx turbo build scoped to your project directory |
| Nx | nx.json | Runs npx nx build {package} for the target package |
| Lerna | lerna.json | Runs npx lerna run build --scope={package} |
All monorepo tools work with all four package managers (npm, Yarn, pnpm, Bun). Set the App Directory in project settings to the subdirectory containing each app — see Your First Deployment. Full walkthrough: Deploy a Turborepo monorepo to your own server.
Build configuration
Every preset supports these optional overrides, configurable from the project settings:
| Option | Description | Example |
|---|---|---|
| Dockerfile path | Custom Dockerfile location relative to the build context | docker/Dockerfile.production |
| Build context | Custom build context path relative to the repository root | ./apps/web |
| Install command | Override the default install command | pnpm install --no-frozen-lockfile |
| Build command | Override the default build command | npm run build:production |
| Output directory | Override the output directory for static builds | out |
Health checks, cron jobs and alerts are configured in a .temps.yaml file in your repository.
Docker
If a Dockerfile is present in the repository root (or the configured app directory), Temps can use it directly instead of generating one.
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Temps routes traffic to the environment or project port if you set one, otherwise to the port in the image's EXPOSE directive, otherwise to 3000.
When using a custom Dockerfile or the generated Dockerfile, Temps supports:
- Multi-stage builds — all generated Dockerfiles use separate build and production stages
- BuildKit — enabled by default; supports
--mount=type=cachefor dependency caching - Build arguments — environment variables are injected as
ARGdirectives and passed via--build-arg - Custom base images — any base image works in your custom Dockerfile
- Platform targeting —
linux/amd64andlinux/arm64
Static sites
A Git repository with an index.html and no other detected build is offered the static preset (nixpacks-static), which deploys the files as they are, with no build step. You can also upload a pre-built bundle (see Build methods).
The vite, react-app, rsbuild and docusaurus presets take a different deployment path from server apps: Temps builds a container image, extracts the build output from it, and the proxy serves the files directly. No container is left running for any of them. Single-page apps get an index.html fallback; Netlify-style _redirects files are not supported.
Container runtime
Every deployed container runs with these defaults:
| Setting | Default | Configurable |
|---|---|---|
| CPU limit | None (uncapped) | Yes |
| Memory limit | 512 MB for new projects | Yes |
| Restart policy | On failure | Yes |
| Log retention | 50 MB x 3 files (150 MB total) | No |
| Network binding | 127.0.0.1 (localhost only) | No |
| Init process | Enabled (--init) | No |
Only limits are applied to the container; the CPU and memory requests stored on a project are not reserved. See Resources for the full settings model and Scaling for replicas.
Security is enforced at the container level:
- All Linux capabilities are dropped
no-new-privilegesis set- PID limit of 512 processes
- Containers bind to localhost — external access goes through the Temps proxy with automatic TLS
Override detection
If Temps detects the wrong framework, change the preset under Project → Settings → Build & deploy → Build → Framework, or pass --preset to up.
To change the install command, build command or output directory, add a build section to .temps.yaml in your repository root:
.temps.yaml
build:
install_command: npm ci
build_command: npm run build:production
output_dir: dist
For Autopack presets, set the start command with a Procfile web: line or your package's start script. For monorepos, set the App Directory in project settings.
What is not supported
Outside of the Docker Compose preset above, every other Temps project deploys as a single container (or static file bundle) per environment. The following are explicitly not supported:
- Name
Manual multi-container pods (non-Compose)- Type
- Not supported
- Description
Outside of the Docker Compose preset, there is no sidecar pattern or ad hoc pod grouping. A
dockerfile, framework-preset or Autopack project runs exactly one container. Separate services (databases, Redis, etc.) are managed independently through Managed Services, or bundled together via the Docker Compose preset.
- Name
Kubernetes / Docker Swarm- Type
- Not supported
- Description
Temps uses Docker directly — there is no orchestrator layer. Deployments (including Compose stacks) run as Docker containers managed by the Temps deployer.
- Name
Lambda-style serverless and edge functions- Type
- Not supported
- Description
There are no isolated per-request functions and no edge functions. Your framework's API routes (Next.js, Remix, SvelteKit, etc.) run inside the application container — no cold starts and no per-invocation billing.
- Name
Cloud Native Buildpacks- Type
- Not supported
- Description
Temps uses Autopack and Dockerfile builds. Paketo / Heroku buildpacks are not supported.
- Name
Persistent volumes for single-container apps- Type
- Not supported
- Description
App containers have no persistent volumes. Store data in a managed database or S3 bucket, or use a Docker Compose project with named volumes.
Managed Services vs. Docker Compose
Both let a project use a database, cache, or queue — pick based on how much control you need:
| Managed Service | Docker Compose preset | |
|---|---|---|
| Best for | PostgreSQL, MariaDB, MongoDB, Redis, S3-compatible storage | Anything else, or a stack you already have as a compose file |
| Managed by | Temps (backups, upgrades, connection injection) | You (via the compose file) |
| Setup | Create the service, then link it to the project — no YAML | Point the docker-compose preset at your compose file |
See Deploy with a Database for the Managed Services path, or the Docker Compose section above to deploy a compose stack directly.