Heroku and Convox are both Platforms-as-a-Service designed around The Twelve-Factor App methodologies.
Convox is open-source and built entirely on AWS cloud services. It enables you to deploy your apps to your own AWS account for maximum control. Depending on your application and engineering team, migrating an app to Convox could unlock security, reliability, performance, cost and/or operational improvements.
Many parts of the Heroku platform map directly to Convox:
|Codebase||Git Repo||Git Repo|
$ heroku config
$ convox env
|Build / Release / Run||
$ git push heroku master
$ heroku releases
$ convox deploy
$ convox releases
$ heroku ps
$ convox ps
$ heroku scale
$ convox scale
$ heroku addons
$ convox resources
$ heroku logs
$ convox logs
$ heroku run
$ convox run
$ convox exec
Other parts are similar, but represent more significant changes to your apps:
$PORT environment variable
ports: - 80:8000
$ heroku local
$ convox start
Cedar Stack Image
Docker Base Image
IaaS / AWS
This guide explains the differences of the platforms, and walks you through the steps required to migrate an app.
Let’s start with a simple Python and Postgres Heroku app. The codebase is in a GitHub repo.
First, let’s create an empty Convox app:
convox apps create Creating app python-getting-started... CREATING
If you don’t have Convox set up in your AWS account, refer to the Getting Started doc.
Convox uses Heroku’s buildpacks to build images for apps. The
convox init command will generate a Dockerfile to describe how to build your app with the appropriate buildpack.
To get started, run:
convox init Updating convox/init... OK Initializing a python app Building app metadata. This could take a while... OK Writing docker-compose.yml... OK Writing Dockerfile... OK Writing .dockerignore... OK
|Heroku uses a Procfile to define process types and commands.||Convox uses a docker-compose.yml file to define service types and commands.|
convox init command generated a
docker-compose.yml file for our Convox app. Every process type and command in
Procfile is added as a service and command to
version: "2" services: database: image: convox/postgres ports: - 5432/tcp volumes: - /var/lib/postgresql/data web: build: context: . command: gunicorn gettingstarted.wsgi --log-file - environment: - PORT=4001 labels: convox.port.443.protocol: tls links: - database ports: - 80:4001/tcp - 443:4001/tcp
Now our app can be deployed to Convox:
convox deploy $ convox deploy Deploying python-getting-started Creating tarball... OK Uploading: 9.56 KB / 9.39 KB [===========================] 101.84 % 0s Starting build... OK running: docker build -f /tmp/407003531/Dockerfile -t python-getting-started/web /tmp/407003531 Sending build context to Docker daemon 46.08 kB Step 1 : FROM heroku/cedar ... Successfully built d9c7f075f169 running: docker tag running: docker push web.BXMCXIIFZSQ: digest: sha256:62815bd42414f508c7ce326a42dbc7df484beaf175ee5581ef7c0fda36dad21a size: 1994 Release: RRYXNKQRAPD Promoting RRYXNKQRAPD... UPDATING convox apps info $ convox apps info python-getting-started Name python-getting-started Status running Release RRYXNKQRAPD Processes database web Endpoints internal-python-getting-started-AT3UMZ4-i-500316325.us-east-1.elb.amazonaws.com:5432 (database) python-getting-started-w-IC7MLNI-1004687141.us-east-1.elb.amazonaws.com:80 (web) python-getting-started-w-IC7MLNI-1004687141.us-east-1.elb.amazonaws.com:443 (web)
Sure enough, our app is available at the endpoint.
|Heroku uses addons to provision database services, and sets app config with service connection information.||Convox uses resources to provision database services, and sets app environment with service connection information.|
The previous step deployed a database container. A containerized database is good for development and verification purposes, but in production we’ll want a “real” hosted database. There are two strategies.
Reuse Heroku Addons
Both Heroku and Convox run in the AWS cloud. As long as the Heroku addons and Convox app are in the same region, access between them is fast. So the simplest strategy is to connect the Convox app to the Heroku addons by copying over the config.
# copy Heroku config to Convox app environment heroku config -s | convox env set Updating environment... OK To deploy these changes run `convox releases promote RWGFPGSELVA` convox releases promote RWGFPGSELVA Promoting RWGFPGSELVA... OK # verify the Convox environment, database connection and data convox run web python manage.py migrate Running migrations: No migrations to apply.
The other strategy is to create new databases and migrate data. This has the security advantage of moving your database and data into a VPC that is not acessable to anything but your Convox app.
To do this, we will backup the Heroku database, and restore it into a new, private Postgres database.
# create the Convox resource and open a local proxy convox resources create postgres Creating postgres-2098 (postgres)... CREATING convox resources proxy postgres-2098 proxying 127.0.0.1:5432 to dev-east-postgres-2098.cyzckls48pd3.us-east-1.rds.amazonaws.com:5432 # stop writing data and capture a backup heroku maintenance:on heroku pg:backups:capture Backing up DATABASE to b001... done heroku pg:backups:download Getting backup from ⬢ pure-basin-53177... done, #1 Downloading latest.dump... # restore the Convox database from the backup pg_restore -Ov -d app -h localhost -n public -U postgres latest.dump pg_restore: connecting to database for restore Password: pg_restore: creating TABLE "public.auth_group" pg_restore: creating SEQUENCE "public.auth_group_id_seq" ...
Scale Down Database Containers
Now that we’ve got a real database set up, we’ll want to scale down the database container so that we’re not running unnecessary resources. Scaling the container to a count of -1 will also deprovision its load balancer, saving us money on our AWS bill.
convox scale database --count=1
Our first deploy to Convox is just the beginning. From here you can explore: