diff --git a/Dockerfile b/Dockerfile index 77ab3cf..13c2cec 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,48 +1,21 @@ -FROM node:8-slim - -RUN apt-get update && \ -apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \ -libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \ -libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \ -libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \ -fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst ttf-freefont \ -ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \ -wget https://github.com/Yelp/dumb-init/releases/download/v1.2.1/dumb-init_1.2.1_amd64.deb && \ -dpkg -i dumb-init_*.deb && rm -f dumb-init_*.deb && \ -apt-get clean && apt-get autoremove -y && rm -rf /var/lib/apt/lists/* - -RUN yarn global add puppeteer@1.8.0 && yarn cache clean - -ENV NODE_PATH="/usr/local/share/.config/yarn/global/node_modules:${NODE_PATH}" - -ENV PATH="/tools:${PATH}" - -RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser - -COPY --chown=pptruser:pptruser ./tools /tools - -# Set language to UTF8 -ENV LANG="C.UTF-8" +FROM node:10-slim + +RUN apt-get update \ + && apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \ + libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \ + libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \ + libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \ + fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst ttf-freefont git-core \ + ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget \ + && wget https://github.com/Yelp/dumb-init/releases/download/v1.2.1/dumb-init_1.2.1_amd64.deb \ + && dpkg -i dumb-init_*.deb \ + && rm -f dumb-init_*.deb \ + && apt-get clean \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* \ + && yarn global add puppeteer@1.11.0 \ + && yarn cache clean WORKDIR /app -# Add user so we don't need --no-sandbox. -RUN mkdir /screenshots \ - && mkdir -p /home/pptruser/Downloads \ - && chown -R pptruser:pptruser /home/pptruser \ - && chown -R pptruser:pptruser /usr/local/share/.config/yarn/global/node_modules \ - && chown -R pptruser:pptruser /screenshots \ - && chown -R pptruser:pptruser /app \ - && chown -R pptruser:pptruser /tools - -# Run everything after as non-privileged user. -USER pptruser - -# --cap-add=SYS_ADMIN -# https://docs.docker.com/engine/reference/run/#additional-groups - ENTRYPOINT ["dumb-init", "--"] - -# CMD ["/usr/local/share/.config/yarn/global/node_modules/puppeteer/.local-chromium/linux-526987/chrome-linux/chrome"] - -CMD ["node", "index.js"] diff --git a/LICENSE b/LICENSE index 005dbe2..6701138 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 alekzonder +Copyright (c) 2018 Daniel IƱigo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 4bbbd9d..fef3055 100644 --- a/README.md +++ b/README.md @@ -1,179 +1,5 @@ # puppeteer docker image -docker image with [Google Puppeteer](https://github.com/GoogleChrome/puppeteer) installed +Docker image with [Google Puppeteer](https://github.com/GoogleChrome/puppeteer) installed. -and [screenshots scripts](#screenshots-tools) - -[![nodesource/node](http://dockeri.co/image/alekzonder/puppeteer)](https://hub.docker.com/r/alekzonder/puppeteer/) - -## docker tags - -- `latest` -- `1` -- `1.1.1` -- `1.1.0` -- `1.0.0` -- `0` -- `0.13.0` -- `0.12.0` -- `0.11.0` -- `0.10.2` -- `0.10.1` -- `0.10.0` -- `0.9.0` - -## install - -``` -docker pull alekzonder/puppeteer:latest -# OR -docker pull alekzonder/puppeteer:1.0.0 -# OR -docker pull alekzonder/puppeteer:1 - -``` - -## before usage - - -1. you should pass `--no-sandbox, --disable-setuid-sandbox` args when launch browser - -```js -const puppeteer = require('puppeteer'); - -(async() => { - - const browser = await puppeteer.launch({ - args: [ - '--no-sandbox', - '--disable-setuid-sandbox' - ] - }); - - const page = await browser.newPage(); - - await page.goto('https://www.google.com/', {waitUntil: 'networkidle2'}); - - browser.close(); - -})(); -``` - -2. if you got page crash with `BUS_ADRERR` ([chromium issue](https://bugs.chromium.org/p/chromium/issues/detail?id=571394)), increase shm-size on docker run with `--shm-size` argument - -```bash -docker run --shm-size 1G --rm -v :/app/index.js alekzonder/puppeteer:latest -``` - -3. If you're seeing random navigation errors (unreachable url) it's likely due to ipv6 being enabled in docker. Navigation errors are caused by ERR_NETWORK_CHANGED (-21) in chromium. Disable ipv6 in your container using `--sysctl net.ipv6.conf.all.disable_ipv6=1` to fix: -```bash -docker run --shm-size 1G --sysctl net.ipv6.conf.all.disable_ipv6=1 --rm -v :/app/index.js alekzonder/puppeteer:latest -``` - -4. add `--enable-logging` for chrome debug logging http://www.chromium.org/for-testers/enable-logging - -```js -const puppeteer = require('puppeteer'); - -(async() => { - - const browser = await puppeteer.launch({args: [ - '--no-sandbox', - '--disable-setuid-sandbox', - - // debug logging - '--enable-logging', '--v=1' - ]}); - - -``` - - -## usage - -### mount your script to /app/index.js - -```bash -docker run --shm-size 1G --rm -v :/app/index.js alekzonder/puppeteer:latest -``` - -### custom script from dir - -```bash -docker run --shm-size 1G --rm \ - -v :/app \ - alekzonder/puppeteer:latest \ - node my_script.js -``` - -## screenshots tools - -simple screenshot tools in image - -```bash -docker run --shm-size 1G --rm -v /tmp/screenshots:/screenshots \ - alekzonder/puppeteer:latest \ - 'https://www.google.com' 1366x768 -``` - -### screenshot tools syntax - -` x []` - -* `delay_in_ms`: is optional (defaults to `0`) - * Waits for `delay_in_ms` milliseconds before taking the screenshot - -### `screenshot` - -```bash -docker run --shm-size 1G --rm -v /tmp/screenshots:/screenshots \ - alekzonder/puppeteer:latest \ - screenshot 'https://www.google.com' 1366x768 -``` - -output: one line json - -``` -{ - "date":"2017-09-01T05:03:27.464Z", - "timestamp":1504242207, - "filename":"screenshot_1366_768.png", - "width":1366, - "height":768 -} -``` -got screenshot in /tmp/screenshots/screenshot_1366_768.png - -### `full_screenshot` - -save full screenshot of page - -```bash -docker run --shm-size 1G --rm -v /tmp/screenshots:/screenshots \ - alekzonder/puppeteer:latest \ - full_screenshot 'https://www.google.com' 1366x768 -``` - -### `screenshot_series`, `full_screenshot_series` - -adds datetime in ISO format into filename - -useful for cron screenshots - -```bash -docker run --shm-size 1G --rm -v /tmp/screenshots:/screenshots \ - alekzonder/puppeteer:latest \ - screenshot_series 'https://www.google.com' 1366x768 -``` - -```bash -docker run --shm-size 1G --rm -v /tmp/screenshots:/screenshots \ - alekzonder/puppeteer:latest \ - full_screenshot_series 'https://www.google.com' 1366x768 -``` - -``` -2017-09-01T05:08:55.027Z_screenshot_1366_768.png -# OR -2017-09-01T05:08:55.027Z_full_screenshot_1366_768.png -``` +[![nodesource/node](http://dockeri.co/image/dinigo/puppeteer)](https://hub.docker.com/r/dinigo/puppeteer/) diff --git a/examples/google-screenshot.js b/examples/google-screenshot.js deleted file mode 100644 index 5afebac..0000000 --- a/examples/google-screenshot.js +++ /dev/null @@ -1,20 +0,0 @@ -const puppeteer = require('puppeteer'); - -(async() => { - - const browser = await puppeteer.launch({ - args: [ - '--no-sandbox', - '--disable-setuid-sandbox' - ] - }); - - const page = await browser.newPage(); - - await page.goto('https://www.google.com/', {waitUntil: 'networkidle'}); - - await page.screenshot({path: 'google.png'}); - - browser.close(); - -})(); diff --git a/sh/build.sh b/sh/build.sh deleted file mode 100755 index 8e1cd00..0000000 --- a/sh/build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -docker build -t alekzonder/puppeteer:latest . diff --git a/tools/fullScreenshot.js b/tools/fullScreenshot.js deleted file mode 100755 index b847ba9..0000000 --- a/tools/fullScreenshot.js +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env node - -function sleep(ms) { - ms = (ms) ? ms : 0; - return new Promise(resolve => {setTimeout(resolve, ms);}); -} - -process.on('uncaughtException', (error) => { - console.error(error); - process.exit(1); -}); - -process.on('unhandledRejection', (reason, p) => { - console.error(reason, p); - process.exit(1); -}); - -const puppeteer = require('puppeteer'); - -// console.log(process.argv); - -if (!process.argv[2]) { - console.error('ERROR: no url arg\n'); - - console.info('for example:\n'); - console.log(' docker run --shm-size 1G --rm -v /tmp:/screenshots \\'); - console.log(' alekzonder/puppeteer:latest screenshot \'https://www.google.com\'\n'); - process.exit(1); -} - -var url = process.argv[2]; - -var now = new Date(); - -var dateStr = now.toISOString(); - -var width = 800; -var height = 600; - -if (typeof process.argv[3] === 'string') { - var [width, height] = process.argv[3].split('x').map(v => parseInt(v, 10)); -} - -var delay = 0; - -if (typeof process.argv[4] === 'string') { - delay = parseInt(process.argv[4], 10); -} - -var isMobile = false; - -let filename = `full_screenshot_${width}_${height}.png`; - -(async() => { - - const browser = await puppeteer.launch({ - args: [ - '--no-sandbox', - '--disable-setuid-sandbox' - ] - }); - - const page = await browser.newPage(); - - page.setViewport({ - width, - height, - isMobile - }); - - await page.goto(url, {waitUntil: 'networkidle2'}); - - await sleep(delay); - - await page.screenshot({path: `/screenshots/${filename}`, fullPage: true}); - - browser.close(); - - console.log( - JSON.stringify({ - date: dateStr, - timestamp: Math.floor(now.getTime() / 1000), - filename, - width, - height - }) - ); - -})(); diff --git a/tools/fullScreenshotSeries.js b/tools/fullScreenshotSeries.js deleted file mode 100755 index 32e90de..0000000 --- a/tools/fullScreenshotSeries.js +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env node - -function sleep(ms) { - ms = (ms) ? ms : 0; - return new Promise(resolve => {setTimeout(resolve, ms);}); -} - -process.on('uncaughtException', (error) => { - console.error(error); - process.exit(1); -}); - -process.on('unhandledRejection', (reason, p) => { - console.error(reason, p); - process.exit(1); -}); - -const puppeteer = require('puppeteer'); - -// console.log(process.argv); - -if (!process.argv[2]) { - console.error('ERROR: no url arg\n'); - - console.info('for example:\n'); - console.log(' docker run --shm-size 1G --rm -v /tmp:/screenshots \\'); - console.log(' alekzonder/puppeteer:latest screenshot \'https://www.google.com\'\n'); - process.exit(1); -} - -var url = process.argv[2]; - -var now = new Date(); - -var dateStr = now.toISOString(); - -var width = 800; -var height = 600; - -if (typeof process.argv[3] === 'string') { - var [width, height] = process.argv[3].split('x').map(v => parseInt(v, 10)); -} - -var delay = 0; - -if (typeof process.argv[4] === 'string') { - delay = parseInt(process.argv[4], 10); -} - -var isMobile = false; - -let filename = `${dateStr}_full_screenshot_${width}_${height}.png`; - -(async() => { - - const browser = await puppeteer.launch({ - args: [ - '--no-sandbox', - '--disable-setuid-sandbox' - ] - }); - - const page = await browser.newPage(); - - page.setViewport({ - width, - height, - isMobile - }); - - await page.goto(url, {waitUntil: 'networkidle2'}); - - await sleep(delay); - - await page.screenshot({path: `/screenshots/${filename}`, fullPage: true}); - - browser.close(); - - console.log( - JSON.stringify({ - date: dateStr, - timestamp: Math.floor(now.getTime() / 1000), - filename, - width, - height - }) - ); - -})(); diff --git a/tools/full_screenshot b/tools/full_screenshot deleted file mode 100755 index f4c2a31..0000000 --- a/tools/full_screenshot +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -env node /tools/fullScreenshot.js "$@" diff --git a/tools/full_screenshot_series b/tools/full_screenshot_series deleted file mode 100755 index a8f2669..0000000 --- a/tools/full_screenshot_series +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -env node /tools/fullScreenshotSeries.js "$@" diff --git a/tools/screenshot b/tools/screenshot deleted file mode 100755 index 2f2fa64..0000000 --- a/tools/screenshot +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -env node /tools/screenshot.js "$@" diff --git a/tools/screenshot.js b/tools/screenshot.js deleted file mode 100755 index 81e7535..0000000 --- a/tools/screenshot.js +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env node - -function sleep(ms) { - ms = (ms) ? ms : 0; - return new Promise(resolve => {setTimeout(resolve, ms);}); -} - -process.on('uncaughtException', (error) => { - console.error(error); - process.exit(1); -}); - -process.on('unhandledRejection', (reason, p) => { - console.error(reason, p); - process.exit(1); -}); - -const puppeteer = require('puppeteer'); - -// console.log(process.argv); - -if (!process.argv[2]) { - console.error('ERROR: no url arg\n'); - - console.info('for example:\n'); - console.log(' docker run --shm-size 1G --rm -v /tmp:/screenshots \\'); - console.log(' alekzonder/puppeteer:latest screenshot \'https://www.google.com\'\n'); - process.exit(1); -} - -var url = process.argv[2]; - -var now = new Date(); - -var dateStr = now.toISOString(); - -var width = 800; -var height = 600; - -if (typeof process.argv[3] === 'string') { - var [width, height] = process.argv[3].split('x').map(v => parseInt(v, 10)); -} - -var delay = 0; - -if (typeof process.argv[4] === 'string') { - delay = parseInt(process.argv[4], 10); -} - -var isMobile = false; - -let filename = `screenshot_${width}_${height}.png`; - -(async() => { - - const browser = await puppeteer.launch({ - args: [ - '--no-sandbox', - '--disable-setuid-sandbox' - ] - }); - - const page = await browser.newPage(); - - page.setViewport({ - width, - height, - isMobile - }); - - await page.goto(url, {waitUntil: 'networkidle2'}); - - await sleep(delay); - - await page.screenshot({path: `/screenshots/${filename}`, fullPage: false}); - - browser.close(); - - console.log( - JSON.stringify({ - date: dateStr, - timestamp: Math.floor(now.getTime() / 1000), - filename, - width, - height - }) - ); - -})(); diff --git a/tools/screenshotSeries.js b/tools/screenshotSeries.js deleted file mode 100755 index 86711a4..0000000 --- a/tools/screenshotSeries.js +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env node - -function sleep(ms) { - ms = (ms) ? ms : 0; - return new Promise(resolve => {setTimeout(resolve, ms);}); -} - -process.on('uncaughtException', (error) => { - console.error(error); - process.exit(1); -}); - -process.on('unhandledRejection', (reason, p) => { - console.error(reason, p); - process.exit(1); -}); - -const puppeteer = require('puppeteer'); - -// console.log(process.argv); - -if (!process.argv[2]) { - console.error('ERROR: no url arg\n'); - - console.info('for example:\n'); - console.log(' docker run --shm-size 1G --rm -v /tmp:/screenshots \\'); - console.log(' alekzonder/puppeteer:latest screenshot \'https://www.google.com\'\n'); - process.exit(1); -} - -var url = process.argv[2]; - -var now = new Date(); - -var dateStr = now.toISOString(); - -var width = 800; -var height = 600; - -if (typeof process.argv[3] === 'string') { - var [width, height] = process.argv[3].split('x').map(v => parseInt(v, 10)); -} - -var delay = 0; - -if (typeof process.argv[4] === 'string') { - delay = parseInt(process.argv[4], 10); -} - -var isMobile = false; - -let filename = `${dateStr}_screenshot_${width}_${height}.png`; - -(async() => { - - const browser = await puppeteer.launch({ - args: [ - '--no-sandbox', - '--disable-setuid-sandbox' - ] - }); - - const page = await browser.newPage(); - - page.setViewport({ - width, - height, - isMobile - }); - - await page.goto(url, {waitUntil: 'networkidle2'}); - - await sleep(delay); - - await page.screenshot({path: `/screenshots/${filename}`, fullPage: false}); - - browser.close(); - - console.log( - JSON.stringify({ - date: dateStr, - timestamp: Math.floor(now.getTime() / 1000), - filename, - width, - height - }) - ); - -})(); diff --git a/tools/screenshot_series b/tools/screenshot_series deleted file mode 100755 index 0c073cc..0000000 --- a/tools/screenshot_series +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -env node /tools/screenshotSeries.js "$@"