簡體   English   中英

Puppeteer 似乎不適用於 docker

[英]Puppeteer does not seem to work with docker

我使用 puppeteer 編寫了一個程序。 在我的電腦本地運行良好。 但是,這在 docker 中執行時不會返回任何內容。

這些是我的程序。

我的 test.js:

'use strict';
const express = require('express');
const puppeteer = require('puppeteer')
const devices = require('puppeteer/DeviceDescriptors');
const fs = require('fs');
const app = express();
const port = process.env.PORT || 8080;
const validUrl = require('valid-url');


var parseUrl = function(url) {
    url = decodeURIComponent(url)
    if (!/^(?:f|ht)tps?\:\/\//.test(url)) {
        url = 'http://' + url;
    }
    return url;
};

app.get('/', function(req, res) {
    var myurl = parseUrl(req.query.url);
    if (validUrl.isWebUri(myurl)) {
            (async () => {
      const browser =  await puppeteer.launch();
      const newContext = await browser.createIncognitoBrowserContext();
      try {
      const page = await browser.newPage();
      await page.goto(myurl);
      const html = await page.content();
      res.send(html);
      await browser.close();
       } catch (err) {
        console.error(err.message);
      } finally {
        await browser.close();
      }
    })()
    } else {
        res.send('Invalid url: ' + urlToScreenshot);
    }
});

app.listen(port, function() {
    console.log('App listening on port ' + port)
})

我的 package.json

{
  "dependencies": {
    "express": "^4.17.1",
    "puppeteer": "2.0.0",
    "valid-url": "^1.0.9"
  }
}

我的 Dockerfile

FROM buildkite/puppeteer:latest

ENV  PATH="${PATH}:/node_modules/.bin"

# Copy the app
COPY . /app/
#COPY local.conf /etc/fonts/local.conf
WORKDIR app
RUN npm i

# Add user so we don't need --no-sandbox.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
    && mkdir -p /home/pptruser/Downloads \
    && chown -R pptruser:pptruser /home/pptruser \
    && chown -R pptruser:pptruser ./node_modules

# Run everything after as non-privileged user.
USER pptruser

EXPOSE 8080
#ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "test.js"]

我的啟動器.sh

docker stop mytest
docker rm mytest
docker build -t mytest.
docker run --name mytest -p 127.0.0.1:8682:8080 -d mytest

當我輸入這個 curl 命令時,程序在真空中運行。

curl -v -i http://127.0.0.1:8682/?url=https://www.google.com

在此處輸入圖片說明

我的其他容器與本地 IP 地址 (127.0.0.1) 配合良好在此處輸入圖片說明

而如果我在沒有 docker 的情況下運行 nodejs 程序,它運行得很好。

在此處輸入圖片說明

我該如何解決它的擔憂?

TL;DR :確保node正在偵聽0.0.0.0

容器的localhost與主機的localhost不同。 要訪問在容器中運行的服務器,服務器必須首先偵聽0.0.0.0 ,這意味着偵聽所有接口的請求(這將允許在容器中運行的服務器接收來自容器外部的請求 - 在這種情況下,您的主機機器)。 現在,一旦服務器偵聽所有接口,您需要在主機上分配一個端口來偵聽請求並將其轉發到服務器正在偵聽的容器端口。 為此,我們使用-p選項。

正如您在上圖中所見(對於docker ps ),在端口部分,有一些127.0.0.1:port1 -> port2/tcp形式的條目。 這些容器已發布端口以允許來自容器外部的傳入連接。

編輯:

我嘗試使用您的文件重現環境,在 curl 請求之后,我收到此錯誤:

App listening on port 8080
(node:1) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!
[1213/074149.395461:FATAL:zygote_host_impl_linux.cc(116)] No usable sandbox! Update your kernel or see https://chromium.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.
#0 0x557e2b76fe29 base::debug::CollectStackTrace()
#1 0x557e2b6d3ee3 base::debug::StackTrace::StackTrace()
#2 0x557e2b6e86b3 logging::LogMessage::~LogMessage()
#3 0x557e2cec9eee service_manager::ZygoteHostImpl::Init()
#4 0x557e2b30ef6c content::ContentMainRunnerImpl::Initialize()
#5 0x557e2b35b76c service_manager::Main()
#6 0x557e2b30d541 content::ContentMain()
#7 0x557e2b35a9dd headless::(anonymous namespace)::RunContentMain()
#8 0x557e2b35a73b headless::HeadlessShellMain()
#9 0x557e2901f218 ChromeMain
#10 0x7fca167042e1 __libc_start_main
#11 0x557e2901f0aa _start

Received signal 6
#0 0x557e2b76fe29 base::debug::CollectStackTrace()
#1 0x557e2b6d3ee3 base::debug::StackTrace::StackTrace()
#2 0x557e2b76f9b1 base::debug::(anonymous namespace)::StackDumpSignalHandler()
#3 0x7fca1c68e0e0 <unknown>
#4 0x7fca16716fff gsignal
#5 0x7fca1671842a abort
#6 0x557e2b76e815 base::debug::BreakDebugger()
#7 0x557e2b6e8af9 logging::LogMessage::~LogMessage()
#8 0x557e2cec9eee service_manager::ZygoteHostImpl::Init()
#9 0x557e2b30ef6c content::ContentMainRunnerImpl::Initialize()
#10 0x557e2b35b76c service_manager::Main()
#11 0x557e2b30d541 content::ContentMain()
#12 0x557e2b35a9dd headless::(anonymous namespace)::RunContentMain()
#13 0x557e2b35a73b headless::HeadlessShellMain()
#14 0x557e2901f218 ChromeMain
#15 0x7fca167042e1 __libc_start_main
#16 0x557e2901f0aa _start
  r8: 0000000000000000  r9: 00007ffd218069a0 r10: 0000000000000008 r11: 0000000000000246
 r12: 00007ffd21807c58 r13: 00007ffd21806c38 r14: 00007ffd21807c60 r15: 00007ffd21806c50
  di: 0000000000000002  si: 00007ffd218069a0  bp: 00007ffd21806be0  bx: 0000000000000006
  dx: 0000000000000000  ax: 0000000000000000  cx: 00007fca16716fff  sp: 00007ffd21806a18
  ip: 00007fca16716fff efl: 0000000000000246 cgf: 002b000000000033 erf: 0000000000000000
 trp: 0000000000000000 msk: 0000000000000000 cr2: 0000000000000000
[end of stack trace]
Calling _exit(1). Core file will not be generated.


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

    at onClose (/app/node_modules/puppeteer/lib/Launcher.js:348:14)
    at Interface.helper.addEventListener (/app/node_modules/puppeteer/lib/Launcher.js:337:50)
    at Interface.emit (events.js:194:15)
    at Interface.close (readline.js:379:8)
    at Socket.onend (readline.js:157:10)
    at Socket.emit (events.js:194:15)
    at endReadableNT (_stream_readable.js:1125:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我的猜測是您可以與在 docker 中運行的服務進行對話,但是您需要調試它的一些應用程序級問題。 為了證明這一點,我只是用一個簡單的 nodejs 服務器更改了您的test.js文件,並且我能夠連接到它並保持一切不變。 我不是 NodeJS 專家,但你也應該從你的角度嘗試這個練習來確認這一點。

希望這可以幫助!

我遇到了同樣的問題,並通過以下修改解決了這個問題

將此添加到您的泊塢窗中

RUN apk --no-cache add bash g++ gcc libgcc make python chromium    
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true    
RUN yarn global add nodemon    
RUN npm install

並在 puppeteer 中傳遞以下選項。 請注意 puppeteer 版本是 5.3.1

const browser = await puppeteer.launch({
    headless: true,
    ignoreHTTPSErrors :true,
    executablePath: '/usr/bin/chromium-browser',
    args: ['--no-sandbox']
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM