Heroku Buildpack for Common Lisp
My rework of the Common Lisp buildpack for Heroku by Mike Travers.
Differences from the Mike's buildpack:
- Doesn't install patched portableaserve and wuwei. You are free to use any webserver. If you need a version not available in quicklisp, you can fetch it as a git submodule of your application.
- Doesn't force your application to be saved into a lisp image at Heroku.
We recommend the build output to consist of full application and libraries sources
together with prebuild .fasl files to speedup loading. You can build a lisp image,
but often this will lead to problems. For example, many libraries keep static files
asdf:system-relative-pathname. If lisp image is saved and copied to another location (as it happens with build results at Heroku), those libraries will not find their static files.
To feel comfortable, read about Heroku Procfile
and Buildpack. You will then understand,
that Heroku allows you to use any unix command to start your application. And buildpack
provides a separate
compile step, where you can prepare things for that command: fetch
the lisp implementation binary, download libraries with quicklisp and build .fasl files. Again,
using full power of unix.
compile script of this buildpack installs SBCL available as sbcl/sbcl-1.0.54-x86-64-linux/run-sbcl.sh,
and then invokes a heroku-compile.lisp script in your application root directory.
In your heroku-compile.lisp you typically want to prebuild .fasl files of your
application by first
(asdf:disable-output-translations) and then loading your ASDF system.
If you need Quicklisp, call
cl-user::require-quicklisp, it installs quicklisp in the
Your application is started according to what you specfy in your Procfile. Here you can invoke the SBCL and run the lisp code you need. In the Procfile command you also want to disable ASDF output translations.
Disabling ASDF output tranlastions is necessary becuse Heroku performs the
step on one machine/directory, and then copies the result into another machine/directory.
With default output translations ASDF caches .fasl files according to the full path
of their source files. When the sources are moved to another location, ASDF can not match them
to the cached .fasls. In result full recompilation will hapen at start time of your application.
With ASDF output translations disabled the .fasl files are placed near the sources, and when copied together, ASDF still matches them.
See the example application.
- Heroku does not have a persistent file system. Applications should use S3 for storage; ZS3 is a useful CL library for doing that.
- You can login into the server where your application is deployed and inspect it with
heroku run bashcommand. See one off dynos.
require-quicklispfunction should accept desirable quicklisp dist version and quicklisp client version, because when deploying application to server we want predictable environement.
- Mike Travers for his great example
- Jose Santos Martins Pereira for hosting SBCL binary tarball at S3 and example of how to deploy it to heroku.
- Heroku and their new Buildpack-capable stack
- QuickLisp library manager
- All other countless lispers and developers of all generations who made this possible.