Migrate from Railway to Temps
To move a Railway service to a self-hosted Temps server: deploy the same Git repository (Temps auto-detects the build and reads an existing railpack.json or nixpacks.toml, or uses your Dockerfile), copy your variables, restore a pg_dump of your Railway Postgres into a Temps managed PostgreSQL service you link to the project, move volume files to S3 storage, then cut DNS over. The deployment model is the same — Git push, auto-detect, run in containers — but Temps has no pre-deploy command, no persistent volumes for app containers and no template marketplace, so those parts need the changes described below.
For how the two compare feature by feature, see Temps vs Railway; for what you pay Railway today, see Railway pricing.
Applications
Builds: Railpack, Nixpacks and Dockerfiles
Railway builds apps without a Dockerfile using Railpack, which became its default builder on 19 September 2025; older services were built with Nixpacks. Temps doesn't run Railpack or Nixpacks. It detects the framework from your repository files and builds with autopack, its own builder, which reads an existing railpack.json or nixpacks.toml for custom settings (see supported platforms).
Next.js, Vite, Python, Go, Rust and Java apps are detected automatically. Express, NestJS, Astro, Nuxt and other Node servers aren't, so pick the Node preset when you create the project. If your repository has a Dockerfile, Temps builds it as-is, which is the most portable option.
Environment Variables
Add environment variables
- 1
In Railway, open Project then Variables then Raw Editor and copy the variables in .env format.
- 2
In Temps, open Project then Settings then Environment Variables and paste them in.
- 3
Remove or replace Railway-specific variables (PORT, RAILWAY_ENVIRONMENT, the Railway DATABASE_URL) using their Temps equivalents.
Export your Railway variables from Railway → Project → Variables → Raw Editor (copy the .env format), then add them in Temps → Project → Settings → Environment Variables (see environment variables for full reference).
Railway injects a few platform variables automatically (RAILWAY_ENVIRONMENT, PORT, etc.). Remove or replace Railway-specific ones:
| Railway variable | Temps equivalent |
|---|---|
PORT | Remove. Temps sets PORT to the project's port, which is pre-filled from the detected framework (3000 for Node; see Ports). Change it under Project → Settings → Build & deploy |
RAILWAY_ENVIRONMENT | Use NODE_ENV or a custom TEMPS_ENV var |
RAILWAY_VOLUME_MOUNT_PATH | Remove (see Volumes) |
DATABASE_URL (Railway Postgres) | Map to the POSTGRES_URL Temps injects when you link a managed database (see below) |
Reference variables such as Postgres.DATABASE_URL (Railway's double-brace template syntax) | Replace with literal values, or with the variables Temps injects when you link a managed service |
Pre-deploy commands, cron schedules and replicas
- Pre-deploy command. Temps has no pre-deploy or release command, and it doesn't run database migrations for you. Run them as a one-off step after the deploy, from CI or over SSH, as shown in Laravel migrations. Don't chain them into the start command: with restarts or several replicas they can run more than once at the same time.
- Cron schedule. A Railway cron service runs its start command on a schedule. Temps cron jobs are
.temps.yamlentries (pathandschedule) that call an HTTP path in your app, so turn the job into an endpoint. - Replicas. Set a fixed replica count per environment (see Scaling).
Deploy
Create and deploy the project
- 1
Download deploy.sh, review it, then run the local copy to install Temps.
- 2
Go to Projects then New Project in the Temps console.
- 3
Connect your Git repository and select your branch.
- 4
Add environment variables.
- 5
Click Deploy.
Checkpoint: Wait until the deployment completes and the app responds at its Temps preview URL before cutting over DNS.
# Install Temps if not already done
curl -fsSL https://temps.sh/deploy.sh -o deploy.sh
less deploy.sh
bash deploy.sh
- Go to Projects → New Project in the Temps console
- Connect your Git repository and select your branch
- Add environment variables
- Click Deploy
Databases
Railway's Postgres service injects DATABASE_URL into services that reference it. On Temps, choose one of (see managed services and deploy with a database for full details):
- Temps managed PostgreSQL — a Postgres container on your Temps server, on the same private network as your apps. You create it, then link it to the project (simplest path)
- External provider — Neon, Supabase, or any hosted Postgres
Step 1: Export from Railway Postgres
Railway's DATABASE_URL uses the private network, so it only works from inside your Railway project. To dump from your machine, open the Postgres service's Settings → Networking, add Public Access, and copy the DATABASE_PUBLIC_URL variable it creates (Railway docs). Public access goes through Railway's TCP proxy, which is billed as egress.
# Export a compressed, portable backup
RAILWAY_DATABASE_URL="<DATABASE_PUBLIC_URL>"
pg_dump "$RAILWAY_DATABASE_URL" \
--no-acl \
--no-owner \
-Fc \
-f railway_backup.dump
# Verify the dump is readable
pg_restore --list railway_backup.dump | head -20
Step 2: Create the New Database
Create a managed Postgres database
- 1
In the Temps dashboard, go to Managed Services then New Service then PostgreSQL.
- 2
Choose a name (for example myapp-db).
- 3
Temps creates the Postgres service. It isn't attached to any project until you link it in Step 4.
Checkpoint: Confirm the service appears in the services list with status running, and note its ID.
Option A — Temps managed PostgreSQL (recommended): Temps doesn't create a database when you deploy. Create the service, then link it to the project (Step 4). Linking creates a database named <project>_<environment> and injects POSTGRES_URL, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, POSTGRES_USER and POSTGRES_PASSWORD into that environment.
bunx @temps-sdk/cli services create -t postgres -n myapp-db -y
bunx @temps-sdk/cli services list # note the service ID
bunx @temps-sdk/cli services link --id <service-id> -p my-app
bunx @temps-sdk/cli services env --id <service-id> -p my-app # POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB
Option B — External Postgres: Create a database at Neon, Supabase, or any Postgres host and copy the connection string.
Step 3: Restore Your Data
A Temps managed database isn't reachable from the internet: on the Temps server it listens on 127.0.0.1, on a host port assigned from 5432 (docker ps on the server shows it). Copy the dump to the server and restore it there, using the user, password and database name from services env. For an external provider, use its connection string as NEW_DATABASE_URL instead.
scp railway_backup.dump user@your-server:/tmp/
ssh user@your-server
# Restore into the linked database
NEW_DATABASE_URL="postgresql://<POSTGRES_USER>:<POSTGRES_PASSWORD>@127.0.0.1:<host-port>/<POSTGRES_DB>"
pg_restore \
--clean \
--if-exists \
--no-owner \
-d "$NEW_DATABASE_URL" \
/tmp/railway_backup.dump
# Sanity check — compare row counts between old and new
psql "$RAILWAY_DATABASE_URL" -c "SELECT schemaname, tablename, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC LIMIT 10;"
psql "$NEW_DATABASE_URL" -c "SELECT schemaname, tablename, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC LIMIT 10;"
Point your app at the new database on the Temps preview URL and run your test suite before touching DNS. Only then update DATABASE_URL in your production environment.
Step 4: Link the Database and Point the App at It
Link the database to the project
- 1
Open the myapp-db service in the Temps dashboard and link it to the my-app project and environment.
- 2
Temps injects POSTGRES_URL, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, POSTGRES_USER and POSTGRES_PASSWORD into that environment.
- 3
If your code reads DATABASE_URL, change it to read POSTGRES_URL, or set DATABASE_URL to the same value in the environment's variables.
Checkpoint: Redeploy and confirm the app connects to the new database before touching DNS.
Your code probably reads DATABASE_URL. Either change it to read POSTGRES_URL, or set DATABASE_URL to the same value as POSTGRES_URL in the environment's variables (copy it from bunx @temps-sdk/cli services env --id <service-id> -p my-app). The hostname in POSTGRES_URL is the database container's name on the private network, so it only resolves from inside your apps, not from your laptop.
For an external database, set DATABASE_URL to the provider's connection string.
Volumes and persistent storage
Railway volumes keep files between deploys. Temps app containers have no persistent volumes, and anything written inside the container is lost on the next deploy. Choose one of:
- Object storage (recommended for uploads and user files). Create a Temps managed S3 storage service and link it to the project, which injects
S3_ENDPOINT,S3_ACCESS_KEY,S3_SECRET_KEY,S3_BUCKETand AWS-style aliases. Change the app to read and write files through an S3 client, then upload your existing files to the bucket. Cloudflare R2 or any other S3-compatible store works the same way. - Docker Compose project with a named volume. If the app needs a real filesystem (SQLite, a search index), deploy it as a Docker Compose project and declare a named volume for that path. Named volumes in a Compose project persist across deploys.
Download the files from the Railway volume first with the Railway CLI (volume docs). railway volume files lists, downloads and uploads files, and railway volume browse opens an interactive file browser:
railway volume files list /
railway volume files download /backup.tar ./backup.tar
Temps backups cover managed services such as S3 storage and Postgres, not files inside app containers.
Templates
Railway templates are pre-configured stacks (e.g. "Node + Postgres"). Temps doesn't have a template marketplace, but the examples page covers common stacks with working configs.
Verify and cut over DNS
Add a custom domain and cut over DNS
- 1
Find your numeric project ID with: bunx @temps-sdk/cli projects show -p my-app --json (look for the id field).
- 2
Confirm your app works at the Temps preview URL before touching DNS.
Checkpoint: Open the preview URL and run your test suite first.
- 3
Go to Project then Settings then Domains then Add Domain.
- 4
Add the A or CNAME record shown at your DNS provider.
- 5
Temps provisions TLS automatically.
Checkpoint: Keep your Railway project running for 48 hours as a fallback in case you need to roll back.
- Confirm your app works at the Temps preview URL before touching DNS
- Go to Project → Settings → Domains → Add Domain
- Add the A or CNAME record shown
- Temps provisions TLS automatically
Keep your Railway project running for 48 hours as a fallback.