One of my mentees here in codementor.io encountered a problem when running Python and Ruby together on Heroku. That session inspired me to write this tutorial—how to run more than one environment on Heroku.
PROBLEM
The project was working in Cloud9 without any problems. But after deploying to Heroku, logs from Heroku was giving errors about Python problems. The scraper that was written in Python was not working. Steve, my mentee, had created an old test environment on Cloud9 for me to work on his problem.
SOLUTION
This solution uses this guideline from Heroku.
I solved the problem by using multi-buildpacks for Python and Ruby.
Heroku multi-buildpacks
By mistakenly saying, Buildpacks are responsible for deploying and running your Heroku apps. There are many Buildpacks (many can be seen here and here).
There are different Buildpacks for Ruby and Python, for example.
So, If someone wants to deploy Ruby and Python together on Heroku, he needs to use “multiple buildpacks”. Which means that when deploying to Heroku, Heroku will use different Buildpacks to deploy and run your applications for Ruby and Python, for example. Each Buildpack will create a specific compilation environment.
Running apps with Procfile
Steve’s application needs to run on Puma Server (the default web server of Ruby on Rails). So, I needed to create a Procfile
to launch his server automatically after it’s deployed to Heroku. Procfiles are responsible for launching code on Heroku after deployment. For example, you can launch web servers and long-running tasks. See more from here.
So, I created a Procfile file like this on his project’s root:
# Procfile
web: bundle exec rails server -p $PORT
worker: python scraper.py
In multiple buildpacks, the order of the buildpacks are very important.
I needed to add Ruby buildpack as the last one because Steve would be running a Puma web server for Ruby, as I said before. If I hadn’t done it like that, Steve wouldn’t be able to run his Ruby server on Heroku. So, I added Python buildpack first, and then added Ruby buildpack later. Together, they become “the mighty multiple buildpack”, ready to use on Heroku.
# commandline commands
heroku buildpacks:clear # remove all of the buildpacks first
heroku buildpacks:add heroku/python # add the python buildpack first
heroku buildpacks:add heroku/ruby # add the ruby buildpack second
heroku buildpacks # to see what I have done
# === golden-ratio-1618 Buildpack
# 1. heroku/python
# 2. heroku/ruby
Internals of a Buildpack
To know more about the internals of a Buildpack, you can review the Github source of a Buildpack, for example, Ruby. bin/detect
file is especially important. You can see the source code of this file to see what is needed for Heroku to deploy your app, or it will fail when deploying. For example, for Ruby, the check is done for Gemfile
which needs to be present in the root directory of your app.
Python required packages were missing
But after adding all of the buildpacks, the project is still not functioning on Heroku, yet. That was because the Python requirements.txt
file was missing. That file is responsible for adding the required Python packages to your app to be installed on Heroku automatically after each deployment (like Gemfile
in Ruby). This is needed because, every time you deploy, Heroku launches a new instance and initializes it by running those files. They are the required files for the environment like Python and Ruby.
I also needed to verify the behavior in the local, so I ran pip install -r requirements.txt
as a command to install the required packages to the local.
And, I tested the setup with: heroku local
command. See more about it here.
I put the required packages by looking to Python scraper’s header code, which was the needed scraper file to be run by Heroku by my mentee, the lines starting with import
. One of them was lxml
. I found its latest version number by looking at its github page (to the tags).
So, we created a requirements.txt file like this:
# requirements.txt file
lxml==3.6.4
So, after delivering the training session, Steve responded like this:
Man, I really love these reactions.
Conclusion
With this article, my aim was that trying to show how I handled a mentee’s request and let you know about how to run multiple-buildpacks on Heroku. Of course, there are many details I skipped over. Maybe, those can be the next article’s topics. Similarly, you can also read more tutorials about Heroku, like: how to parse dashboard Heroku or how to get push notifications when your Heroku app is deployed. See you next time.