pdf printer based on puppeteer.
Install:
npm install --save @plotdb/print
@plotdb/print
uses puppeteer to generate PDF from html or link. You can run @plotdb/print
as a print server in Docker (called 'Cloud Mode') and request PDF via API calls, or run puppeteer directly in your server (called 'Local Mode').
Since you won't need puppeteer in local server when calling @plotdb/print in cloud mode, puppeteer related modules are optional and listed in peer dependencies and can be installed via:
npm install puppeteer@^23.11.1 easy-pdf-merge@^0.2.6 tmp@^0.2.1
Then, in your code:
# Get a printer instance
printer.get!
.then ->
# Print some html
printer.print {html: "my html to be printed ..."}
.then (buf) ->
# Print via link
printer.print {link: "https://to-your-website..."}
.then ({buf}) -> # return a Buffer object of the desired PDF
You will have first setup api endpoint that can generate PDF for you. Check setup API endpoint
section below.
Once you have prepared the api endpoint, in your code:
my-printer = new printer {server: {key: "your-api-key", url: "api-endpoint"}}
my-printer.init!
.then ->
my-printer.print {link: "https://to-your-website..."}
.then ({stream}) ->
# return a Stream object of the desired PDF, you can then e.g.:
stream.pipe response
To run @plotdb/print in cloud mode, a simple server exposing an API endpoint /pdf
is available as server.js
, which can be used independently or used with docker.
Note Puppeteer requires certain libraries in order to run with node:20-slim, which is listed in docker/Dockerfile; however based on versions this may vary so you should modify it if necessary.
Additionally, it might have issues running puppeteer in docker under MacOS, yet it will work in places such as Cloud Run.
You can find a Dockerfile under docker
folder, which can be built by:
cd <repo-root>
docker buildx build --platform=linux/amd64 -t <your-tag> docker
You can run the prepared local server via:
cd <repo-root>
node dist/server.js
You probably will want to create your owner version of print server, in this case you can refe to src/server.ls or web/server.ls for a minimal example of creating a print server.
These server script read APIKEY
environment variable which will be set via secret.key
file in npm script print-server
and start
, which contains a single line of secret code. You can generate a random secret code with crypto
:
require("crypto").randomBytes(32).toString("base64")
To build and push directly to Google Artifact Repository for later user:
docker buildx build --platform=linux/amd64 \
-t [your-region]-docker.pkg.dev/[project-id]/[repo-name]/[image-name]:latest \
--push docker
For example:
docker buildx build --platform=linux/amd64
-t asia-east1-docker.pkg.dev/my-project/puppeteer-pdf/puppeteer-pdf:latest
--push docker
To deploy (use above name as example), you will need first create a secret:
# create: note, this only need to be run once.
gcloud secrets create APIKEY --data-file=<(echo "your-secret-key")
# update: when you need to update your key. note old key won't be deleted automatically
gcloud secrets versions add APIKEY --data-file=<(echo "new-key")
# to allow cloud run access this secret, find out your service account:
gcloud run services describe my-pdf-service --platform=managed --region=asia-east1 \
--format="value(spec.template.spec.serviceAccountName)"
# then grant access to it:
gcloud projects add-iam-policy-binding <project-id> \
--member="serviceAccount:<the-account-returned-in-previous-command>" \
--role="roles/secretmanager.secretAccessor"
gcloud run deploy my-pdf-service \
--image=asia-east1-docker.pkg.dev/my-project/puppeteer-pdf/puppeteer-pdf:latest \
--platform=managed \
--region=asia-east1 \
--allow-unauthenticated \
--memory=512Mi \
--cpu=1 \
--update-secrets=APIKEY=APIKEY:latest
Once deployed, you can test it with the dummy api endpoint ping
which should respond with a simple pong
string:
curl https://<your-cloud-run-domain>/ping
And you can use the secret key you used and the url provided by google cloud run to prepare the configuration for @plotdb/print
:
my-printer = new print {server: {key: "your-secret-key", url: "path-to-cloud-run-api"}
my-printer.init!then -> ...
MIT