Docs Getting started
Coming from Railway, Heroku or Vercel
This page maps Railway, Heroku and Vercel to Dawnrose, so you can move an app one piece at a time. For how Dawnrose is organized, see the introduction.
Side by side
| Dawnrose | Railway | Heroku | Vercel |
|---|---|---|---|
| Project | Project | App | Project |
| Service | Service | Process type or add-on | The app itself |
| Environment | Environment | Pipeline stage | Production, Preview |
| Pull request environment | PR environment | Review app | Preview deployment |
| Variables | Variables | Config vars | Environment variables |
| Cron service | Cron schedule | Heroku Scheduler | Cron job |
dawnrose.json | railway.json | Procfile | vercel.json |
From Railway
Railway uses the same building blocks, so most things carry over by name.
- References such as
${{ Postgres.DATABASE_URL }}and${{ shared.KEY }}work as written when the services keep their names, with or without spaces inside the braces. See References. - Private hostnames change from
<service>.railway.internalto<service>.dawnrose.internal. - Provided variables start with
DAWNROSE_, such asDAWNROSE_PRIVATE_DOMAINandDAWNROSE_PUBLIC_DOMAIN. Not everyRAILWAY_variable has one; see the full list. - railway.json isn’t read, but dawnrose.json has the same
buildanddeploysections and the same names for the fields it has, such asbuildCommand,startCommand,preDeployCommand,healthcheckPathandcronSchedule. Copy it todawnrose.json. Fields Dawnrose doesn’t know are ignored. SetbuildertoAUTOorDOCKERFILE: Nixpacks builds aren’t available. - CLI.
up,link,run,shell,logs,addanddomainhave the same names indawn, andrailway variablesisdawn vars.
From Heroku
- Builds. There are no buildpacks. Dawnrose detects Node.js, Python, Go and static sites and writes a Dockerfile for them. For other languages, such as Ruby, PHP or Java, add a
Dockerfile. See Builds. - Procfile. The
web:line is the start command for Node.js and Python builds, unless you set one. Other lines aren’t read: put arelease:command in the service’s pre-deploy command, and run aworker:as a second service from the same repository with that start command. A worker doesn’t need to listen on a port. - Add-ons. Adding a database doesn’t set
DATABASE_URLon your app the way a Heroku add-on does. Add Postgres or Redis from a template and reference it:DATABASE_URL=${{ Postgres.DATABASE_URL }}orREDIS_URL=${{ Redis.REDIS_URL }}. For other add-ons, use the provider directly and keep its keys in sealed variables. - Dynos become replicas, each with a CPU and memory limit.
- CLI.
heroku config:setisdawn vars set,heroku logs --tailisdawn logs -f, andheroku runis closest todawn exec, which runs in a running replica.git push herokubecomes a push to GitHub with auto-deploy on, ordawn up.
From Vercel
- Next.js builds as a Node.js app: Dawnrose runs your
buildscript, then yourstartscript (next start) as a server that keeps running on$PORT. API routes run in the same server. - Static sites. A Vite, Create React App, Angular or Astro project with a build script and no start script is served by nginx (see Builds). There’s no fallback to
index.html, so reloading a client-side route gets a 404 unless you use your ownDockerfileand nginx config. - Functions. A Dawnrose function is one TypeScript or Python file with no packages, and an HTTP function listens on
$PORT. Anything bigger is a service. Services keep running unless you set Sleep after idle. - vercel.json isn’t read. Move redirects, rewrites and headers into your app. A cron job becomes a cron service, which runs a command rather than calling a path.
- Previews become pull request environments on Hobby and Pro, deploy hooks the service’s deploy hook, and Blob storage an S3-compatible bucket.
- CLI.
vercelisdawn up, andvercel env pullisdawn vars pull > .env.
Moving a database
Add the database from a template, turn on its TCP proxy, then copy the data from your machine with the usual tools. Stop writes to the old app first. For Postgres:
pg_dump --format=custom --no-owner --no-acl "$OLD_DATABASE_URL" > app.dump
dawn shell --service Postgres
pg_restore --no-owner --no-acl --dbname "$DATABASE_PUBLIC_URL" app.dump
The Postgres template runs version 16. Other databases work the same way, with their own tools and their *_PUBLIC_URL variable. Turn the proxy off when you’re done.
Moving a domain
Add the domain to the service and create its TXT record while the CNAME still points at your old host: verification only checks the TXT record. Switch the CNAME once the app works on its generated domain. The certificate is issued when the CNAME reaches Dawnrose. See Custom domains.
Let your agent do it
With your agent connected over MCP, you can hand it the move: it creates services and databases, sets variables, deploys, reads build logs and fixes what fails.
What isn’t there yet
Dawnrose is new. Check that you don’t depend on these:
- One region for now. The FAQ says where apps run.
- No SLA, published uptime figure or status page.
- No GPUs.
- No SAML or single sign-on. People sign in with Google, GitHub or an email and password.
Checklist
- The app listens on
0.0.0.0and the port in$PORT. - Each process is a service with a start command.
- Variables are copied, secrets sealed, and values the old platform set for you, such as
DATABASE_URL, are references. - Data is restored, and the app works on its generated domain.
- Your domain points at Dawnrose, and the old app is stopped.