今天公司有个项目交付凭证交付的项目,需要针对不同的任务id做截图,然后交付,原本是用PRA软件做,但是服务器上时不时跑一些其他的项目,PRA的截图非常不稳定,时不时出错。索性自己部署用一个api,传进去url,然后返回图片。细节需求不讲了,实现也非常简单

代码结构如下:

/screenshot-service
  ├── docker-compose.yml
  ├── api/
  │   ├── Dockerfile
  │   ├── package.json
  │   ├── package-lock.json
  │   └── index.js

具体的docker-compose.yml代码如下:

version: '3.8'

services:
  browserless:
    image: browserless/chrome:latest
    environment:
      - MAX_CONCURRENT=10
      - MAX_QUEUE_LENGTH=100
      - TOKEN=换成你自己的token
      - DEFAULT_BLOCK_ADS=true
      - KEEP_ALIVE=true
      - DEFAULT_DISABLE_CACHE=true
    ports:
      - "3000:3000"
    restart: unless-stopped
  
  api:
    build: ./api
    environment:
      - BROWSERLESS_WS_URL=ws://browserless:3000?token=换成前面的token
      - PORT=8080
    ports:
      - "8080:8080"
    depends_on:
      - browserless

api/Dockerfile代码如下:

FROM node:18-alpine

WORKDIR /app
COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 8080
CMD ["node", "index.js"]

package.json的代码如下:

{
  "name": "screenshot-api",
  "version": "1.0.0",
  "description": "Browserless screenshot API",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "puppeteer-core": "^21.0.0"
  }
}

index.js代码如下:

const express = require('express');
const puppeteer = require('puppeteer-core');
const app = express();
const port = process.env.PORT || 8080;

app.get('/screenshot', async (req, res) => {
  const { url, width = 1280, height = 720, fullPage = 'false' } = req.query;
  
  if (!url) {
    return res.status(400).json({ error: 'URL parameter is required' });
  }

  try {
    const browser = await puppeteer.connect({
      browserWSEndpoint: process.env.BROWSERLESS_WS_URL,
    });

    const page = await browser.newPage();
    await page.setViewport({ width: parseInt(width), height: parseInt(height) });
    await page.goto(url, { waitUntil: 'networkidle2', cache: false});

    const screenshot = await page.screenshot({
      fullPage: fullPage === 'true',
      type: 'png',
    });

    await browser.close();

    res.set('Content-Type', 'image/png');
    res.send(screenshot);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: 'Failed to capture screenshot' });
  }
});

app.listen(port, () => {
  console.log(`API server running on port ${port}`);
});

然后回到项目根目录运行

# 重新构建并启动
docker-compose up -d --build

如果失败可以清理后重新构建

# 如果失败可以停止然后清除再重新构建
docker-compose down
docker builder prune -f

效果如下:

By qidian

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注