[ Day 05 ] 用 Puppeteer 來做自動化機器人吧 (四) : Dockerize 篇


上篇 用 Puppeteer 來做自動化機器人吧 (三) : 應用篇 用 Puppeteer 實作了機器人自動排程貼文,今天想來談談 Puppeteer 如何 Dockerize,以便可以部署在不同環境上。

接下將分享如何建立 Dockerfile 以及幾項我當初實作時遇到的一些小雷。

一、建立 Dockerfile

第一步是要先下載 Docker,這邊就不多贅述。接下來在專案底下建立 Dockerfile,將下方程式碼複製貼上後儲存。

接下來要先 build image,指令為 docker build -t puppeteer-bot .

build 完後就可以 docker run -d --name puppeteer-bot-timeline puppeteer-bot:latest

我們可以透過 docker logs puppeteer-bot-timeline 查看 console.log 出來的內容 ( 如果有的話 )。

* 記得 headless 要設定為 true 才能運行唷。

FROM node:11-slim
# 下載 chromium 在 docker 運行時所需套件
RUN apt-get update && apt-get install -yq libgconf-2-4
RUN apt-get update && apt-get install -y wget --no-install-recommends \
    && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
    && apt-get update \
    && apt-get install -y google-chrome-unstable \
      --no-install-recommends \
    && rm -rf /var/lib/apt/lists/* \
    && apt-get purge --auto-remove -y curl \
    && rm -rf /src/*.deb

ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init
USER root
ENV TZ=Asia/Taipei # 轉換時區,非必要
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY . /app/
WORKDIR app
RUN npm install
EXPOSE 8084
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "main.js"]

踩雷點分享

接下來想跟大家分享當初在 Dockerize 遇到的一些狀況:

1. Puppeteer 安裝 Chromium 時會缺少一些套件

一開始想說 Dockerize 應該很容易,安裝 node 然後 npm install 就好了,但沒想到一直報錯說 Chromium 缺少套件。後來去 Puppeteer 的 issue 上查到原來安裝 Puppeteer 時會自動安裝 Chromium,但要在 Docker 上運行的相關套件並不會自動下載,後來就照著 Github 上的教學去安裝相關套件,後續才能運行。

2. Page Focus 問題

在開發時我是透過開啟一個 browser,然後持續開三個分頁來操作,希望能加快處理的速度。開發過程中我發現當 headless : false 時,他會同時開啟三個分頁,但只有被 focus 的 tab 有在運行接下來的 script,另外兩頁並沒有。因為我在運行完會被 tab close,所以接下來第二頁被 focus 後會再開始運行。

查了一下 issue,有查到一樣的問題,但在 headless: true 的時候,是會同時處理的,但目前還沒找到其他解法。

3. Page Crash 問題

上面有提到我在一個瀏覽器上操作三個分頁,放在 docker 上運行,一直遇到 Page Crash 問題,原先覺得是 memory 開不夠,但在 aws 上看 memory 使用狀況覺得好像還好。後來有在 issue 上查到原來要在 launch browser 時加上 --disable-dev-shm-usage

By default, Docker runs a container with a /dev/shm shared memory space 64MB.
This is typically too small for Chrome and will cause Chrome to crash when rendering large pages.
To fix, run the container with docker run --shm-size=1gb to increase the size of /dev/shm.
Since Chrome 65, this is no longer necessary.
Instead, launch the browser with the --disable-dev-shm-usage flag:
const browser = await puppeteer.launch({
args: ['--disable-dev-shm-usage']
});

4. 時區問題

這個問題跟 Puppeteer 比較無關,是跟上篇在實作 LINE 貼文串發文機器人相關。我在 docker 上運行時,將排程時間設定為 7:00,但實際去後台看會變成 15:00,但我很確定機器人是輸入 7:00 ( 畢竟是一個一個數字輸入 ),後來發現 LINE 貼文串後台會自動幫你轉時區(!),所以就要在 Dockerfile 指定 container 的時區,才不會被加 8 小時。

總結

今天分享了如何建立 Dockerfile,能夠在 Docker 運行 Puppeteer。也分享了四個遇到的問題,希望對大家有幫助。如果有任何建議,也歡迎指教及分享,謝謝!

參考資料

  1. Hosting Puppeteer in a Docker container
  2. 在自己建立的 Debian docker image 設定時區
  3. What is "Page crashed!" error?
#node.js #Puppeteer







你可能感興趣的文章

滲透測試基本技術 第二章(前篇)

滲透測試基本技術 第二章(前篇)

LeetCode JS Easy 2704. To Be Or Not To Be

LeetCode JS Easy 2704. To Be Or Not To Be

安裝RabbitMQ Server

安裝RabbitMQ Server






留言討論