Deploy across environments
If you keep separate installations or workspaces for test, staging and production, each has its own templates. Copy tested templates from one to another by hand in Studio, or in your release pipeline.
An export holds each template’s current draft and the current workspace files, not the published versions. Export when the drafts in the source environment are the ones you tested.
By hand in Studio
Section titled “By hand in Studio”- In the source environment, open Workspace → Editor in Studio and choose + → Export workspace next to the Files heading. You get a zip file. To copy one folder, choose Export folder in that folder’s … menu instead. Files at the workspace root are only in a workspace export.
- In the target environment, choose + → Import… in the editor, drop the zip in, and click Import workspace (or Import folder). New templates and files are added; existing ones are updated.
- Check the imported templates, then publish them. Until you do, documents still render with the previous versions.
In your release pipeline
Section titled “In your release pipeline”Your build exports the templates once, and each deployment imports them, so every environment gets the templates that were tested with the release.
1. Give the pipeline an API key per environment
Section titled “1. Give the pipeline an API key per environment”In Studio, open Manage → API keys in each environment, click Create API key, and give it
the permissions template:read, template:write, template:publish and asset:manage. Store
each key in your pipeline’s secret store.
On a self-hosted installation you can instead set a deploy key in .env with DEPLOY_API_KEY
and DEPLOY_WORKSPACE, so no one has to open Studio; see
the deploy key.
2. Export in the build
Section titled “2. Export in the build”Run this in your build, with PDF_URL and API_KEY set to the test environment’s address and
key:
curl -fo templates.zip "$PDF_URL/v1/workspace/export" \ -H "x-api-key: $API_KEY"Keep templates.zip with the release’s build output, so every deployment of that release imports
the same file.
3. Import in each deployment
Section titled “3. Import in each deployment”Run this in each deployment, with PDF_URL and API_KEY set to that environment’s address and
key, and RELEASE_NUMBER set by your pipeline:
printf '{"archiveBase64":"%s","parentId":null,"publish":true,"label":"Release %s"}' \ "$(base64 < templates.zip | tr -d '\n')" "$RELEASE_NUMBER" > import.json
curl -f "$PDF_URL/v1/workspace-folders/import" \ -H "x-api-key: $API_KEY" \ -H "content-type: application/json" \ --data @import.json -o result.json
cat result.jsonjq -e '.unpublished == null' result.json > /dev/null # fails the step if a template stayed a draft"publish": true publishes the imported templates straight away. The response counts what was
created, updated and published; see import and export.
If a template could not be published, it is listed in unpublished with the reason, and the step
fails. The other templates are already live.
label is saved on the import’s entries under Manage → Audit log (in each entry’s
Event details), so you can see which release changed what.
Redeploying the same release is safe: unchanged templates are left alone. To roll back, deploy the earlier release; its templates are published as new versions.
What an import changes
Section titled “What an import changes”- Copied: templates and workspace files (partials, stylesheets, data, scripts, translations, fonts, images and workbooks). API keys, webhooks, signing certificates, users, render limits and past renders stay in each environment.
- Nothing is deleted: a template you removed in the source stays in the target until you delete it there.
Different settings per environment
Section titled “Different settings per environment”Self-hosted installations only. To make a template behave differently per environment, for example a “TEST” watermark everywhere except production, keep one set of templates and give each environment its own value.
-
Set the value on each server. Add a
SCRIPT_ENVline to each installation’s.envfile, then rundocker compose up -d:.env on the test and staging servers SCRIPT_ENV=ADD_WATERMARK=true.env on the production server SCRIPT_ENV=ADD_WATERMARK=false -
Read it in a script. In the Studio editor of your test environment, choose + → New entity → Script next to the Files heading and name it
watermark.js. In the script’s header, change Runs where included to Runs before every render. The script reads the value fromprocess.envand passes it to every template:watermark.js (in Studio) function beforeRender(req, res) {req.data.AddWatermark = process.env.ADD_WATERMARK === "true";} -
Use it in the template. Show the watermark only when the value is set:
{{#if @root.AddWatermark}}<div class="watermark">TEST</div>{{/if}} -
Publish the template so its new version includes the script. The script and template then move to the other environments with the rest of your templates; only the
.envvalue differs.
Troubleshooting
Section titled “Troubleshooting”| Error | What to do |
|---|---|
403 FORBIDDEN |
The key is missing a permission; see step 1. |
429 RATE_LIMITED |
Another import or export is running. Retry the step. |
LIMIT_EXCEEDED (400 or 413) |
The workspace is too large for one zip. Export the folders one at a time with GET /v1/workspace-folders/{id}/export and import each zip. Copy files at the workspace root by hand. |
404 NOT_FOUND on a folder export |
The folder ID is wrong or belongs to another workspace. |
A template in unpublished |
Read its message. Usually the template uses a file outside the exported folder that the target lacks; export the whole workspace instead. |