Migrate from Render to Bahriya
Render runs your app as a web service, background worker, or cron job, built from your repository and configured through environment groups or a render.yaml. Bahriya uses the same service shapes but deploys a container image you build, spread across the regions you choose, with configuration supplied as environment variables and secrets. This guide maps each Render concept to Bahriya and walks the move.
Render runs your app as a web service, background worker, or cron job, built from your repository and configured through environment groups or a render.yaml. Bahriya uses the same service shapes but deploys a container image you build, spread across the regions you choose, with configuration supplied as environment variables and secrets. This guide maps each Render concept to Bahriya and walks the move.
What maps to what
| Render | Bahriya |
|---|---|
| Web service | An HTTP container |
| Background worker | A worker container |
| Cron job | A cron job |
| Build from repo / native runtime | A Dockerfile producing an image |
render.yaml blueprint | Container settings (Console fields or Reis flags) |
| Environment groups | Environment variables and secrets |
| Secret files / secret env vars | Secrets (encrypted, injected as env vars) |
| Render Postgres | An external database via a connection secret |
| Render Key Value / Redis | Bahriya Memcached, or an external cache via a secret |
| Instance type / scaling | Resources, replicas, and autoscaling |
onrender.com domain + custom domains | Default hostname with automatic TLS + custom domains |
1. Containerise
If you deploy a Render Docker service you already have a Dockerfile — carry it over. If you use a native runtime, write a Dockerfile that installs dependencies and starts your app on a single port:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8080
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]Render sets a PORT for you; keep reading it from the environment and bind to 0.0.0.0. Declare the port with --port on Bahriya (default 8080). Build and push the image:
docker build -t ghcr.io/myorg/api:v1.0.0 .
docker push ghcr.io/myorg/api:v1.0.02. render.yaml and environment groups to env and secrets
Render's blueprint and environment groups collect your configuration in one place. On Bahriya, split it:
- Non-sensitive values become plain environment variables.
- Sensitive values (database URLs, API keys, secret files) become secrets — created once, attached to the project, and wired to the variable name your app expects.
Health check paths defined in render.yaml map to --healthcheck — see Health Checks.
3. Managed database and cache
- Database. Render Postgres becomes an external database of your choosing, reachable over the network, with its connection string stored as a secret wired to
DATABASE_URL. Provision the new database, migrate your data, and confirm connectivity from a Bahriya container before cutting over. - Cache. For a Memcached-compatible cache use Bahriya Memcached. For Redis or another engine, connect to an external instance via a secret, exactly as you do the database.
4. Scaling
Render scales by instance type and count. On Bahriya, set minimum CPU (millicores) and memory (MB), a replica count, and — for automatic scaling — a maximum replica count. Setting --max_replicas above --replicas enables autoscaling between the two. See Resources and Scaling.
5. Deploy
From the Console follow Deploy Your First Container, or with Reis:
reis container:create \
--type http \
--name "Web API" \
--handle web-api \
--image ghcr.io/myorg/api:v1.0.0 \
--registry ghcr \
--port 8080 \
--healthcheck /healthz \
--cpu 500 \
--memory 512 \
--replicas 2 \
--max_replicas 8 \
--regions falkenstein-1 \
--regions virginia-1 \
--env APP_ENV=production \
--secrets DATABASE_URL=database-urlChoose regions close to your users from the four that are live — see Regions.
6. Point your domain and cut over
Your container is reachable at https://web-api.<region>.x.on.bahriya.app with automatic TLS. Test there, then add your production domain, verify it, and move DNS across — see Custom Domain Setup. Keep the Render service running until traffic has drained, then suspend and remove it.