ZipReport-server is the zipreport HTML to PDF conversion daemon, based on rod and Chromium, written in Go.
Note: zipreport-server 2.xx only works with zipreport library version >= 2.0.0 ,and it is incompatible with previous versions.
Starting with v2.3.0, zipreport-server uses an external configuration file and no longer bundles a self-signed certificate; instead, mount a folder with a proper config.json (see the sample configuration file), and optionally modify and use the sample script to generate your own self-signed certificates; see below for a docker-compose example, and check the migration guide.
Also, please note that prometheus metrics are now exposed using a dedicated port, and metrics are disabled by default. Check the configuration file options for available configuration parameters.
zipreport-server relies on Chromium to render artifacts into PDF. As such, it allows unfettered execution of any external dependencies and scripts your template may use. This behavior may pose a security risk on certain environments. The daemon also relies on the creation of ephemeral http servers on localhost as part of the rendering process.
The zipreport-server API receives a rendering request with an associated ZPT resource. For each rendering request, zipreport-server launches an internal http server to serve the ZPT content, and then instructs a Chromium instance to open the temporary url and render to PDF.
The settling time for the internal HTML/JS rendering process can either be a default value in milisseconds (the default behavior), or triggered by writing 'zpt-view-ready' to the JS console. By using the console approach, the PDF generation is triggered only after all dynamic canvas elements were generated.
Format: multipart/form-data
Fields:
| Field | Mandatory | Description |
|---|---|---|
| report | Yes | Report file |
| page_size | Yes | Page size (A5/A4/A3/Letter/Legal/Tabloid) |
| margins | Yes | Margin type (none/minimal/standard) |
| landscape | No | If true, print in landscape |
| script | No | Main html file (default report.html) |
| settling_time | No | Settling time, in ms (default 200ms, see below) |
| timeout_job | No | Job timeout, in seconds (default 120s, see below) |
| timeout_js | No | JavaScript event timeout, in seconds (default 30s, see below) |
| js_event | No | If true, wait for the javascript event (see below) |
| ignore_ssl_errors | No | If true, ssl errors in referenced resources will be ignored |
settling_time (default: 200)
Value in ms to wait after the DOM is ready to print the report. This setting is ignored if js_event is enabled.
timeout_job (default 120)
Waiting time, in seconds, to perform the conversion operation, including waiting times such as settling_time.
timeout_js (default 30)
Time to wait, in seconds, for the javascript event to be triggered, before generating the report anyway. Requires js_event to be true.
js_event
If true, the system will wait upto timeout_js for a specific console message before generating the PDF. This allows for dynamic pages to signal when DOM manipulation is finished.
Triggering example:
<script>
(function() {
// signal end of composition
console.log("zpt-view-ready")
})();
</script>Prometheus metrics endpoint. Besides the default internal Go metrics, the following are provided:
| metric | type | description |
|---|---|---|
| total_requests | counter | Total conversion requests |
| total_request_success | counter | Number of successful API calls |
| total_request_error | counter | Number of failed API calls |
| conversion_time | histogram | Elapsed conversion time histogram, in seconds. The upper bound is 120 |
| current_http_servers | gauge | Current internal HTTP server count |
| current_browsers | gauge | Current internal browser instance count |
zipreport-server performs header-based authentication using the token specified in your configuration file (apiServer.options.authTokenSecret). Clients must pass the authentication token in the X-Auth-Key header.
Environment Variable Override
The API key can also be set via the ZIPREPORT_API_KEY environment variable, which takes precedence over the config file. This is useful for Docker deployments:
docker run -p 6543:6543 -e ZIPREPORT_API_KEY=your-secret-key zipreport-server:2.3.1Example:
curl -X POST http://localhost:6543/v2/render \
-H "X-Auth-Key: your-secret-token" \
-F "[email protected]" \
-F "page_size=A4" \
-F "margins=standard" \
-F "script=index.html" \
-o output.pdfWithout authentication, requests will receive 401 Unauthorized.
Starting with version 2.3.0, zipreport-server uses a configuration file. The Docker image includes a default configuration, so you can run with just the ZIPREPORT_API_KEY environment variable for basic usage. For advanced configuration, mount a custom config file to /app/config/config.json.
Multi-Platform Support
Docker images are built for both linux/amd64 and linux/arm64. This enables running on:
- Intel/AMD servers and desktops (amd64)
- Apple Silicon Macs — M1/M2/M3/M4 (arm64)
- ARM64 cloud instances — AWS Graviton, Ampere, etc.
The correct image is selected automatically by Docker based on the host architecture. Chromium is sourced from different locations depending on the platform:
- amd64: Google's Chromium snapshots (same source as go-rod's default)
- arm64: Playwright CDN (arm64 Chromium builds)
Both variants are functionally identical and store the browser in rod's expected cache location.
Quick Start
# Build locally
docker build . --tag zipreport-server:2.3.1
# Run with API key (uses default config, HTTP only, no TLS)
docker run -p 6543:6543 -e ZIPREPORT_API_KEY=your-secret-key zipreport-server:2.3.1Production Deployment with Custom Configuration
Create a config.json file (see config.sample.json or complete reference):
{
"apiServer": {
"host": "",
"port": 6543,
"options": {
"authTokenSecret": "your-secure-random-token-here",
"defaultSecurityHeaders": "1"
},
"tlsEnable": false
},
"zipReport": {
"concurrency": 8,
"baseHttpPort": 42000
},
"log": {
"level": "info"
}
}Then run with your configuration:
# Mount your configuration directory
docker run -p 6543:6543 \
-v $(pwd)/config:/app/config \
zipreport-server:2.3.1With TLS/HTTPS
Generate certificates (or use your own):
cd config
./generate_certs.shUpdate config.json to enable TLS:
{
"apiServer": {
"tlsEnable": true,
"tlsCert": "config/ssl/server.crt",
"tlsKey": "config/ssl/server.key",
"options": {
"authTokenSecret": "your-secure-random-token-here"
}
}
}Run with TLS:
docker run -p 6543:6543 \
-v $(pwd)/config:/app/config \
zipreport-server:2.3.1Using Prebuilt Image
# Pull latest version
docker pull ghcr.io/zipreport/zipreport-server:latest
# Or specific version
docker pull ghcr.io/zipreport/zipreport-server:2.3.1
# Run with mounted configuration
docker run -p 6543:6543 \
-v $(pwd)/config:/app/config \
ghcr.io/zipreport/zipreport-server:2.3.1Docker Compose Example
version: '3.8'
services:
zipreport:
image: ghcr.io/zipreport/zipreport-server:2.3.1
ports:
- "6543:6543"
- "2220:2220" # Prometheus metrics (if enabled)
volumes:
- ./config:/app/config
restart: unless-stoppedConfiguration Options
See docs/configuration.md for complete configuration reference with 70+ options including:
- API server settings (host, port, timeouts, TLS)
- Authentication configuration
- Prometheus metrics endpoint
- ZipReport rendering engine settings
- Logging configuration with rotation
Migration from 2.2.x
If upgrading from 2.2.x or earlier, see the migration guide for converting environment variables to the new configuration file format.
Build Binaries
# Build all binaries (zipreport-server and browser-update)
make build
# Or just build
makeBinaries will be created in ./bin/:
bin/zipreport-server- Main server binarybin/browser-update- Browser download utility (fetches Chromium for the current platform)
Updating Chromium Versions
The Chromium revision constants are defined in pkg/browser/browser.go:
Revision— Chromium snapshot revision for amd64 (must match rod'sRevisionDefaultso the launcher finds it in the cache)RevisionPlaywright— Playwright CDN revision for arm64 Linux builds
To update the bundled Chromium version, change these constants and rebuild. The browser-update command will download the new version on next run.
Generate Self-Signed Certificates
# Generate certificates in config/ssl/
cd config
./generate_certs.sh
# Or using make (generates in cert/ directory)
make certificateRun Tests
# Run all tests
make test
# Run quick tests (skip long-running tests)
make test-short
# Run with extended timeout
make test-integrationFormat Code
make fmtRun Server Locally
# Make sure you have a configuration file
cp config/config.sample.json config/config.json
# Edit config.json with your settings
# Run the server
./bin/zipreport-server -c config/config.json
# Or use default config location
./bin/zipreport-serverThe ZipReport Project is sponsored exclusively by BlackShield
MIT License - see LICENSE file for details