mirror of
https://github.com/documenso/documenso.git
synced 2026-07-14 06:47:10 +10:00
feat: support DOCX uploads via Gotenberg (#2801)
Uploaded .docx files are converted to PDF on the server using a Gotenberg sidecar before entering the normal envelope pipeline. The feature is opt-in via NEXT_PRIVATE_DOCUMENT_CONVERSION_URL; when unset, only PDF uploads are accepted. A per-process circuit breaker opens for 30s after a conversion failure to shed load. Ships a dev Dockerfile that layers Microsoft Core Fonts and additional language fonts onto the upstream Gotenberg image for better fidelity. Co-authored-by: Ephraim Duncan <55143799+ephraimduncan@users.noreply.github.com> Co-authored-by: Ephraim Duncan <55143799+ephraimduncan@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: AI Recipient & Field Detection (Self-hosting)
|
||||
title: AI Recipient & Field Detection
|
||||
description: Configure Google Vertex AI so Documenso can detect recipients and fields automatically.
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,408 @@
|
||||
---
|
||||
title: Document Conversion
|
||||
description: Enable DOCX uploads on a self-hosted Documenso instance by running a Gotenberg sidecar that converts Word documents to PDF.
|
||||
---
|
||||
|
||||
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
|
||||
import { Callout } from 'fumadocs-ui/components/callout';
|
||||
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||
|
||||
## Overview
|
||||
|
||||
Documenso can accept `.docx` uploads in addition to PDFs. When a user uploads a Word document, the Documenso server sends it to a [Gotenberg](https://gotenberg.dev) service which uses LibreOffice to convert it to PDF. The converted PDF is what gets stored, signed, and downloaded. The original DOCX is discarded.
|
||||
|
||||
This feature is **opt-in for self-hosted instances**. When the conversion service is not configured, DOCX uploads are rejected in the UI and only PDFs are accepted.
|
||||
|
||||
| Property | Value |
|
||||
| ----------------------- | -------------------------------------------------------------------- |
|
||||
| Conversion engine | [Gotenberg](https://gotenberg.dev) + LibreOffice |
|
||||
| Input format | `.docx` (Office Open XML Word documents) |
|
||||
| Output format | PDF |
|
||||
| Network requirement | Documenso must reach the Gotenberg HTTP API |
|
||||
| Default request timeout | 30 seconds per file |
|
||||
| Failure handling | An internal circuit breaker opens for 30 seconds after a failure |
|
||||
|
||||
<Callout type="info">
|
||||
Only `.docx` is accepted. Legacy `.doc`, `.odt`, `.rtf`, and other LibreOffice-supported formats
|
||||
are rejected at the upload step even when Gotenberg is configured.
|
||||
</Callout>
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
- A running Gotenberg 8 instance with the LibreOffice module (`gotenberg/gotenberg:8-libreoffice` or newer).
|
||||
- Network reachability from the Documenso container to the Gotenberg HTTP API.
|
||||
- A version of Documenso that includes the document conversion feature.
|
||||
|
||||
## Build the Gotenberg Image
|
||||
|
||||
The upstream `gotenberg/gotenberg:8-libreoffice` image works out of the box, but it ships only **metric-compatible font substitutes** (Carlito for Calibri, Liberation for Arial/Times/Courier). Layout widths are preserved but documents will look noticeably different from Word.
|
||||
|
||||
For better fidelity, especially for non-Latin scripts, build a derived image that adds Microsoft Core Fonts and additional language fonts. The Documenso repository ships a reference Dockerfile at [`docker/development/Dockerfile.gotenberg`](https://github.com/documenso/documenso/blob/main/docker/development/Dockerfile.gotenberg) that you can use as a starting point:
|
||||
|
||||
```dockerfile
|
||||
FROM gotenberg/gotenberg:8-libreoffice
|
||||
|
||||
USER root
|
||||
|
||||
RUN echo "deb http://deb.debian.org/debian trixie contrib non-free" \
|
||||
> /etc/apt/sources.list.d/contrib.list \
|
||||
&& echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" \
|
||||
| debconf-set-selections \
|
||||
&& apt-get update -qq \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \
|
||||
ca-certificates \
|
||||
ttf-mscorefonts-installer \
|
||||
fonts-symbola \
|
||||
fonts-noto-extra \
|
||||
fonts-hosny-amiri \
|
||||
fonts-thai-tlwg \
|
||||
fonts-sil-padauk \
|
||||
fonts-sarai \
|
||||
fonts-samyak-taml \
|
||||
culmus \
|
||||
libfribidi0 \
|
||||
libharfbuzz0b \
|
||||
&& fc-cache -f \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
USER gotenberg
|
||||
```
|
||||
|
||||
<Callout type="warn">
|
||||
`ttf-mscorefonts-installer` accepts the Microsoft Core Fonts EULA on your behalf via debconf. By
|
||||
installing this image you are agreeing to those licence terms. Review them before publishing the
|
||||
image.
|
||||
</Callout>
|
||||
|
||||
Build and publish the image to a registry you control:
|
||||
|
||||
```bash
|
||||
docker build -t registry.example.com/documenso/gotenberg:8 \
|
||||
-f Dockerfile.gotenberg .
|
||||
docker push registry.example.com/documenso/gotenberg:8
|
||||
```
|
||||
|
||||
If you do not need extra fonts, skip the build step entirely and reference `gotenberg/gotenberg:8-libreoffice` directly in the next section.
|
||||
|
||||
## Deploy the Service
|
||||
|
||||
The Gotenberg service should run **alongside** your Documenso container, not exposed to the public internet. The conversion service has no built-in authorisation beyond HTTP Basic auth, so it should sit on a private network or behind your existing reverse proxy.
|
||||
|
||||
<Tabs items={['Docker Compose', 'Kubernetes', 'External Instance']}>
|
||||
<Tab value="Docker Compose">
|
||||
|
||||
Add a `gotenberg` service to the `compose.yml` you use for Documenso:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
gotenberg:
|
||||
image: registry.example.com/documenso/gotenberg:8
|
||||
# Or use upstream directly:
|
||||
# image: gotenberg/gotenberg:8-libreoffice
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
GOTENBERG_API_BASIC_AUTH_USERNAME: ${GOTENBERG_USERNAME}
|
||||
GOTENBERG_API_BASIC_AUTH_PASSWORD: ${GOTENBERG_PASSWORD}
|
||||
command:
|
||||
- gotenberg
|
||||
- --api-enable-basic-auth
|
||||
- --libreoffice-deny-private-ips
|
||||
- --api-timeout=500s
|
||||
- --libreoffice-auto-start
|
||||
- --libreoffice-start-timeout=300s
|
||||
- --pdfengines-disable-routes
|
||||
- --webhook-disable
|
||||
healthcheck:
|
||||
test: ['CMD', 'curl', '-fsS', 'http://localhost:3000/health']
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
|
||||
documenso:
|
||||
# existing config
|
||||
environment:
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_URL: http://gotenberg:3000
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_USERNAME: ${GOTENBERG_USERNAME}
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_PASSWORD: ${GOTENBERG_PASSWORD}
|
||||
depends_on:
|
||||
gotenberg:
|
||||
condition: service_healthy
|
||||
```
|
||||
|
||||
Do **not** publish Gotenberg's port (`3000`) to the host. Documenso reaches it over the internal Docker network using the service name (`http://gotenberg:3000`).
|
||||
|
||||
</Tab>
|
||||
<Tab value="Kubernetes">
|
||||
|
||||
Create a Deployment, Service, and Secret. Example manifests:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: gotenberg-auth
|
||||
namespace: documenso
|
||||
stringData:
|
||||
username: documenso
|
||||
password: replace-me-with-a-strong-password
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: gotenberg
|
||||
namespace: documenso
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels: { app: gotenberg }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: gotenberg }
|
||||
spec:
|
||||
containers:
|
||||
- name: gotenberg
|
||||
image: registry.example.com/documenso/gotenberg:8
|
||||
args:
|
||||
- gotenberg
|
||||
- --api-enable-basic-auth
|
||||
- --libreoffice-deny-private-ips
|
||||
- --api-timeout=500s
|
||||
- --libreoffice-auto-start
|
||||
- --libreoffice-start-timeout=300s
|
||||
- --pdfengines-disable-routes
|
||||
- --webhook-disable
|
||||
env:
|
||||
- name: GOTENBERG_API_BASIC_AUTH_USERNAME
|
||||
valueFrom: { secretKeyRef: { name: gotenberg-auth, key: username } }
|
||||
- name: GOTENBERG_API_BASIC_AUTH_PASSWORD
|
||||
valueFrom: { secretKeyRef: { name: gotenberg-auth, key: password } }
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
readinessProbe:
|
||||
httpGet: { path: /health, port: 3000 }
|
||||
livenessProbe:
|
||||
httpGet: { path: /health, port: 3000 }
|
||||
initialDelaySeconds: 30
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gotenberg
|
||||
namespace: documenso
|
||||
spec:
|
||||
selector: { app: gotenberg }
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
```
|
||||
|
||||
Then reference the in-cluster URL from Documenso's environment:
|
||||
|
||||
```
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_URL=http://gotenberg.documenso.svc.cluster.local:3000
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_USERNAME=documenso
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_PASSWORD=replace-me-with-a-strong-password
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab value="External Instance">
|
||||
|
||||
Documenso does not have to colocate with Gotenberg. You can point it at any reachable Gotenberg deployment: a managed instance, a shared internal service, or a Gotenberg-compatible API.
|
||||
|
||||
```bash
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_URL=https://gotenberg.internal.example.com
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_USERNAME=documenso
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_PASSWORD=replace-me-with-a-strong-password
|
||||
```
|
||||
|
||||
The remote instance must:
|
||||
|
||||
- Expose the LibreOffice route `/forms/libreoffice/convert`.
|
||||
- Be reachable from the Documenso container with low enough latency that the 30 second per-request timeout is comfortable.
|
||||
- Be on a private network or require authentication. Uploaded documents are sent to it as multipart form data and may contain sensitive content.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Recommended Gotenberg Flags
|
||||
|
||||
The flags in the examples above are not arbitrary. Each one matters for a production deployment.
|
||||
|
||||
| Flag | Why it matters |
|
||||
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--api-enable-basic-auth` | Requires HTTP Basic credentials on every API route. Without this, anyone with network access to the container can convert arbitrary documents. |
|
||||
| `--libreoffice-deny-private-ips` | Rejects any outbound fetch LibreOffice tries to make to private, loopback, link-local, or cloud-metadata addresses while processing a document. Mitigates SSRF via malicious `.docx` files that embed `TargetMode="External"` references. Requires Gotenberg 8.32.0. |
|
||||
| `--api-timeout=500s` | Server-side request ceiling. Documenso aborts at 30 s by default, so this is a safety net for very large documents. |
|
||||
| `--libreoffice-auto-start` | Starts LibreOffice at container boot so the first request is not slow. |
|
||||
| `--libreoffice-start-timeout=300s`| Allows LibreOffice up to 5 minutes to come up under load. |
|
||||
| `--pdfengines-disable-routes` | Disables the PDF engines routes Documenso does not use. Shrinks the attack surface. |
|
||||
| `--webhook-disable` | Disables webhook callbacks. Documenso uses synchronous requests only. |
|
||||
|
||||
## Configure Documenso
|
||||
|
||||
Set the following environment variables on the Documenso container and restart it.
|
||||
|
||||
### Required
|
||||
|
||||
| Variable | Description |
|
||||
| ------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| `NEXT_PRIVATE_DOCUMENT_CONVERSION_URL`| Base URL of the Gotenberg service (e.g., `http://gotenberg:3000`). Leave unset to disable the feature. |
|
||||
|
||||
### Optional
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ------------------------------------------- | ------- | -------------------------------------------------------------------------------------------- |
|
||||
| `NEXT_PRIVATE_DOCUMENT_CONVERSION_USERNAME` | | HTTP Basic auth username. Set when Gotenberg runs with `--api-enable-basic-auth`. |
|
||||
| `NEXT_PRIVATE_DOCUMENT_CONVERSION_PASSWORD` | | HTTP Basic auth password. Set together with the username. |
|
||||
| `NEXT_PRIVATE_DOCUMENT_CONVERSION_TIMEOUT_MS`| `30000` | Per-request timeout in milliseconds. Increase for very large documents. |
|
||||
|
||||
<Callout type="info">
|
||||
When `NEXT_PRIVATE_DOCUMENT_CONVERSION_URL` is set, the public flag
|
||||
`NEXT_PUBLIC_DOCUMENT_CONVERSION_ENABLED` is derived automatically on server start. You do not
|
||||
need to set it yourself, and setting it manually has no effect.
|
||||
</Callout>
|
||||
|
||||
### Example `.env` Snippet
|
||||
|
||||
```bash
|
||||
# Document conversion (DOCX -> PDF)
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_URL=http://gotenberg:3000
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_USERNAME=documenso
|
||||
NEXT_PRIVATE_DOCUMENT_CONVERSION_PASSWORD=replace-me-with-a-strong-password
|
||||
# NEXT_PRIVATE_DOCUMENT_CONVERSION_TIMEOUT_MS=60000
|
||||
```
|
||||
|
||||
## Verify the Setup
|
||||
|
||||
{/* prettier-ignore */}
|
||||
<Steps>
|
||||
<Step>
|
||||
### Restart the Documenso container
|
||||
|
||||
Restart so the new environment variables are picked up.
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
### Confirm Gotenberg is healthy
|
||||
|
||||
From a shell inside the Documenso container or another container on the same network:
|
||||
|
||||
```bash
|
||||
curl -fsS http://gotenberg:3000/health
|
||||
```
|
||||
|
||||
The endpoint is exempt from basic auth and should return `200 OK`.
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
### Upload a test DOCX
|
||||
|
||||
In the Documenso web UI, open **Documents** and try uploading a small `.docx` file. The upload dropzone should accept it, and after a few seconds the editor should open with the converted PDF.
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
### Check the server logs
|
||||
|
||||
Successful conversions log a `document_conversion_attempt` event with `result: "success"`, the duration, and the file size. Failures log the same event with `result: "error"` and an error code (`CONVERSION_SERVICE_UNAVAILABLE`, `CONVERSION_FAILED`, or `UNSUPPORTED_FILE_TYPE`).
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- **Treat the conversion service as untrusted internal infrastructure.** Documents pass through Gotenberg in plain form. Run it on a private network and require HTTP Basic auth.
|
||||
- **Run with `--libreoffice-deny-private-ips`.** Without this flag, a malicious `.docx` can trigger LibreOffice to fetch URLs from your internal network (SSRF).
|
||||
- **Disable unused routes.** `--pdfengines-disable-routes` and `--webhook-disable` reduce attack surface. Documenso only uses the LibreOffice convert route.
|
||||
- **Do not expose Gotenberg to the public internet.** Even with basic auth, this is a document-processing service with a non-trivial CPU and memory footprint; exposing it invites abuse.
|
||||
- **Rotate credentials.** Rotating the basic auth secret is a config change in both Gotenberg and Documenso, followed by a restart of each.
|
||||
|
||||
## Resource Sizing
|
||||
|
||||
Conversion is CPU- and memory-bound on LibreOffice. As a starting point:
|
||||
|
||||
| Workload | Suggested resources |
|
||||
| ----------------------------- | ------------------------------------ |
|
||||
| Light (a few DOCX per minute) | 1 vCPU, 1 GB RAM |
|
||||
| Moderate (sustained uploads) | 2 vCPU, 2 GB RAM |
|
||||
| Heavy / multi-tenant | Horizontally scale Gotenberg replicas behind a load balancer |
|
||||
|
||||
Gotenberg is stateless. Each container handles one or more concurrent requests independently. Scale horizontally rather than vertically once a single replica is saturated.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<Accordions type="multiple">
|
||||
<Accordion title="DOCX uploads are rejected with 'Only PDF and DOCX files are allowed'">
|
||||
The Documenso server does not see `NEXT_PRIVATE_DOCUMENT_CONVERSION_URL`. Check the value is set
|
||||
on the running container (`docker exec documenso printenv | grep DOCUMENT_CONVERSION`) and
|
||||
restart after changing it.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Uploads fail with 'Document conversion service is currently unavailable'">
|
||||
Documenso could not reach Gotenberg. Verify:
|
||||
|
||||
- The URL in `NEXT_PRIVATE_DOCUMENT_CONVERSION_URL` is resolvable from the Documenso container
|
||||
(use the Docker service name or in-cluster DNS, not `localhost`).
|
||||
- Gotenberg's `/health` endpoint returns `200`.
|
||||
- Basic auth credentials match between the two services.
|
||||
|
||||
After repeated failures, an internal circuit breaker opens for 30 seconds. Subsequent uploads
|
||||
will fail fast during that window; this is intentional and self-recovers.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Uploads fail with 'Failed to convert document to PDF'">
|
||||
Gotenberg was reachable but returned a non-2xx response. Check the Gotenberg container logs:
|
||||
|
||||
```bash
|
||||
docker compose logs -f gotenberg
|
||||
```
|
||||
|
||||
Common causes: corrupted `.docx` file, exotic embedded objects LibreOffice cannot render, or a
|
||||
file that genuinely exceeded the conversion timeout. Increase
|
||||
`NEXT_PRIVATE_DOCUMENT_CONVERSION_TIMEOUT_MS` for very large documents.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Converted PDFs look different from the Word document">
|
||||
LibreOffice is not byte-identical to Microsoft Word. Layout, font metrics, and complex elements
|
||||
(Charts, SmartArt, ActiveX controls) may differ. To improve fidelity:
|
||||
|
||||
- Use the custom Dockerfile in this guide to install Microsoft Core Fonts and additional
|
||||
language fonts.
|
||||
- Make sure any custom fonts referenced by your documents are installed in the Gotenberg image.
|
||||
- For pixel-perfect output, ask users to export to PDF from Word before uploading.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Form controls in the DOCX appear blank or missing">
|
||||
Documenso disables Gotenberg's `exportFormFields` flag during conversion. Word content controls
|
||||
(`<w:sdt>`) become static graphics in the output PDF, which prevents Documenso's later
|
||||
flattening step from making them invisible. This is intentional. Use Documenso fields
|
||||
(signature, text, date, etc.) for anything that needs to be filled in by signers.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Conversion is slow on the first request">
|
||||
LibreOffice starts lazily by default. Pass `--libreoffice-auto-start` to Gotenberg so it warms
|
||||
up at container boot. Allow up to a minute on first start before considering the service
|
||||
unhealthy.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="The circuit breaker keeps opening">
|
||||
Repeated failures open an in-process circuit breaker for 30 seconds. If you see this in
|
||||
production, the underlying problem is the Gotenberg service. Check its logs, resource usage,
|
||||
and connectivity. The breaker is per-process and resets on restart.
|
||||
</Accordion>
|
||||
</Accordions>
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Upload Documents (User Guide)](/docs/users/documents/upload) - End-user view of DOCX uploads
|
||||
- [Environment Variables](/docs/self-hosting/configuration/environment) - Full configuration reference
|
||||
- [Docker Compose Deployment](/docs/self-hosting/deployment/docker-compose) - Compose-based deployment patterns
|
||||
- [Gotenberg Documentation](https://gotenberg.dev/docs/getting-started/introduction) - Upstream Gotenberg docs
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Advanced
|
||||
description: Optional configuration for OAuth providers, AI features, and other advanced settings.
|
||||
description: Optional configuration for OAuth providers, AI features, document conversion, and other advanced settings.
|
||||
---
|
||||
|
||||
<Cards>
|
||||
@@ -14,4 +14,9 @@ description: Optional configuration for OAuth providers, AI features, and other
|
||||
description="Enable AI-powered recipient and field detection."
|
||||
href="/docs/self-hosting/configuration/advanced/ai-features"
|
||||
/>
|
||||
<Card
|
||||
title="Document Conversion"
|
||||
description="Accept DOCX uploads by running a Gotenberg sidecar that converts Word documents to PDF."
|
||||
href="/docs/self-hosting/configuration/advanced/document-conversion"
|
||||
/>
|
||||
</Cards>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"title": "Advanced",
|
||||
"pages": ["oauth-providers", "ai-features"]
|
||||
"pages": ["oauth-providers", "document-conversion", "ai-features"]
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ You can control who is allowed to create accounts on your instance with the foll
|
||||
- **`NEXT_PUBLIC_DISABLE_GOOGLE_SIGNUP`**, **`NEXT_PUBLIC_DISABLE_MICROSOFT_SIGNUP`**, **`NEXT_PUBLIC_DISABLE_OIDC_SIGNUP`**: Set to `true` to block brand-new account creation through the matching SSO provider. Existing users with the provider already linked can still sign in, and existing users can still link the provider to their account. `NEXT_PUBLIC_DISABLE_OIDC_SIGNUP` also blocks new-account creation through the organisation authentication portal.
|
||||
- **`NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS`**: Restrict signups to specific email domains. When set, only users whose email address matches one of the listed domains can create an account. Leave empty to allow all domains.
|
||||
|
||||
Sign-in for existing users is never affected — only the creation of brand-new accounts.
|
||||
Sign-in for existing users is never affected, only the creation of brand-new accounts.
|
||||
|
||||
Both the master switch and the domain allowlist apply to email/password registration and OAuth (Google, Microsoft, OIDC). If a user attempts to sign up via OAuth with a disallowed domain, they are redirected to the sign-in page with an error.
|
||||
|
||||
@@ -279,6 +279,23 @@ AI features must also be enabled in organisation/team settings after configurati
|
||||
|
||||
---
|
||||
|
||||
## Document Conversion
|
||||
|
||||
Documenso can accept `.docx` uploads by sending them to a [Gotenberg](https://gotenberg.dev) service that converts them to PDF. When `NEXT_PRIVATE_DOCUMENT_CONVERSION_URL` is unset, DOCX uploads are rejected and only PDFs are accepted.
|
||||
|
||||
| Variable | Description | Default |
|
||||
| --------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `NEXT_PRIVATE_DOCUMENT_CONVERSION_URL` | Base URL of the Gotenberg service (e.g., `http://gotenberg:3000`). Unset disables the feature. | |
|
||||
| `NEXT_PRIVATE_DOCUMENT_CONVERSION_USERNAME` | HTTP Basic auth username. Required when Gotenberg runs with `--api-enable-basic-auth`. | |
|
||||
| `NEXT_PRIVATE_DOCUMENT_CONVERSION_PASSWORD` | HTTP Basic auth password. Set together with the username. | |
|
||||
| `NEXT_PRIVATE_DOCUMENT_CONVERSION_TIMEOUT_MS` | Per-request timeout in milliseconds. Increase for very large documents. | `30000` |
|
||||
|
||||
The public flag `NEXT_PUBLIC_DOCUMENT_CONVERSION_ENABLED` is derived automatically from `NEXT_PRIVATE_DOCUMENT_CONVERSION_URL` on server start. Do not set it manually.
|
||||
|
||||
For setup, image-build instructions, and security recommendations, see [Document Conversion](/docs/self-hosting/configuration/advanced/document-conversion).
|
||||
|
||||
---
|
||||
|
||||
## Background Jobs
|
||||
|
||||
Documenso supports multiple background job providers for processing emails, documents, webhooks, and scheduled tasks.
|
||||
|
||||
@@ -11,16 +11,41 @@ import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||
|
||||
| Limitation | Value |
|
||||
| ----------------------- | ----------------------------------- |
|
||||
| Supported format | PDF only |
|
||||
| Supported formats | PDF, DOCX |
|
||||
| Maximum file size | 50MB (configurable for self-hosted) |
|
||||
| Encrypted PDFs | Not supported |
|
||||
| Password-protected PDFs | Not supported |
|
||||
| Legacy `.doc` files | Not supported (convert to DOCX) |
|
||||
|
||||
<Callout type="warn">
|
||||
Documenso does not support password-protected or encrypted PDF files. Remove encryption before
|
||||
uploading.
|
||||
</Callout>
|
||||
|
||||
## Supported Formats
|
||||
|
||||
Documenso accepts two file formats:
|
||||
|
||||
- **PDF** (`.pdf`): used as-is. **Recommended.**
|
||||
- **Word** (`.docx`): converted to PDF on the server during upload. The converted PDF is what recipients sign.
|
||||
|
||||
Other formats (`.doc`, `.odt`, `.rtf`, images) are not supported. Convert them to PDF or DOCX before uploading.
|
||||
|
||||
<Callout type="warn">
|
||||
**Upload a PDF whenever you can.** DOCX files are converted to PDF using LibreOffice, which is not
|
||||
byte-identical to Microsoft Word. Spacing, line breaks, fonts, and complex elements (tables,
|
||||
charts, headers, footers) can shift in the converted PDF. For the final document to look exactly
|
||||
the way you designed it, export to PDF from Word, Google Docs, or Pages and upload the PDF
|
||||
directly.
|
||||
</Callout>
|
||||
|
||||
<Callout type="info">
|
||||
DOCX support requires the document conversion service. It is enabled on
|
||||
[documenso.com](https://app.documenso.com). Self-hosted instances must
|
||||
[configure it](/docs/self-hosting/configuration/advanced/document-conversion) before DOCX uploads
|
||||
are accepted.
|
||||
</Callout>
|
||||
|
||||
## Upload Methods
|
||||
|
||||

|
||||
@@ -38,15 +63,15 @@ You can upload documents in two ways:
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
### Drag and drop your PDF
|
||||
### Drag and drop your file
|
||||
|
||||
Drag a PDF file from your computer and drop it anywhere on the page.
|
||||
Drag a PDF or DOCX file from your computer and drop it anywhere on the page.
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
### Wait for the upload to complete
|
||||
|
||||
The document will process and the editor will open when ready.
|
||||
The document will process and the editor will open when ready. DOCX files take a few extra seconds while they are converted to PDF.
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
@@ -70,7 +95,7 @@ You can upload documents in two ways:
|
||||
<Step>
|
||||
### Select your file
|
||||
|
||||
Choose a PDF file from your computer.
|
||||
Choose a PDF or DOCX file from your computer.
|
||||
|
||||
</Step>
|
||||
<Step>
|
||||
@@ -81,16 +106,32 @@ You can upload documents in two ways:
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## DOCX Conversion
|
||||
|
||||
We always recommend uploading a PDF rather than a DOCX. If you have the original document open in Word, Google Docs, or Pages, export to PDF from there and upload the PDF. The result is guaranteed to match what you see on screen.
|
||||
|
||||
If you do upload a `.docx` file, Documenso converts it to PDF before adding it to the envelope. The original `.docx` is discarded. Only the converted PDF is stored, signed, and downloaded.
|
||||
|
||||
Things to keep in mind when uploading DOCX:
|
||||
|
||||
- **The converted PDF will not be pixel-identical to your Word document.** Conversion uses LibreOffice, which renders most documents faithfully but differs from Microsoft Word in subtle ways. Spacing, font metrics, line breaks, and complex layout features can shift.
|
||||
- **Always review the converted PDF before adding fields or sending.** Open the document in the editor and scroll through every page to confirm it looks the way you expect.
|
||||
- **Form controls are flattened.** Word content controls (drop-downs, date pickers, checkboxes) become static text or graphics. Use Documenso fields for anything that needs to be filled in.
|
||||
- **Fonts not installed on the server fall back to substitutes.** On documenso.com, common fonts (Calibri, Arial, Times New Roman, etc.) are installed. On self-hosted instances, font fidelity depends on the operator's setup.
|
||||
- **Tracked changes and comments are preserved as they appear in Word.** Accept or reject changes and remove comments before uploading if you do not want them in the final document.
|
||||
|
||||
If the converted PDF does not match what you expect, export the document to PDF from Word, Google Docs, or another tool and upload the PDF directly.
|
||||
|
||||
## Uploading Multiple Documents
|
||||
|
||||
You can upload multiple PDF files at once to create a single envelope containing multiple documents. The number of files you can upload per envelope depends on your plan.
|
||||
You can upload multiple files at once to create a single envelope containing multiple documents. The number of files you can upload per envelope depends on your plan.
|
||||
|
||||
To upload multiple files:
|
||||
|
||||
- Select multiple PDF files when using the file picker, or
|
||||
- Drag and drop multiple PDF files at once
|
||||
- Select multiple PDF or DOCX files when using the file picker, or
|
||||
- Drag and drop multiple files at once
|
||||
|
||||
All files in the same upload become part of the same envelope and share the same recipients and signing workflow.
|
||||
You can mix PDF and DOCX files in the same upload. All files become part of the same envelope and share the same recipients and signing workflow.
|
||||
|
||||
<Callout type="info">
|
||||
If you need separate signing workflows for each document, upload them individually.
|
||||
@@ -114,15 +155,37 @@ The document remains in `Draft` status until you send it. You can close the edit
|
||||
<Accordion title="File is larger than 50MB">
|
||||
Reduce the file size before uploading:
|
||||
|
||||
- Compress images within the PDF
|
||||
- Compress images within the document
|
||||
- Remove unnecessary pages
|
||||
- Use a PDF compression tool
|
||||
- Use a PDF compression tool (for PDFs) or save with images downsampled (for DOCX)
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Only PDF files are allowed">
|
||||
Convert your document to PDF before uploading. Most applications (Word, Google Docs, etc.) can
|
||||
export to PDF format.
|
||||
<Accordion title="Only PDF and DOCX files are allowed">
|
||||
Documenso accepts PDF and DOCX. For other formats (`.doc`, `.odt`, `.rtf`, etc.), export to PDF
|
||||
from your editor (Word, Google Docs, Pages) and upload the PDF.
|
||||
|
||||
If you are self-hosted and DOCX is rejected, the [document conversion
|
||||
service](/docs/self-hosting/configuration/advanced/document-conversion) is not configured on your
|
||||
instance.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="DOCX upload fails with a conversion error">
|
||||
The document conversion service was reachable but could not convert the file. Common causes:
|
||||
|
||||
- The `.docx` file is corrupted. Open it in Word, save a new copy, and try again.
|
||||
- The file uses very unusual fonts or embedded objects that LibreOffice cannot render.
|
||||
- The file is unusually large or complex and exceeded the conversion timeout.
|
||||
|
||||
If the problem persists, export the document to PDF from Word and upload the PDF directly.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="DOCX upload fails with 'conversion service unavailable'">
|
||||
The document conversion service is down or temporarily unreachable. Try again in a minute. If you
|
||||
self-host, check the [document conversion
|
||||
service](/docs/self-hosting/configuration/advanced/document-conversion) logs.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="You cannot upload encrypted PDFs">
|
||||
|
||||
Reference in New Issue
Block a user