I've successfully got Phantomjs to work on Heroku but now I'm hitting issues with the phantomjs-node interface for node.js (see https://github.com/sgentle/phantomjs-node).
When I'm attempting to initialize Phantom I'm seeing a 10-15 second delay and then:
> phantom stdout: ReferenceError: Can't find variable: socket
phantom stdout: phantomjs://webpage.evaluate():1
phantomjs://webpage.evaluate():1
phantomjs://webpage.evaluate():1
You can reproduce the problem with the following steps or by pulling down my test app at https://github.com/matellis/phantom-test
git init phantom-test
cd phantom-test
heroku apps:create
# create node app as per Heroku instructions here https://devcenter.heroku.com/articles/nodejs
# copy bin and lib folders from http://phantomjs.googlecode.com/files/phantomjs-1.6.1-linux-x86_64-dynamic.tar.bz2 into root of your new project
# if you don't do this step you'll get an error "phantom stderr: execvp(): No such file or directory"
git add .
git commit -m "init"
git push heroku
Test your app has come up, the third to last line will tell you the URL, it should read like:
http://fathomless-ravine-5563.herokuapp.com deployed to Heroku
If successful you should see Hello World! in your browser.
Now from the same folder as your Heroku application run:
heroku run node
At the node prompt try the following:
phantom = require('phantom');
x = phantom.create();
Wait 10-15 seconds and you should see the error. Nothing works from this point on.
This should output file foo.png
:
x = phantom.create(function(ph){ph.createPage(function(page){ page.open('http://bbcnews.com', function(status){ page.render('foo.png', function(result) {ph.exit()}); }); }); });
To validate Phantomjs is working fine on Heroku, try the following using my test project:
>heroku run bash
Running `bash` attached to terminal... up, run.1
~ $ phantomjs test.js http://bbcnews.com foo.png
~ $ ls *.png
foo.png
I cannot reproduce any of these problems locally but there are other issues reported where folks may have hit this issue locally.
The problem seems to originate in shim.js
line 1637:
s.on('request', function(req) {
var evil;
evil = "function(){socket.emit('message', " + (JSON.stringify(JSON.stringify(req))) + " + '\\n');}";
return controlPage.evaluate(evil);
});
I've tried variations of versions of node, phantom, etc. with no luck.
I've also tried a custom buildpack that sets the DYLD variable, see http://github.com/tecnh/heroku-buildpack-nodejs with no luck either.
Anyone who has got Phantom + Node playing together nicely on Heroku please let me know. There are several references to this on Stackoverflow but nobody is saying "I got it to work, here's how".
Supported Runtimes As illustrated by the Node. js release schedule below, Heroku's currently supported Node. js versions are 16.
You should not include folder node_modules in your . gitignore file (or rather you should include folder node_modules in your source deployed to Heroku). If folder node_modules: exists then npm install will use those vendored libraries and will rebuild any binary dependencies with npm rebuild .
Run the npm install command in your local app directory to install the dependencies that you declared in your package. json file. Start your app locally using the heroku local command, which is installed as part of the Heroku CLI. Your app should now be running on http://localhost:5000/.
I've never used the phantomjs node module, but I do have an app running both node and phantomjs on Heroku.
You need to use custom buildpacks in order to get this to work. My .buildpacks
file looks like
http://github.com/heroku/heroku-buildpack-nodejs.git
http://github.com/stomita/heroku-buildpack-phantomjs.git
You should then be able to run phantomjs scripts in a child process:
var script = app.get('root') + '/scripts/rasterize.js' //the phantomjs script to run
, bin = app.get('phantom') //normally this would just be the string "phantomjs"
, spawn = require('child_process').spawn;
// set up args to the phantom cli
// (run the phantomjs command in your terminal to see options/format)
var args = [];
// ...
var phntm = spawn(bin, args);
phntm.stdout.on('data', function (data) { /* do something */ });
phntm.stderr.on('data', function (data) { /* do something */ });
phntm.on('exit', function (code) { /* handle exit */ });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With