I want to create a function to create a pdf from a HTML file and trigger it from AWS Lambda. I have put the function inside a docker image and deployed the docker image to AWS Lambda. It is working fine when I run the docker locally, but when I deploy it to AWS Lambda, it does not work.
My app.js which is responsible for creating the pdf file:
const fs = require('fs');
const puppeteer = require('puppeteer');
const path = require('path');
const chromium = require('chrome-aws-lambda');
const buildPaths = {
buildPathHtml: path.resolve('./index.html'),
buildPathPdf: path.resolve('./my-file.pdf')
};
const { buildPathHtml, buildPathPdf } = buildPaths;
const isFileExist = (filePath) => {
try {
fs.statSync(filePath);
return true;
} catch (error) {
return false;
}
};
const printPdf = async () => {
if (!isFileExist(buildPathHtml)) {
throw new Error('HTML file does not exist.');
}
console.log('Creating browser...');
browser = await chromium.puppeteer.launch({
args: ['--no-sandbox', '--disable-dev-shm-usage', '--disable-web-security'],
executablePath: await chromium.executablePath,
headless: true,
});
console.log('Browser created. Creating page...');
const page = await browser.newPage();
console.log('Page created. Going to html file path...');
await page.goto(`file:${buildPathHtml}`, { waitUntil: 'networkidle0' });
console.log('Went to html file path. Creating pdf...');
const pdf = await page.pdf({
format: 'A4',
printBackground: true,
landscape: true,
displayHeaderFooter: true,
headerTemplate: ``,
footerTemplate: `
<div style="font-size: 10px; font-family: 'Raleway'; font-weight: bold; width: 1000px; text-align: center; color: grey; padding-left: 10px;">
<span>Page: </span>
<span class="pageNumber"></span> / <span class="totalPages"></span>
<span> - Date: </span>
<span class="date"></span>
</div>`,
margin: {
top: '20px',
right: '20px',
bottom: '40px',
left: '20px'
}
});
console.log('Pdf created. Closing the browser...');
await browser.close();
console.log('Succesfully created the PDF');
fs.writeFileSync(buildPathPdf, pdf);
return {
headers: {
"Content-type": "application/pdf",
},
statusCode: 200,
body: pdf.toString("base64"),
isBase64Encoded: true,
};
};
exports.lambdaHandler = async (event) => {
try {
console.log('Handler invoked. Event: ', event);
const response = await printPdf();
console.log('Response generated. response: ', response);
return response;
} catch (error) {
console.log('Error generating PDF', error);
}
}
exports.lambdaHandler();
This is my Dockerfile:
FROM amazon/aws-lambda-nodejs:12
COPY google-chrome.repo /etc/yum.repos.d/
RUN yum -y update google-chrome-stable
RUN yum -y install google-chrome-stable
COPY . ./
RUN npm ci --quiet
CMD [ "app.lambdaHandler" ]
I build the docker with this command:
docker build -t my-function .
Then I run it like this:
docker run -p 9000:8080 my-function:latest
Now to test it locally I run this command:
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
And it works fine. But when I deploy it to AWS Lambda and invoke a test from there I get this error:
START RequestId: 3de1cb55-eee5-4c82-a3c4-4dabf7eb9570 Version: $LATEST
2021-03-18T22:06:30.748Z 3de1cb55-eee5-4c82-a3c4-4dabf7eb9570 INFO Handler invoked. Event: {}
2021-03-18T22:06:30.750Z 3de1cb55-eee5-4c82-a3c4-4dabf7eb9570 INFO Creating browser...
2021-03-18T22:06:36.269Z 3de1cb55-eee5-4c82-a3c4-4dabf7eb9570 INFO Error generating PDF Error: Protocol error (Target.setDiscoverTargets): Target closed.
at /var/task/node_modules/puppeteer/lib/cjs/puppeteer/common/Connection.js:71:63
at new Promise (<anonymous>)
at Connection.send (/var/task/node_modules/puppeteer/lib/cjs/puppeteer/common/Connection.js:70:16)
at Function.create (/var/task/node_modules/puppeteer/lib/cjs/puppeteer/common/Browser.js:116:26)
at ChromeLauncher.launch (/var/task/node_modules/puppeteer/lib/cjs/puppeteer/node/Launcher.js:101:56)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async printPdf (/var/task/app.js:27:12)
at async Runtime.exports.lambdaHandler [as handler] (/var/task/app.js:75:20)
END RequestId: 3de1cb55-eee5-4c82-a3c4-4dabf7eb9570
REPORT RequestId: 3de1cb55-eee5-4c82-a3c4-4dabf7eb9570 Duration: 5540.02 ms Billed Duration: 6366 ms Memory Size: 512 MB Max Memory Used: 377 MB Init Duration: 825.77 ms
It seems that google-chrome-stable has not been successfully installed in AWS Lambda environment. Any ideas how to fix it?