A lightweight microservice to generate screenshots of webpages using a headless Chrome browser. Built with Node.js, Express, and Puppeteer, orchestrated via Docker Compose.
- Simple API: RESTful endpoint to request screenshots.
- Dockerized: specific containers for the API and the headless browser.
- Network Aware: Configured to run on an external
caddynetwork for easy integration with other services.
- Docker
- Docker Compose
-
Clone the repository (if you haven't already):
git clone https://github.com/sicaboy/webpage-screenshot-api.git cd webpage-screenshot-api -
Configure Environment: copy
.env.exampleto.envand set yourAPI_SECRET.cp .env.example .env
-
Start the services:
docker compose up --build -d
This will start two containers:
screenshot-api: The API service listening on port8080.screenshot-browser: The headless Chromium instance.
Secure the API by setting an API_SECRET environment variable in your .env file. When set, all requests must include the X-API-Secret header.
Endpoint: POST /screenshot
Request Headers:
Content-Type: application/jsonX-API-Secret: <your_api_secret>(Required ifAPI_SECRETenv var is set)
Request Body:
| Field | Type | Description | Required |
|---|---|---|---|
url |
String | The full URL of the webpage to capture. | Yes |
device |
String | Device name to emulate (e.g., "iPhone 13", "iPad Pro"). Overrides width/height. | No |
width |
Number | Viewport width in pixels (default: 1280). Ignored if device is set. |
No |
height |
Number | Viewport height in pixels (default: 800). Ignored if device is set. |
No |
fullPage |
Boolean | If true, captures the full scrollable page. | No |
darkMode |
Boolean | If true, forces the browser into dark mode. | No |
delay |
Number | Wait time in milliseconds after load before capturing. | No |
waitForSelector |
String | CSS selector to wait for before capturing (max 10s timeout). | No |
Response: Returns a JSON object containing the Base64 encoded screenshot.
{
"success": true,
"screenshot": "iVBORw0KGgoAAAANSUhEUgAA..."
}curl -X POST http://localhost:8080/screenshot \
-H "Content-Type: application/json" \
-H "X-API-Secret: my_secure_secret_123" \
-d '{"url": "https://google.com"}'curl -X POST http://localhost:8080/screenshot \
-H "Content-Type: application/json" \
-H "X-API-Secret: my_secure_secret_123" \
-d '{
"url": "https://news.ycombinator.com",
"device": "iPhone 13 Pro",
"fullPage": true,
"darkMode": true,
"delay": 1000
}'The response screenshot field contains the Base64 image data, which you can decode and save as a .png file or display directly in a frontend application (e.g., <img src="data:image/png;base64,..." />).