Replacing Railway, Render or Fly.io with a controllable target platform? WZ-IT provides PaaS and cloud migration from EUR 1,990 excluding VAT through target acceptance and can take over ongoing operations.
A comparison of Railway, Render and Fly.io migrations to private infrastructure starts by identifying which platform capabilities the application actually uses. A stateless web service transfers differently from a system with several workers, volumes, private services, databases and scheduled jobs.
This article compares the shared layers and technical differences. Separate implementation guides cover Railway, Render and Fly.io.
Contents
- Shared core and important differences
- Migrate Railway
- Migrate Render
- Migrate Fly.io
- Choose the target platform
- Data and persistent volumes
- Networking, domains and internal services
- Cut over without an uncontrolled big bang
Shared core and important differences
| Layer | Railway | Render | Fly.io |
|---|---|---|---|
| Deployment | services from Git or images | services and Blueprint configuration | apps and Machines from images and fly.toml |
| Configuration | variables and references | environment groups and service variables | secrets and app configuration |
| Persistence | volumes and database services | persistent disks and database services | volumes attached to Machines |
| Background work | separate services and cron | background workers and cron jobs | processes, Machines and scheduling by design |
| Networking | public and private domains | private and public services | private 6PN networking, services and regions |
| Scaling | per service | per service | Machines and regions |
The target does not need to reproduce every source interface. It needs to implement the required behaviour through understandable components.
Migrate Railway
Start with Railway projects, environments and services. Relevant controls include:
- build source or container image
- start command and health check
- service variables and references between services
- public and private domains
- volumes, mount paths and actual data
- PostgreSQL, MySQL, Redis or other data products
- restart and scaling settings
- deployment triggers and connected repositories
Railway variables can reference values from other services. On the target, these become static connections or values generated through secret management. The name of a variable is insufficient: determine which service creates it, which environment uses it and whether it should be rotated during cutover.
Treat persistent volumes separately from the application. For databases, a consistent dump, restore or replication path is normally safer than copying a running database directory.
Migrate Render
Render can describe infrastructure through a Blueprint. This definition is a useful inventory source but may not include every dashboard setting, secret and external dependency.
Capture in particular:
- web services and private services
- background workers and cron jobs
- build and start commands
- environment groups and individual secrets
- persistent disks and mount paths
- managed databases and caches
- domains, redirects and health checks
- region and scaling
A Render service filesystem without a persistent disk is not durable application storage. Check whether the application still writes local files and has only avoided a visible loss so far. Replace such implicit assumptions with object storage, a volume or a database on the target.
Migrate Fly.io
Fly.io represents applications through Machines, volumes, services, regions, secrets and fly.toml. An application can therefore be more distributed than a conventional single service.
Inventory:
- apps, organisation and regions
- Machines, process groups and images
- services, ports, checks and autostart behaviour
- secrets and non-secret configuration
- volumes, Machine attachment and replication model
- private communication across the Fly network
- public IPs, Anycast and domains
- databases, tunnels and external dependencies
Fly Volumes are local persistent storage in one region and do not automatically become a shared cluster filesystem. Determine whether the application expects local persistence, database replication or real shared storage in the target design.
If the current deployment spans several regions, do not silently collapse it onto one target server. Assess latency, failover, data consistency and the availability objective before consolidation.
Choose the target platform
| Target | Suitable when | Additional ownership |
|---|---|---|
| Docker Compose | a few bounded services on one system are sufficient | organise deployments, secrets, updates and recovery |
| Coolify | Git deployments, domains and several apps need a convenient control layer | operate platform, hosts, backups and monitoring |
| Kubernetes | multiple nodes, teams, policies or dynamic orchestration are lasting requirements | operate cluster, add-ons, networking, storage and upgrades |
| separate servers | databases, workers or security zones should be isolated deliberately | manage and connect several systems consistently |
Service count alone does not decide. Recovery objectives, team structure, growth, security boundaries and existing operating skills matter too. Kubernetes vs Docker Compose vs Coolify compares these platform layers in more detail.
Data and persistent volumes
Answer four questions for each stateful component:
- What is the authoritative data set? Database, volume, object storage or external service.
- How is a consistent export created? Dump, snapshot, API export, file sync or replication.
- How is completeness verified? Row counts, checksums, object counts and functional tests.
- How are new writes handled? Freeze, final delta sync or continuous replication.
Do not copy volume data without validation. User and group IDs, permissions, symlinks, locks and application-level consistency can all affect restart on the target.
Networking, domains and internal services
PaaS platforms generate many network details automatically. The target must make them explicit:
- public endpoints and TLS
- private service-to-service traffic
- firewall rules and outbound connections
- DNS and TTL before cutover
- WebSocket and streaming behaviour
- email, OAuth redirects and webhooks
- stable outbound IPs where partners allow-list them
- administrative access without unnecessary public ports
Internal source hostnames are not portable. Change applications to new service names or target addresses and test them in staging first.
Cut over without an uncontrolled big bang
A controlled migration separates preparation from switching:
- Build target infrastructure and delivery.
- Start applications without production data.
- Move test data or an initial data set.
- Validate user journeys, jobs, integrations and recovery.
- Rehearse the final data path and write boundary.
- Switch DNS and applications in the agreed window.
- Run smoke tests and observe monitoring.
- Retire the source only after the rollback window.
The general PaaS exit checklist consolidates acceptance controls. If the source is Vercel, migrating Vercel to Coolify or Hetzner additionally covers Next.js, edge functions and preview deployments.










