I've been attempting to install node-canvas on heroku the last couple of days and have hit a brick wall. The problem boils down to it's dependence upon the cairo library and the "node-waf configure build" wscript that checks for it's existence. Since we can't install libraries directly on heroku I attempted placing the precompiled libraries in the /app/bin folder (which is in heroku's $PATH), then I set the PKG_CONFIG_PATH to /app/bin/pkgconfig so that "pkg-config --libs cairo" could find the library (which is basically what the wscript calls to see if it exists), finally I ensured that the .pc files in the /app/bin/pkgconfig directory were modified to properly point to the libraries/header files in /app/bin.
All of this works fine on my local machine, so I'm not really sure this should be considered an issue for the node-canvas project, but I've been unable to get around this limitation in heroku and was hoping someone with more knowledge could help me get it running, or suggest some changes to the node-canvas package that could help with the cairo dependency issues.
I placed this line into the canvas build script (wscript):
os.system('pkg-config --libs cairo')
This checks for the existence of the cairo package on the system, and produces the following output:
Package cairo was not found in the pkg-config search path.
Perhaps you should add the directory containing `cairo.pc'
to the PKG_CONFIG_PATH environment variable
I have already set the PKG_CONFIG_PATH using:
heroku config:add PKG_CONFIG_PATH=/app/bin/pkgconfig
When I run:
heroku run bash
and in the bash prompt use the same command from above:
pkg-config --libs cairo
I get the result:
which is correct.
This tells me that there is something strange/wrong with the heroku build system and it's pkg-config implementation since it does not seem to be honoring the PKG_CONFIG_PATH environment variable that I have set.
It looks like this comes down to a permissions issue. Heroku's build process doesn't have permission to access the /app folder, so you can't store dependencies there. I suppose the only way to get around this limitation would be to create a node-canvas branch that builds cairo automatically, anyone have any ideas on how to go about this?
I ended up figuring out how to do this, I'll put the steps below.
1) Check out the canvas package from github.
2) Compile the cairo package on 64bit ubuntu.
3) Create a subdirectory named cairo inside the canvas package, place the compiled cairo module library, and header files inside this directory.
4) Modify your wscript to this:
from TaskGen import feature, after, before
srcdir = '.'
blddir = 'build'
VERSION = '0.0.1'
opt.add_option('--profile', action='store_true', help='Enable profiling', dest='profile', default=False)
o = Options.options
conf.env['USE_PROFILING'] = o.profile
if conf.check(lib='gif', libpath=['/lib', '/usr/lib', '/usr/local/lib'], uselib_store='GIF', mandatory=False):
if conf.check(lib='jpeg', libpath=['/lib', '/usr/lib', '/usr/local/lib'], uselib_store='JPEG', mandatory=False):
if conf.env['USE_PROFILING'] == True:
#conf.check_cfg(package='cairo', args='--cflags --libs', mandatory=True)
flags = ['-O3', '-Wall', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE', '-fPIC']
if hasattr(tgen, 'add_precompiled'):
for i in Utils.to_list(tgen.add_precompiled):
input_node = tgen.bld.srcnode.find_resource(i)
obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
obj.target = 'canvas'
obj.source = bld.glob('src/*.cc')
obj.includes = 'cairo'
obj.uselib = ['GIF', 'JPEG']
obj.add_precompiled = ['cairo/libcairo.so']
Wow. This sounds really impressive.
, "canvas": "https://github.com/elspoono/node-canvas/tarball/master"
That actually worked.
I couldn't get jpeg and gif support working ... but all I needed was png anyways. Anyone else feel free to use or look at my node-canvas-heroku fork if interested in performing this same hack. Feel free to contact me too ... I'm interested in improving this, but am not yet learned enough to do more. Appreciate questions and advice.
Just did a test on Nodejitsu. node-canvas appears fully supported.
Was able to successfully deploy live clock example ( https://github.com/LearnBoost/node-canvas/blob/master/examples/live-clock.js ) using just the jitsu deploy command ( no additional configuration was required )
@Marak I'm having an issue with Nodejitsu and node-canvas. Deploy works fine, but it appears that you guys have an old version of jpeglib installed.
Wrong JPEG library version: library is 62, caller expects 80
Judging by this wiki entry node-canvas requires libcairo2-dev & libjpeg8-dev.
EDIT: I ended up just using a simple imagemagick convert png -> jpg to get around the jpeglib issue.
For others wanting to use node-canvas on Heroku I've made a custom buildpack for node.js which also imports Cairo and Pixman so that the official node-canvas package will build when you push. See Heroku's Devcenter for more on custom buildpacks.
Simply do heroku config:add BUILDPACK_URL=git://github.com/bloomtime/heroku-buildpack-nodejs.git#cairo to use the buildpack. You can inspect the differences yourself, or fork the original and make your own fixes.
heroku config:add BUILDPACK_URL=git://github.com/bloomtime/heroku-buildpack-nodejs.git#cairo
I haven't tested everything yet, but basic PNG rendering is working at least. Most likely it will need a little bit more work to get JPG rendering working. If I decide to get fancy I may try to use composable buildpacks so I can keep using the official nodejs buildpack and just bring cairo in separately. Ping me if you're interested in trying that!
See http://www.ryandaigle.com/a/using-vulcan-to-build-binary-dependencies-on-heroku and the last few comments on heroku/vulcan#20 if you also want to build your own (or newer) cairo and pixman binaries.
Just wanted to note here that the custom buildback currently only works on the for node-canvas versions 0.12.x. Node-canvas 0.13.x seems to fail to find the cairo libraries when using gyp.
I've brought @RandomEtc's buildpack up-to-date with current pixman (0.28.2), freetype (2.4.11), and cairo (1.12.14) libraries: https://github.com/mojodna/heroku-buildpack-nodejs
To use this buildpack, heroku config:add BUILDPACK_URL=git://github.com/mojodna/heroku-buildpack-nodejs.git#cairo
heroku config:add BUILDPACK_URL=git://github.com/mojodna/heroku-buildpack-nodejs.git#cairo