One of the great developments that Heroku has open sourced are Buildpacks. Buildpacks are a collection of scripts that detect your application language/framework and install the required interpreters, libraries, etc. to run.
Buildstep is a great tool developed by progrium which uses these buildpacks to transform any application code (supported by any of the included buildpacks) into a self-sufficient Docker image. It is also used in the extremely popular Dokku project made by the same author.
In order to take full advantage of this amazing tool, we have created a base image called tutum/buildstep which can be used directly in a Dockerfile to produce application images with minimum effort.
Let’s see a simple example.
Converting a Django app into a Docker image using buildstep
Imagine we have a Django app and we want to convert it into a Docker image to be able to move it between hosts. In the application code folder, we’ll create the following Dockerfile:
FROM tutum/buildstep EXPOSE 8000 CMD ["python", "manage.py", "runserver", "8000"]
That’s it. The minimum required information for tutum/buildstep to work is the port to expose and the command used to launch your application. Adding the application code and setting the working directory is automatically done by tutum/buildstep using the ONBUILD directive.
Let’s build it:
$ docker build -t fermayo/myapp . Uploading context 99.84 kB Uploading context Step 0 : FROM tutum/buildstep # Executing 3 build triggers Step onbuild-0 : RUN mkdir -p /app ---> Running in 0d65c9537e8f ---> 9d7c609c38ce Step onbuild-1 : ADD . /app ---> 3b7ff5e4f126 Step onbuild-2 : RUN /build/builder ---> Running in 6e7a796d93c3 Python app detected -----> No runtime.txt provided; assuming python-2.7.6. -----> Preparing Python runtime (python-2.7.6) -----> Installing Setuptools (2.1) -----> Installing Pip (1.5.4) -----> Installing dependencies using Pip (1.5.4) Downloading/unpacking Django==1.6.2 (from -r requirements.txt (line 1)) Installing collected packages: Django Successfully installed Django Cleaning up... -----> Discovering process types Procfile declares types -> web ---> 8758f592da19 ---> 8758f592da19 Step 1 : EXPOSE 8000 ---> Running in 3f10763973a8 ---> db32c55e948b Step 2 : CMD ["python", "manage.py", "runserver", "8000"] ---> Running in 7d122de7f8d3 ---> ed1a72bfa5d0 Successfully built ed1a72bfa5d0 Removing intermediate container 0d65c9537e8f Removing intermediate container d79aa6530641 Removing intermediate container 6e7a796d93c3 Removing intermediate container 3f10763973a8 Removing intermediate container 7d122de7f8d3
Our application is now Dockerized into an image called fermayo/myapp. Let’s try it out:
$ docker run -d -p 8000 fermayo/myapp
We have now our Django app up and running!
Converting a Heroku app into a Docker image using buildstep
Buildstep also supports using a Procfile to define the application process types. The following would be a simple Procfile for our Django app we used earlier:
web: python manage.py runserver 8000
To use this instead of manually defining the command, we can create the following Dockerfile:
FROM tutum/buildstep EXPOSE 8000 CMD ["/start", "web"]
By entering the desired process type name in the CMD directive we are defining which command should be used to start the application.
Running your app without building an image using buildstep
If your application is stored in a git repository, you can also run tutum/buildstep passing in an environment variable GIT_REPO with its address and the container will clone the repo and install the dependencies, etc. on the fly:
# Without a Procfile $ docker run -d -p 8000 -e GIT_REPO=https://github.com/fermayo/hello-world-django.git tutum/buildstep python manage.py runserver 8000
# With a Procfile (or relying on the default Procfile provided by the buildpack) $ docker run -d -p 8000 -e GIT_REPO=https://github.com/fermayo/hello-world-php.git -e PORT=8000 tutum/buildstep /start web
So there is no need to build anything.
Give it a try!
This is a great way to getting started with Docker. Let us know if it works for your language/framework and how would you make it better.
Thanks for reading!
Due to a change in the upstream image, applications are now run without root privileges, so port numbers lower than 1024 are unavailable for binding. The image tutum/buildstep and this blog post have been updated appropriately.