今天公司有个项目交付凭证交付的项目,需要针对不同的任务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
效果如下:
