Migration Guide
This guide helps you migrate your applications to Convox Cloud from other platforms. Whether you're coming from Heroku, Render, Railway, or even a self-hosted Convox Rack, we'll walk you through the process step by step.
Quick Migration Overview
From Platform | Effort Level | Key Changes | Migration Time |
---|---|---|---|
Heroku | Low | Procfile → convox.yml | 30 minutes |
Render | Low | render.yaml → convox.yml | 30 minutes |
Railway | Medium | Add Dockerfile, create convox.yml | 1 hour |
Convox Rack | Very Low | Change CLI commands | 15 minutes |
Docker Compose | Low | docker-compose.yml → convox.yml | 30 minutes |
Migrating from Heroku
Prerequisites
- Heroku CLI installed
- Application source code
- Database backups (if applicable)
Step 1: Export Heroku Configuration
# List your Heroku apps
$ heroku apps
# Export environment variables
$ heroku config -a your-heroku-app -s > .env.heroku
# Get buildpack info
$ heroku buildpacks -a your-heroku-app
Step 2: Create Dockerfile
Heroku uses buildpacks, but Convox uses Docker. Create a Dockerfile
based on your buildpack:
For Node.js apps:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
For Ruby/Rails apps:
FROM ruby:3.1-alpine
RUN apk add --no-cache build-base postgresql-dev
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install --deployment --without development test
COPY . .
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
For Python apps:
FROM python:3.11-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]
Step 3: Convert Procfile to convox.yml
Heroku Procfile:
web: node server.js
worker: node worker.js
release: node migrate.js
Convox convox.yml:
services:
web:
build: .
command: node server.js
port: 3000
scale:
count: 1
cpu: 250
memory: 512
health: /health
worker:
build: .
command: node worker.js
scale:
count: 1
cpu: 250
memory: 512
migrate:
build: .
command: node migrate.js
scale:
count: 0 # Template service for migrations
Step 4: Handle Add-ons
Map Heroku add-ons to Convox resources:
Heroku Add-on | Convox Equivalent |
---|---|
Heroku Postgres | postgres resource or external |
Heroku Redis | redis resource or external |
SendGrid | Use API with environment variables |
Papertrail | Configure syslog or use external |
New Relic | Add agent to Dockerfile |
Example with database:
resources:
database:
type: postgres
options:
storage: 10
services:
web:
build: .
port: 3000
resources:
- database
Step 5: Migrate Data
# Export from Heroku Postgres
$ heroku pg:backups:capture -a your-heroku-app
$ heroku pg:backups:download -a your-heroku-app
# Import to Convox
$ convox cloud resources import database --file latest.dump -a myapp -i production
Step 6: Deploy to Convox Cloud
# Create machine via Convox Console first
# Log into console.convox.com > Cloud Machines > New Machine
# Set environment variables from Heroku export
$ convox cloud env set $(cat .env.heroku) -a myapp -i production
# Deploy application
$ convox cloud deploy -i production
# Run migrations
$ convox cloud run migrate "node migrate.js" -a myapp -i production
Step 7: Update DNS
Point your domain from Heroku to Convox:
# Get Convox app URL
$ convox cloud services -a myapp -i production
# Update DNS CNAME from:
# your-app.herokuapp.com
# To:
# web.myapp.cloud.convox.com
Migrating from Render
Step 1: Export Render Configuration
Your render.yaml
defines your services. We'll convert this to convox.yml
.
Render render.yaml:
services:
- type: web
name: myapp
env: node
buildCommand: npm install
startCommand: npm start
envVars:
- key: NODE_ENV
value: production
- type: worker
name: background-worker
env: node
buildCommand: npm install
startCommand: npm run worker
databases:
- name: myapp-db
plan: starter
Step 2: Create Dockerfile
Since Render handles builds automatically, you'll need a Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Step 3: Convert to convox.yml
Convox convox.yml:
environment:
- NODE_ENV=production
resources:
database:
type: postgres
options:
storage: 10
services:
web:
build: .
command: npm start
port: 3000
scale:
count: 1
cpu: 500
memory: 512
resources:
- database
worker:
build: .
command: npm run worker
scale:
count: 1
cpu: 250
memory: 512
resources:
- database
Step 4: Migrate and Deploy
# Create Convox machine via Console
# Log into console.convox.com > Cloud Machines > New Machine
# Deploy to Convox
$ convox cloud deploy -i production
# Copy environment variables
$ convox cloud env set DATABASE_URL=postgres://... -a myapp -i production
Migrating from Railway
Railway uses automatic builds and nixpacks. You'll need to be more explicit with Convox.
Step 1: Create Dockerfile
Railway automatically detects your framework. With Convox, create an explicit Dockerfile:
# Example for Next.js app
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["npm", "start"]
Step 2: Create convox.yml
services:
web:
build: .
port: 3000
scale:
count: 1-3
cpu: 500
memory: 1024
targets:
cpu: 70
health: /api/health
Step 3: Handle Railway Variables
# Export from Railway (manually copy from dashboard)
# Then set in Convox
$ convox cloud env set \
DATABASE_URL=postgres://... \
REDIS_URL=redis://... \
SECRET_KEY=... \
-a myapp -i production
Step 4: Deploy
# Create machine via Console first
$ convox cloud deploy -i production
Migrating from Self-Hosted Convox Rack
Migration from a self-hosted Rack to Cloud is straightforward since the application format is the same.
Step 1: Export Application
# From your existing rack
$ convox apps export myapp --file myapp.tgz
$ convox env -a myapp > myapp.env
Step 2: Create Cloud Machine
Log into the Convox Console:
- Navigate to Cloud Machines
- Click "New Machine"
- Select size and region
- Create the machine
Step 3: Import Application
# Import the app
$ convox cloud apps import myapp --file myapp.tgz -i production
# Set environment variables
$ convox cloud env set $(cat myapp.env) -a myapp -i production
Step 4: Adjust for Cloud Limitations
Review your convox.yml
for Cloud compatibility:
Remove unsupported features:
# Remove these if present:
agents: # Not supported in Cloud
volumes: # No persistent volumes in Cloud
privileged: # Limited in Cloud
Handle persistent storage differently:
# Instead of volumes, use external storage
services:
web:
environment:
- S3_BUCKET=myapp-uploads # Use S3 instead of volumes
Step 5: Update CI/CD
Update your deployment commands:
Before (Rack):
convox deploy -a myapp -r production
After (Cloud):
convox cloud deploy -a myapp -i production
Migrating from Docker Compose
Step 1: Convert docker-compose.yml
Docker Compose:
version: '3'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- db
- redis
worker:
build: .
command: npm run worker
depends_on:
- db
- redis
db:
image: postgres:13
environment:
- POSTGRES_PASSWORD=secret
redis:
image: redis:alpine
Convox convox.yml:
environment:
- NODE_ENV=production
resources:
database:
type: postgres
cache:
type: redis
services:
web:
build: .
port: 3000
resources:
- database
- cache
worker:
build: .
command: npm run worker
resources:
- database
- cache
Step 2: Deploy
# Create machine via Console first
$ convox cloud deploy -i production
Common Migration Tasks
Database Migration
PostgreSQL
# Export from source
$ pg_dump $OLD_DATABASE_URL > backup.sql
# Import to Convox
$ convox cloud resources import database --file backup.sql -a myapp -i production
MySQL
# Export from source
$ mysqldump -h old-host -u user -p database > backup.sql
# Import to Convox
$ convox cloud resources import database --file backup.sql -a myapp -i production
MongoDB (Using External Service)
Since Convox Cloud doesn't provide MongoDB:
# Use MongoDB Atlas or similar
$ convox cloud env set MONGODB_URI=mongodb+srv://... -a myapp -i production
File Storage Migration
Convox Cloud doesn't support persistent volumes. Use object storage instead:
# Upload existing files to S3
$ aws s3 sync ./uploads s3://my-bucket/uploads
# Update app to use S3
$ convox cloud env set \
S3_BUCKET=my-bucket \
AWS_ACCESS_KEY_ID=... \
AWS_SECRET_ACCESS_KEY=... \
-a myapp -i production
Scheduled Jobs Migration
From Heroku Scheduler:
timers:
cleanup:
command: rake cleanup
schedule: "0 3 * * *"
service: web
From cron:
timers:
hourly:
command: /app/bin/hourly-task
schedule: "0 * * * *"
service: worker
SSL Certificates
Convox automatically provisions Let's Encrypt certificates:
services:
web:
domain: myapp.com,www.myapp.com
port: 3000
Migration Checklist
Pre-Migration
- Backup all data (database, files, configs)
- Document current environment variables
- Note current scaling configuration
- Identify external services and APIs
- Review application logs for issues
- Plan maintenance window
During Migration
- Create Convox Cloud machine via Console
- Create Dockerfile if needed
- Create convox.yml
- Deploy application
- Import databases
- Set environment variables
- Configure domains
- Run smoke tests
Post-Migration
- Verify all services are running
- Check application logs
- Test critical user paths
- Update DNS records
- Monitor for 24 hours
- Remove old infrastructure
Troubleshooting Common Issues
Build Failures
Problem: Build fails with "out of memory"
Solution: Optimize Dockerfile with multi-stage builds:
# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Runtime stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
Port Configuration
Problem: Application not accessible
Solution: Ensure your app binds to 0.0.0.0
:
// Wrong
app.listen(3000, 'localhost')
// Correct
app.listen(3000, '0.0.0.0')
Database Connections
Problem: Can't connect to database
Solution: Use Convox-provided environment variables:
// The DATABASE_URL is automatically set when you link a resource
const dbUrl = process.env.DATABASE_URL || 'postgres://localhost/dev'
Memory Issues
Problem: Application runs out of memory
Solution: Adjust scaling configuration:
services:
web:
scale:
memory: 1024 # Increase from 512
Getting Help
Resources
Support Channels
- Email: cloud-support@convox.com
- Community: community.convox.com
- Emergency: Contact support with your machine ID
Next Steps
After migration: