Puppeteer unable to run on Heroku - javascript

I deployed an app on heroku, and I added the Puppeteer Heroku buildpack.
After a succesful redeployment, I tried to run it and it fails. Using heroku logs -t, I get this error message:
2018-09-07T13:16:10.870497+00:00 app[web.1]: Error: Failed to launch chrome!
2018-09-07T13:16:10.870512+00:00 app[web.1]: [0907/131610.045486:FATAL:zygote_ho
st_impl_linux.cc(116)] No usable sandbox! Update your kernel or see https://chro
mium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.
md for more information on developing with the SUID sandbox. If you want to live
dangerously and need an immediate workaround, you can try using --no-sandbox.

Here is what worked for me. First, I clear all my buildpacks and then I added the puppeteer-heroku-buildpack and the heroku/nodejs one:
$ heroku buildpacks:clear
$ heroku buildpacks:add --index 1 https://github.com/jontewks/puppeteer-heroku-buildpack
$ heroku buildpacks:add --index 1 heroku/nodejs
Then, add the following args to the puppeteer launch function:
const browser = await puppeteer.launch({
'args' : [
'--no-sandbox',
'--disable-setuid-sandbox'
]
});
Finally, deploy it back to Heroku:
$ git add .
$ git commit -m "Fixing deployment issue"
$ git push heroku master

You should be able to solve this issue by passing the --no-sandbox and --disable-setuid-sandbox flags to puppeteer.launch():
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
],
});
If this does not work, you may want to read the official Puppeteer troubleshooting guide: Running Puppeteer on Heroku.

This answer is fantastic, but in the interests of a minimal, runnable example I thought I'd share my complete code and workflow for getting up and running with a Puppeteer-based web app.
See this answer for a simple scheduler and a clock process version (although all three approaches can coexist in one app without doing anything special).
package.json:
{
"name": "test-puppeteer",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"puppeteer": "^9.1.1"
}
}
Procfile:
web: node index.js
index.js:
const express = require("express");
const puppeteer = require("puppeteer");
const app = express();
app.set("port", process.env.PORT || 5000);
const browserP = puppeteer.launch({
args: ["--no-sandbox", "--disable-setuid-sandbox"]
});
app.get("/", (req, res) => {
// FIXME move to a worker task; see https://devcenter.heroku.com/articles/node-redis-workers
let page;
(async () => {
page = await (await browserP).newPage();
await page.setContent(`<p>web running at ${Date()}</p>`);
res.send(await page.content());
})()
.catch(err => res.sendStatus(500))
.finally(() => page.close())
;
});
app.listen(app.get("port"), () =>
console.log("app running on port", app.get("port"))
);
Set up
Install Heroku CLI and create a new app with Node and Puppeteer buildpacks (see this answer):
heroku create
heroku buildpacks:add --index 1 https://github.com/jontewks/puppeteer-heroku-buildpack -a cryptic-dawn-48835
heroku buildpacks:add --index 1 heroku/nodejs -a cryptic-dawn-48835
(replace cryptic-dawn-48835 with your app name)
Deploy:
git init
git add .
git commit -m "initial commit"
heroku git:remote -a cryptic-dawn-48835
git push heroku master
Verify that it worked with curl https://cryptic-dawn-48835.herokuapp.com. You should see something like
<html><head></head><body><p>web running at Wed May 19 2021 02:12:48 GMT+0000 (Coordinated Universal Time)</p></body></html>

Related

API request through Docker & Nodejs fails but works perfectly when accessed directly using the Nodejs

I am developing an application using Nodejs and Docker. Within the code, I need to make the request to GitLab API to get the data. When I run the application through the Docker command docker-compose exec web sh -c "project=GitLab type=New npm start" then I get the error as it is unable to get the response from the API call but the same code and API request works perfectly when running with the direct command node index.js.
Following is the code I have:
./web/index.js:
const express = require('express');
const http = require("http");
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 9000;
const gitlabDump = require("./controller/GitLabDump");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//Make NodeJS to Listen to a particular Port in Localhost
app.listen(port, function(){
var project = process.env.project;
var type = process.env.type;
if(project.trim() === "GitLab" && (type.trim() === "New" || type.trim() === "Update")){
//If porject is GitLab then fetch the data from Gitlab
console.log("Fetching GitLab Data.......");
gitlabDump.gitlabDump(type, function(data){
console.log("Completed Execution for GitLab")
process.exit();
})
}
}
Following is my controller code where I am making the API request:
./web/controller/GitLabDump.js
const request = require('request');
exports.gitlabDump = function(callback){
var gitlabAPI = "https://gitlab.com/api/v4/projects/<project_id>/repository/tree?ref=<target_branch>&path=path/to/subdirectory";
console.log("BEFORE \n")
request(gitlabAPI, function(error, response, body) {
console.log(JSON.parse(body))
callback("Completed");
})
}
Following is my DockerFile:
./docker.compose.yml
version: '3'
services:
db:
container_name: db
image: mysql:5.7
volumes:
- "./data/mysql:/var/lib/mysql:rw"
environment:
MYSQL_DATABASE: myDatabase
MYSQL_ROOT_PASSWORD: myPassword
MYSQL_PASSWORD: myPassword
DATABASE_HOST: localhost
restart: always
web:
container_name: web
image: node:8
volumes:
- ./web:/usr/src/app
working_dir: /usr/src/app
depends_on:
- db
restart: on-failure
command: "tail -f /dev/null"
environment: ["project=${project}", "type=${type}"]
Following is the command I am using to run the application:
docker-compose exec web sh -c "project=GitLab type=New npm start"
Following is the error that I get:
Fetching GitLab Data.......
BEFORE
undefined:1
undefined
^
The error is coming due to the line console.log(JSON.parse(body)). Because the body is undefined as the API call returns no data.
Please Note:
API URL is correct and I have the proper access because the same URL gives me data when accessing through Chrome, Postman, and even when running the code using the node index.js command.
I am using the same application to make other API calls apart from GitLab and they are working fine.
Can someone please help me what's the issue here and why is failing for GitLab API?
Posting the answer here as it can be useful to someone else in the future:
Finally, I was able to find the resolution. The issue is not happening because of the docker but rather because of the Nodejs itself. If we console.log the error then we get the certificate has expired message.
The fix is to request something like this:
request({
url: gitlabAPI,
agentOptions: {
rejectUnauthorized: false
}
}, function (error, response, body) {
console.log(JSON.parse(response.body))
});
Refer to the questions: Node.js request CERT_HAS_EXPIRED

node server not running : exiting without any output

I've been messing around with codesphere lately and have a weird issue, at least to me:
my server.js:
const express =require('express');
const app = express();
const port = 8000;
app.get('/', (req,res) => {
res.send('Hi there')
});
app.listen(port, () => {
console.log("Running")
});
Upon npm start :
user#codesphere:app [master] $ npm start
personal_website#1.0.0 start /home/user/app
node server.js
then the output exits the server and returns to CLI
Output for running node server.js:
Another edit:
upper part, my package.json in their ide, lower part: package.json open in terminal (nano)
Now I actually think, it is save to assume they have trouble!

Issue with Cluster on Visual studio code (F5) on Node.js v6.0.0

I have some issue with Visual studio code with Cluster
Edit
If I hit Ctrl + F5 it works correctly, what it's doing other than just F5, do I need to start command always with Ctrl?
---
It seems like workers never starts when started with VS Code Launch command (F5). Do I need to do some changes to .vscode/launch.json file to make Cluster work proberly.
Actual code is copied from Node.js 6 api https://nodejs.org/api/cluster.html#cluster_cluster
npm test Windows Command prompt shows this:
Master started
Listening port 80
Listening port 80
Listening port 80
Listening port 80
VS Code (F5) Debug Console show this:
node --debug-brk=7601 --nolazy index.js
Debugger listening on port 7601
Master started
Debugger listening on port 7602
Debugger listening on port 7603
Debugger listening on port 7604
Debugger listening on port 7605
VS Code launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/index.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}",
..........
index.js
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
console.log('Master started')
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(80);
console.log('Listening port 80')
}
I had the same issue. The 2nd workaround described by weinand in https://github.com/Microsoft/vscode/issues/3201 works for me:
Launch node from a terminal and attach to it with the VS Code
debugger.
Run in terminal: node --debug app.js
Then select the default 'attach' launch config and
attach to it.
The workaround is the preferred way if you actually want to debug any
worker and not just the first process that is launched.
I have the same problem on Visual studio code with Cluster.
I found that there are some dirty method to make it works.
Mac OS X:
/Applications/Visual Studio
Code.app/Contents/Resources/app/extensions/node-debug/out/node/nodeDebug.js
Windows:
C:\Program Files (x86)\Microsoft VS Code\resources\app\extensions\node-debug\out\node\nodeDebug.js
Change this
if (!this._noDebug) {
launchArgs.push("--debug-brk=" + port);
}
to
if (!this._noDebug) {
launchArgs.push("--debug=" + port);
}
I know it is not the best way to solve it, but it is working so far for me.

Deploy OpenShift Node.js application from github

I created a node.js (with express) application and have been unsucessfully trying to deploy to OpenShift from github. I am attempting to deploy from the web interface (providing the URL to the github repository root and "master" in the branch/tag field) and am getting an error I'm having trouble understanding:
The initial build for the application failed:
Shell command '/sbin/runuser -s /bin/sh 5724c3b42d5271363b000191 -c "exec /usr/bin/runcon 'unconfined_u:system_r:openshift_t:s0:c4,c687' /bin/sh -c \"gear postreceive --init >> /tmp/initial-build.log 2>&1\""' returned an error. rc=255 .
Last 10 kB of build output: Stopping NodeJS cartridge
Repairing links for 1 deployments
Building git ref 'master', commit a5ca0f7
Building NodeJS cartridge Preparing build for deployment
Deployment id is c2527992
Activating deployment
Starting NodeJS cartridge Sat Apr 30 2016 10:41:09 GMT-0400 (EDT):
Starting application 'profile' ...
Script = server.js
Script Args = Node Options = !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! It is highly recommended that you add a package.json file to your application. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Waiting for application port (8080) become available ...
Application 'profile' failed to start (port 8080 not available) -------------------------
Git Post-Receive Result: failure
Activation status: failure
Activation failed for the following gears: 5724c3b42d5271363b000191
(Error activating gear: CLIENT_ERROR: Failed to execute: 'control start' for /var/lib/openshift/5724c3b42d5271363b000191/nodejs #<IO:0x000000019b0298> #<IO:0x000000019b0220> )
Deployment completed with status: failure postreceive failed
I read a couple of posts about some errors above like port 8080 not available and failed to execute control start but the directives I was able to follow did not solve my issue. I am finding the line that says "using a package.json file is highly recommended" strange as I do have one. My package.json file is:
{
"name": "Portfolio_Memoria",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node server.js"
},
"main": "server.js",
"description": "Portfolio_Memoria",
"author": {
"name": "gorra",
"email": ""
},
"dependencies": {
"express": "~4.9.0",
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"debug": "~2.0.0",
"jade": "~1.6.0",
"stylus": "0.42.3"
}
}
And server.js file is:
#!/usr/bin/env node
var debug = require('debug')('Portfolio_Memoria');
var app = require('./app');
if(typeof process.env.OPENSHIFT_NODEJS_PORT === 'undefined'){
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
} else {
app.set('port', process.env.OPENSHIFT_NODEJS_PORT || 3000);
app.set('ip', process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1');
var server = app.listen(app.get('port'), app.get('ip'), function() {
debug('Express server listening on port ' + server.address().port);
});
}
Of course, the application runs without issue locally. I don't know what I am missing here.
EDIT:
I got it to work by creating a blank application in OpenShift, cloning the repository OpenShift creates via command line, copying my whole project to it and pushing it back. This is a workaround and not a solution to the original problem, though.

Get request in openshift node js app

I'm building an openshift node js app which has to communicate with youtube data API. Its deployment is a success when I do "git push" with the require commented.
/*
var request = require('request');
*/
When I uncomment it, I get this error :
remote: Waiting for application port (8080) become available ...
remote: Application 'eln' failed to start (port 8080 not available)
remote: -------------------------
remote: Git Post-Receive Result: failure
remote: Activation status: failure
remote: Activation failed for the following gears:
remote: 573c3e177628e146d400004e (Error activating gear: CLIENT_ERROR: Failed to execute: 'control start' for /var/lib/openshift/573c3e177628e146d400004e/nodejs
Am I doing it bad? How can I fix it?
thank you.
Edit 1: Adding listening code, I didn't modify it (it was already here when I've created the app).
self.ipaddress = process.env.OPENSHIFT_NODEJS_IP;
self.port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
/**
* Start the server (starts up the sample application).
*/
self.start = function()
{
// Start the app on the specific interface (and port).
self.app.listen(self.port, self.ipaddress, function()
{
console.log('%s: Node server started on %s:%d ...', Date(Date.now() ), self.ipaddress, self.port);
});
};
This is my app.js basic code that is working on openshift.
#!/bin/env node
ipaddress = process.env.OPENSHIFT_NODEJS_IP;
if (typeof ipaddress === "undefined") {
// Log errors on OpenShift but continue w/ 127.0.0.1 - this
// allows us to run/test the app locally.
console.warn('No OPENSHIFT_NODEJS_IP var, using 127.0.0.1');
ipaddress = "127.0.0.1";
};
var server = app.listen(8080, ipaddress, function() {
console.log('Listening on port %d', server.address().port);
});
Can you try that?
Update
After trying it on openshift with request I also got this error but it was because package.json didn't have request under dependencies.
My dependencies now look like this and it works fine:
"dependencies": {
"ejs": "^2.4.1",
"express": "~3.4.4",
"request": "latest" // this is added
},

Categories

Resources