Deploy Remix on Temps

Select the Autopack (Node.js) preset (nixpacks-node) and run up: Temps runs your build script, starts remix-serve (or react-router-serve for React Router v7) on $PORT, and serves it over HTTPS as a persistent Node.js process, so loaders and actions have no cold starts.

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.

For an overview of running Remix on your own server, including costs, see Deploy Remix to your own server. Every framework and the preset it needs is listed under Supported platforms.


Quickstart

From your project root, deploy with the Autopack (Node.js) preset (nixpacks-node), which runs your app as a Node.js server:

npx @temps-sdk/cli up --preset nixpacks-node

Or pick it under Project → Settings → Build & deploy → Build → Framework.

A Vite-based Remix app has a vite.config.js or vite.config.ts, so Temps detects it as the static Vite preset. That preset only serves the built files and can't run the Remix server, so switch the project to Autopack (Node.js). A classic remix.config.js project isn't detected at all and needs the same preset.

With Autopack (Node.js), Temps runs your build script, then starts the app with your start script (for example remix-serve ./build/server/index.js). A web: line in a Procfile takes priority over the start script. remix-serve listens on the PORT that Temps sets. The Node.js version comes from .nvmrc, .node-version or engines.node in package.json, and defaults to 24.


React Router v7 (framework mode)

React Router v7 is the continuation of Remix v2, and its framework mode deploys the same way. Use the same nixpacks-node preset; the default template's scripts already work:

package.json

{
  "scripts": {
    "build": "react-router build",
    "start": "react-router-serve ./build/server/index.js"
  }
}

Temps runs react-router build, then your start script. react-router-serve reads PORT, so no code changes are needed. A React Router v7 app also has a vite.config.ts, so switch it off the detected Vite preset as described above.


What Temps handles automatically

FeatureHow Temps handles it
BuildYour build script (for example npm run build)
StartYour start script, or a Procfile web: line
HTTPSLet's Encrypt, auto-renewed
PortPORT env var injected, defaults to 3000
Loaders and actionsFully supported via Node.js runtime
No cold startsPersistent Node.js process
Preview deploymentsOpt-in; once enabled, each branch gets its own preview environment

Managed PostgreSQL

If your app stores sessions or data in PostgreSQL, create a database under Databases → Create database, then link it from your project's Databases page. Temps doesn't provision one automatically. Once linked, Temps injects the connection string as POSTGRES_URL (not DATABASE_URL), so point Prisma or Drizzle at that variable (for Prisma, url = env("POSTGRES_URL")). See Deploy with a Database.

Temps doesn't run migrations for you. Run them as a one-off step after the deploy, for example from your CI pipeline:

npx prisma migrate deploy

Don't chain migrations into your start script: with restarts or more than one replica they can run several times at once against the same database.


Environment variables

npx @temps-sdk/cli environments vars set SESSION_SECRET "your-secret" -e production

Platform behavior

These rules apply to every app deployed on Temps, regardless of framework.

The one requirement: your app must listen on the port in the PORT environment variable and bind to 0.0.0.0 — not localhost or 127.0.0.1. Temps runs your app in a container and routes traffic from the host, so an app bound to localhost only accepts connections from inside the container and will fail its health check.

Health checks

After your container starts, Temps sends HTTP GET requests to verify it is healthy before routing traffic to it.

  • Path: / (the root of your application) by default
  • Success: 2 consecutive responses with a 2xx, 3xx, 404 or 405 status code
  • Timeout: 300 seconds (5 minutes) for the app to become healthy, fixed in v0.1.0-beta.56. If the app answers with error responses (other 4xx, or 5xx) for 60 seconds in a row, the deployment fails sooner. From the next release the timeout is configurable from 30 to 3600 seconds under Project → Settings → Build & deploy
  • Retry interval: 2 seconds between successful checks, 5 seconds after an error response or a failed connection

Connection errors and other 4xx or 5xx responses are retried until the timeout; if the app hasn't passed by then, the deployment fails. The check runs once, at deploy time. To check a different path, add a .temps.yaml to your repository root:

.temps.yaml
health:
  path: /health

Only path is used. Other health fields (status, interval, timeout, retries) are accepted but currently have no effect.

Add a dedicated /health endpoint that returns a simple 200. This avoids issues where / requires authentication or returns a redirect.

Auto-injected environment variables

Temps injects these variables into every deployment automatically:

VariableValueDescription
PORTResolved portThe port your app must listen on
HOST0.0.0.0Bind address
SENTRY_DSNAuto-generatedError tracking endpoint
TEMPS_API_URLYour Temps URLPlatform API endpoint
TEMPS_API_TOKENDeployment tokenAuthentication for Temps SDKs
OTEL_EXPORTER_OTLP_ENDPOINTYour Temps OTLP URLOpenTelemetry trace collection
OTEL_SERVICE_NAMEProject nameService identifier for traces

You do not need to configure these manually. They are available in process.env (Node.js), os.environ (Python), os.Getenv (Go), and the equivalent in other languages.

Deploying another server-rendered framework? The Next.js and SvelteKit guides follow the same pattern.


Next Steps

Last updated

Was this page helpful?