Deploy Apps on RailPush
RailPush deploys web apps, APIs, workers, cron jobs, static sites, and Docker images from one control plane. Connect a GitHub repo, push to the RailPush remote, paste a Docker image, or use a Deploy to RailPush button.
Every deploy gets a build log, health check, rollout state, deploy history, rollback path, and a live HTTPS URL.
Pick a deploy path
| Path | Best for | What RailPush handles |
|---|---|---|
| GitHub import | Apps that already live in GitHub | Repo connection, framework detection, build command, start command, auto deploys |
| Git push | Heroku-style terminal deploys | Git Smart HTTP remote, build trigger, deploy status in terminal output |
| Dockerfile | Custom runtimes and monorepos | Docker build context, Dockerfile path, command override, health checks |
| Prebuilt image | Existing CI pipelines | Pulling the image, setting ports/env vars, rolling out the service |
| Static site | SPAs and docs sites | Build output hosting, nginx, TLS, cache headers |
| Deploy button | Public templates and examples | One-click repo import with optional branch and service name |
Quick start from GitHub
- Sign in to RailPush and click New -> Web Service.
- Pick a GitHub repository and branch.
- Review the detected framework, build command, start command, and port.
- Add required environment variables such as
DATABASE_URL,SENTRY_DSN,DISCORD_BOT_TOKEN, or provider API keys. - Create the service. RailPush builds, deploys, health-checks, and gives you a live URL.
git push origin main
If auto deploy is enabled, the push starts a new deployment. You can also trigger deploys from the dashboard, REST API, CLI, or MCP tools.
Heroku to RailPush mapping
| Heroku concept | RailPush equivalent |
|---|---|
| Dyno | Service |
| Worker dyno | Worker service |
| Heroku Postgres | Managed PostgreSQL |
| Heroku Redis | Managed Redis |
| Config vars | Service environment variables |
| Procfile web process | Start command |
git push heroku main | git push railpush main |
| Add-ons | Managed databases, object storage, queues, log drains, and alerts |
For a practical migration, start with Git Push Deploys, move config vars with Environment Variables, then provision PostgreSQL or Redis as needed.
Deploy configuration
RailPush can infer most settings, but explicit configuration keeps migrations predictable:
services:
- type: web
name: api
repo: https://github.com/acme/api
branch: main
buildCommand: npm ci && npm run build
startCommand: npm start
port: 3000
healthCheckPath: /health
plan: s
envVars:
- key: NODE_ENV
value: production
- key: DATABASE_URL
value: ${{ databases.api-db.internal_url }}
is_secret: true
The same settings can be managed from the dashboard, API, CLI, or MCP server.
Slow cold starts and rollout timeout
After a build, RailPush waits for the new pod to pass its health check before marking the deploy live. If the pod is not ready within the rollout timeout (5 minutes by default), the deploy fails and RailPush auto-rolls-back to the last good image.
Apps with a slow cold start — large dependency/module graphs, JIT or cache warmup, or a first-pull of a big image onto a cold node — can legitimately need longer. Raise the budget with a service environment variable and redeploy:
| Env var | Default | Bounds | Effect |
|---|---|---|---|
RAILPUSH_ROLLOUT_TIMEOUT_SECONDS | 300 | 60–1800 | How long the rollout waits for the new pod to become ready before failing and rolling back. The startup-probe budget and the Kubernetes progress deadline are scaled up automatically to match, so this single knob is usually all you need. |
RAILPUSH_STARTUP_FAILURE_THRESHOLD | 60 | 1–600 | Number of consecutive startup-probe failures tolerated before the container is restarted. Effective startup budget = this × interval. Set only if you want a startup budget larger than the rollout timeout implies. |
RAILPUSH_STARTUP_INTERVAL_SECONDS | 5 | 1–300 | Seconds between startup-probe attempts. |
For example, to give a service a 12-minute cold-start window, set RAILPUSH_ROLLOUT_TIMEOUT_SECONDS=720 and redeploy.
The fastest durable fix is usually to start listening on your port early — bind the HTTP server before running migrations or other startup work, and do that work asynchronously. A health check that returns 200 as soon as the port is open lets the rollout succeed while initialization continues in the background.
Long-lived connections and graceful shutdown
A deploy is marked live as soon as the new pod is Ready — it does not wait for the old pod to finish shutting down. Old pods drain in the background up to the service's Max Shutdown Delay (terminationGracePeriodSeconds), which is configured per-service and is independent of RAILPUSH_ROLLOUT_TIMEOUT_SECONDS. The rollout timeout does not change the shutdown grace.
If your app holds long-lived connections (SSE, WebSockets, streaming responses), raise Max Shutdown Delay so the old pod can close them cleanly on SIGTERM. Because the rollout completes on the new pod's readiness, a large shutdown delay no longer slows down or fails deploys.
Services with a persistent disk
A persistent disk is single-writer (ReadWriteOnce) — it can only be attached to one running pod at a time. Services with a disk therefore deploy with the Recreate strategy: the old pod is fully stopped (releasing the disk) before the new pod starts. This means a brief gap in availability during each deploy, which is unavoidable for a single-writer volume. Services without a disk keep the default zero-downtime rolling strategy.
Related deploy guides
- Git Push Deploys for Heroku-style terminal deploys.
- Docker Deploys for custom Dockerfiles and prebuilt images.
- Static Sites for SPAs, docs, and pre-rendered sites.
- Preview Environments for pull request deploys.
- Scale to Zero for free-tier sleep and wake behavior.