certificate.p12 reading process issue
Issue Description
Issued "Error: Failed to get private key bags" when using the certificate to sign documents. The sign button continuously spins indefinitely and never completes.
I'm not sure but I think its the same issue as this. : https://github.com/documenso/documenso/issues/1087
Update: Added the NEXT_PRIVATE_SIGNING_PASSPHRASE variable and the issue persists.
Steps to Reproduce
- Upload a PDF file
- Send it to the recipient A
- Recipient A completes and attempt to signs it but the sign button spins indefinitely and never completes
- Check the following error message in the Docker logs for the Documenso app container:
Error: Failed to get private key bags
docker-compose.yml file
version: '3.8'
services:
database:
image: postgres:15
environment:
- POSTGRES_USER=${POSTGRES_USER:?err}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?err}
- POSTGRES_DB=${POSTGRES_DB:?err}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
restart: always
volumes:
- database:/var/lib/postgresql/data
documenso:
image: documenso/documenso:latest
depends_on:
database:
condition: service_healthy
environment:
- PORT=${PORT:-3000}
- NEXTAUTH_URL=${NEXTAUTH_URL:-${NEXT_PUBLIC_WEBAPP_URL}}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET:?err}
- NEXT_PRIVATE_ENCRYPTION_KEY=${NEXT_PRIVATE_ENCRYPTION_KEY:?err}
- NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=${NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY:?err}
- NEXT_PRIVATE_GOOGLE_CLIENT_ID=${NEXT_PRIVATE_GOOGLE_CLIENT_ID}
- NEXT_PRIVATE_GOOGLE_CLIENT_SECRET=${NEXT_PRIVATE_GOOGLE_CLIENT_SECRET}
- NEXT_PUBLIC_WEBAPP_URL=${NEXT_PUBLIC_WEBAPP_URL:?err}
- NEXT_PUBLIC_MARKETING_URL=${NEXT_PUBLIC_MARKETING_URL:-https://documenso.com}
- NEXT_PRIVATE_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@database:5432/${POSTGRES_DB}
- NEXT_PRIVATE_DIRECT_DATABASE_URL=${NEXT_PRIVATE_DIRECT_DATABASE_URL:-postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@database:5432/${POSTGRES_DB}}
- NEXT_PUBLIC_UPLOAD_TRANSPORT=${NEXT_PUBLIC_UPLOAD_TRANSPORT:-database}
- NEXT_PRIVATE_UPLOAD_ENDPOINT=${NEXT_PRIVATE_UPLOAD_ENDPOINT}
- NEXT_PRIVATE_UPLOAD_FORCE_PATH_STYLE=${NEXT_PRIVATE_UPLOAD_FORCE_PATH_STYLE}
- NEXT_PRIVATE_UPLOAD_REGION=${NEXT_PRIVATE_UPLOAD_REGION}
- NEXT_PRIVATE_UPLOAD_BUCKET=${NEXT_PRIVATE_UPLOAD_BUCKET}
- NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID=${NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID}
- NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY=${NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY}
- NEXT_PRIVATE_SMTP_TRANSPORT=${NEXT_PRIVATE_SMTP_TRANSPORT:?err}
- NEXT_PRIVATE_SMTP_HOST=${NEXT_PRIVATE_SMTP_HOST}
- NEXT_PRIVATE_SMTP_PORT=${NEXT_PRIVATE_SMTP_PORT}
- NEXT_PRIVATE_SMTP_USERNAME=${NEXT_PRIVATE_SMTP_USERNAME}
- NEXT_PRIVATE_SMTP_PASSWORD=${NEXT_PRIVATE_SMTP_PASSWORD}
- NEXT_PRIVATE_SMTP_APIKEY_USER=${NEXT_PRIVATE_SMTP_APIKEY_USER}
- NEXT_PRIVATE_SMTP_APIKEY=${NEXT_PRIVATE_SMTP_APIKEY}
- NEXT_PRIVATE_SMTP_SECURE=${NEXT_PRIVATE_SMTP_SECURE}
- NEXT_PRIVATE_SMTP_FROM_NAME=${NEXT_PRIVATE_SMTP_FROM_NAME:?err}
- NEXT_PRIVATE_SMTP_FROM_ADDRESS=${NEXT_PRIVATE_SMTP_FROM_ADDRESS:?err}
- NEXT_PRIVATE_RESEND_API_KEY=${NEXT_PRIVATE_RESEND_API_KEY}
- NEXT_PRIVATE_MAILCHANNELS_API_KEY=${NEXT_PRIVATE_MAILCHANNELS_API_KEY}
- NEXT_PRIVATE_MAILCHANNELS_ENDPOINT=${NEXT_PRIVATE_MAILCHANNELS_ENDPOINT}
- NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN=${NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN}
- NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR=${NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR}
- NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY=${NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY}
- NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=${NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT}
- NEXT_PUBLIC_POSTHOG_KEY=${NEXT_PUBLIC_POSTHOG_KEY}
- NEXT_PUBLIC_DISABLE_SIGNUP=${NEXT_PUBLIC_DISABLE_SIGNUP}
- NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=${NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH:-/opt/documenso/cert.p12}
ports:
- ${PORT:-3000}:${PORT:-3000}
restart: always
volumes:
- ./certificate.p12:/opt/documenso/cert.p12
user: "root"
caddy:
image: caddy:latest
ports:
- "80:80"
- "443:443"
restart: always
volumes:
- caddy_data:/data
- ./caddy_config:/config
- ./caddy_config/Caddyfile:/etc/caddy/Caddyfile
volumes:
database:
caddy_data:
external: true
.env file
POSTGRES_USER="my-postgres-user"
POSTGRES_PASSWORD="my-postgres-pass"
POSTGRES_DB=documenso
PORT=8080
NEXTAUTH_URL="my-url-path"
NEXTAUTH_SECRET="my-secret"
NEXT_PRIVATE_ENCRYPTION_KEY="my-private-encryption-key"
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="my-secondary-encryption-key"
NEXT_PUBLIC_WEBAPP_URL="my-url-path"
NEXT_PUBLIC_DISABLE_SIGNUP=
NEXT_PRIVATE_SIGNING_PASSPHRASE=my-passphrase
NEXT_PRIVATE_SMTP_TRANSPORT="smtp-auth"
NEXT_PRIVATE_SMTP_HOST="<my-host>"
NEXT_PRIVATE_SMTP_PORT=<my-port>
NEXT_PRIVATE_SMTP_USERNAME="<my-username>"
NEXT_PRIVATE_SMTP_PASSWORD="<my-password>"
NEXT_PRIVATE_SMTP_FROM_NAME="<my-smtp-from-name>"
NEXT_PRIVATE_SMTP_FROM_ADDRESS="<my-smtp-from-address>"
Steps used to create the certificate.p12 file
https://github.com/documenso/documenso/blob/main/SIGNING.md
Expected Behavior
Recipient A signs the document without issue and the document being marked as signed.
Current Behavior
- Signing document steps
- Console log :
2024-05-24T10:06:25.248226950Z Error: Failed to get private key bags 2024-05-24T10:06:25.248401860Z at D (/app/apps/web/.next/server/chunks/8690.js:1:353526) 2024-05-24T10:06:25.248412583Z at async D (/app/apps/web/.next/server/chunks/8690.js:1:351623) 2024-05-24T10:06:25.248418676Z at async i (/app/apps/web/.next/server/chunks/8690.js:1:5527) 2024-05-24T10:06:25.248424797Z at async h (/app/apps/web/.next/server/pages/api/trpc/[trpc].js:1:39385) 2024-05-24T10:06:25.248430176Z at async /app/apps/web/.next/server/pages/api/trpc/[trpc].js:1:109200 2024-05-24T10:06:25.248435549Z at async resolveMiddleware (file:///app/node_modules/@trpc/server/dist/index.mjs:420:30) 2024-05-24T10:06:25.248454457Z at async callRecursive (file:///app/node_modules/@trpc/server/dist/index.mjs:456:32) 2024-05-24T10:06:25.248460568Z at async callRecursive (file:///app/node_modules/@trpc/server/dist/index.mjs:456:32) 2024-05-24T10:06:25.248466117Z at async resolve (file:///app/node_modules/@trpc/server/dist/index.mjs:486:24) 2024-05-24T10:06:25.248471477Z at async inputToProcedureCall (file:///app/node_modules/@trpc/server/dist/resolveHTTPResponse-cd1a9112.mjs:46:22) { 2024-05-24T10:06:25.248477094Z code: 'GenericFailure' 2024-05-24T10:06:25.248482380Z }
- Document's 'Recent activity' section marks the document as signed, but its status remains 'pending'.
Screenshots (optional)
Operating System [e.g., Windows 10]
Docker
Browser [e.g., Chrome, Firefox]
All
Version [e.g., 2.0.1]
1.5.4
Please check the boxes that apply to this issue report.
- [ ] I have searched the existing issues to make sure this is not a duplicate.
- [X] I have provided steps to reproduce the issue.
- [X] I have included relevant environment information.
- [X] I have included any relevant screenshots.
- [X] I understand that this is a voluntary contribution and that there is no guarantee of resolution.
- [ ] I want to work on creating a PR for this issue if approved
Thank you for opening your first issue and for being a part of the open signing revolution!
One of our team members will review it and get back to you as soon as it possible 💚
Meanwhile, please feel free to hop into our community in Discord
I encountered the same issue today, where the error "Failed to get private key bags" appeared while using the certificate to sign documents. This seems similar to your experience. After some investigation, I realized the issue was due to an unset passphrase ENV Variables.
Once I corrected the passphrase for signing, the error was resolved and the certificate could be resealed successfully. To prevent this issue in your environment, ensure the passphrase is correctly set by adding the following environment variable in your .env file:
NEXT_PRIVATE_SIGNING_PASSPHRASE=<your_passphrase>
This should help rectify the "private key bags" error you're encountering.
I encountered the same issue today, where the error "Failed to get private key bags" appeared while using the certificate to sign documents. This seems similar to your experience. After some investigation, I realized the issue was due to an unset passphrase ENV Variables.
Once I corrected the passphrase for signing, the error was resolved and the certificate could be resealed successfully. To prevent this issue in your environment, ensure the passphrase is correctly set by adding the following environment variable in your
.envfile:NEXT_PRIVATE_SIGNING_PASSPHRASE=<your_passphrase>This should help rectify the "private key bags" error you're encountering.
Hey, thanks for your help. I tried to add the "NEXT_PRIVATE_SIGNING_PASSPHRAS" variable but it persists. Do you followed this method to generate your certifiacate or another one ?:
openssl genrsa -out private.key 2048openssl req -new -x509 -key private.key -out certificate.crt -days 365openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt
Yes I followed the steps provided exactly to generate my key file.
Did you also check the permissions?
Get Outlook for iOShttps://aka.ms/o0ukef
From: Altin @.> Sent: Monday, June 3, 2024 5:00:22 PM To: documenso/documenso @.> Cc: Ting Xu @.>; Comment @.> Subject: Re: [documenso/documenso] certificate.p12 reading process issue (Issue #1171)
I encountered the same issue today, where the error "Failed to get private key bags" appeared while using the certificate to sign documents. This seems similar to your experience. After some investigation, I realized the issue was due to an unset passphrase ENV Variables.
Once I corrected the passphrase for signing, the error was resolved and the certificate could be resealed successfully. To prevent this issue in your environment, ensure the passphrase is correctly set by adding the following environment variable in your .env file:
NEXT_PRIVATE_SIGNING_PASSPHRASE=<your_passphrase>
This should help rectify the "private key bags" error you're encountering.
Hey, thanks for your help. I tried to add the "NEXT_PRIVATE_SIGNING_PASSPHRAS" variable but it persists. Do you followed this method to generate your certifiacate or another one ?:
- openssl genrsa -out private.key 2048
- openssl req -new -x509 -key private.key -out certificate.crt -days 365
- openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt
— Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdocumenso%2Fdocumenso%2Fissues%2F1171%23issuecomment-2146199242&data=05%7C02%7C%7Cc708bd5dfe7a40a19dab08dc841892a4%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638530488293554963%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=9qpK%2BcJ1261SUKRlAxeCUv1XO2PK5IRGF%2FWa65L668g%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAHEV7PZLAJYUQPUKFLK4RPTZFTRPNAVCNFSM6AAAAABIHG55LSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBWGE4TSMRUGI&data=05%7C02%7C%7Cc708bd5dfe7a40a19dab08dc841892a4%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638530488293571615%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=IlLdr1QWy0IiFgoZMscN4Pb3RxeGqHr2VIUWkCLxX50%3D&reserved=0. You are receiving this because you commented.Message ID: @.***>
Yes I followed the steps provided exactly to generate my key file. Did you also check the permissions? Get Outlook for iOShttps://aka.ms/o0ukef …
🫠 I added user: "root" and I didn't get permission issues in logs so idk from where it come from...
Yes I followed the steps provided exactly to generate my key file. Did you also check the permissions? Get Outlook for iOShttps://aka.ms/o0ukef
…
🫠 I added
user: "root"and I didn't get permission issues in logs so idk from where it come from...
Just curious, were you using Portainer? If you do, updating the environment variables via GUI won't start to affect until you redeploy it. They have a tiny line under the environment variables section.
Environment changes will not take effect until redeployment occurs manually or via webhook.
Yes I followed the steps provided exactly to generate my key file. Did you also check the permissions? Get Outlook for iOShttps://aka.ms/o0ukef
…
🫠 I added
user: "root"and I didn't get permission issues in logs so idk from where it come from...Just curious, were you using Portainer? If you do, updating the environment variables via GUI won't start to affect until you redeploy it. They have a tiny line under the environment variables section.
Environment changes will not take effect until redeployment occurs manually or via webhook.
I'm actually running Docker Compose on a virtual server (a droplet from DigitalOcean). I always do docker compose down and then docker compose up -d.
Yes I followed the steps provided exactly to generate my key file. Did you also check the permissions? Get Outlook for iOShttps://aka.ms/o0ukef
…
🫠 I added
user: "root"and I didn't get permission issues in logs so idk from where it come from...Just curious, were you using Portainer? If you do, updating the environment variables via GUI won't start to affect until you redeploy it. They have a tiny line under the environment variables section.
Environment changes will not take effect until redeployment occurs manually or via webhook.I'm actually running Docker Compose on a virtual server (a droplet from DigitalOcean). I always do
docker compose downand thendocker compose up -d.
Can you try to run this command and share the environment variables?
docker exec documenso env
Yes I followed the steps provided exactly to generate my key file. Did you also check the permissions? Get Outlook for iOShttps://aka.ms/o0ukef
…
🫠 I added
user: "root"and I didn't get permission issues in logs so idk from where it come from...Just curious, were you using Portainer? If you do, updating the environment variables via GUI won't start to affect until you redeploy it. They have a tiny line under the environment variables section.
Environment changes will not take effect until redeployment occurs manually or via webhook.I'm actually running Docker Compose on a virtual server (a droplet from DigitalOcean). I always do
docker compose downand thendocker compose up -d.Can you try to run this command and share the environment variables?
docker exec documenso env
Here we go :
documenso-production-documenso-1 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=my-hostname
NEXT_PRIVATE_SMTP_SECURE=
NEXT_PRIVATE_SMTP_TRANSPORT=smtp-auth
NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID=
NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY=
NEXT_PRIVATE_UPLOAD_ENDPOINT=
NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN=
NEXT_PRIVATE_SMTP_HOST=smtp.mail.me.com
NEXT_PRIVATE_GOOGLE_CLIENT_SECRET=
NEXT_PRIVATE_SMTP_PASSWORD=my-password
NEXT_PRIVATE_RESEND_API_KEY=
NEXT_PUBLIC_WEBAPP_URL=http://my-droplet-ip:8080
NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12
NEXT_PRIVATE_DIRECT_DATABASE_URL=postgres://me:my-password@database:5432/documenso
NEXT_PRIVATE_MAILCHANNELS_API_KEY=
NEXT_PRIVATE_GOOGLE_CLIENT_ID=
NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=
NEXT_PRIVATE_UPLOAD_BUCKET=
NEXTAUTH_URL=http://my-droplet-ip:8080
NEXT_PRIVATE_SMTP_USERNAME=my-email
PORT=8080
NEXT_PUBLIC_DISABLE_SIGNUP=
NEXT_PRIVATE_SMTP_FROM_NAME=Document
NEXT_PRIVATE_SMTP_APIKEY_USER=
NEXT_PUBLIC_MARKETING_URL=https://documenso.com
NEXT_PRIVATE_SMTP_PORT=580
NEXT_PRIVATE_SMTP_APIKEY=
NEXT_PRIVATE_MAILCHANNELS_ENDPOINT=
NEXTAUTH_SECRET=my-key
[email protected]
NEXT_PUBLIC_UPLOAD_TRANSPORT=database
NEXT_PRIVATE_UPLOAD_FORCE_PATH_STYLE=
NEXT_PRIVATE_ENCRYPTION_KEY=my-key
NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR=
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PRIVATE_UPLOAD_REGION=
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=my-key
NEXT_PRIVATE_DATABASE_URL=postgres://me:my-password@database:5432/documenso
NEXT_PRIVATE_SIGNING_PASSPHRASE=passphrase
NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY=
NODE_VERSION=18.20.2
YARN_VERSION=1.22.19
HOME=/root
I am having the same issue on Vercel. I have both NEXT_PRIVATE_SIGNING_PASSPHRASE and NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS and have the same behaviour & error message.
@ACA30, you could consider adding the -legacy option when generating the cert.p12 as a workaround. It was suggested by a user (Mega) on Discord.
So:
openssl pkcs12 -export -out legacy_certificate.p12 -inkey private.key -in certificate.crt -legacy
Then:
base64 -i legacy_certificate.p12 -o legacy_certificate.p12.base64 for NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS
Worked for me on Azure.
Good luck!
@ACA30, you could consider adding the
-legacyoption when generating the cert.p12 as a workaround. It was suggested by a user (Mega) on Discord.So:
openssl pkcs12 -export -out legacy_certificate.p12 -inkey private.key -in certificate.crt -legacyThen:
base64 -i legacy_certificate.p12 -o legacy_certificate.p12.base64forNEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTSWorked for me on Azure.
Good luck!
Did you use both NEXT_PRIVATE_SIGNING_PASSPHRASE and NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS variables?
Yes, make sure that the passphrase matches the one set during certificate creation "Choose a strong password and remember it, as you will need it to use the certificate" (Source: SIGNING.md).
@ACA30, you could consider adding the
-legacyoption when generating the cert.p12 as a workaround. It was suggested by a user (Mega) on Discord. So:openssl pkcs12 -export -out legacy_certificate.p12 -inkey private.key -in certificate.crt -legacyThen:base64 -i legacy_certificate.p12 -o legacy_certificate.p12.base64forNEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTSWorked for me on Azure. Good luck!Did you use both
NEXT_PRIVATE_SIGNING_PASSPHRASEandNEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTSvariables?
I've been following this issue and tried a few different things, the thing I was missing was the base64 file contents so thanks for this!!! Works now, using the -legacy flag
I tried the legacy-flag, but it didn't work. Deployed it via Portainer. Still doesn't work with my certificate.
Here's what worked for me.:
- Create the keys with -legacy flag as mentioned.
- Set the key owner to uid
1001on the host to match thenextjsuser of the same id that owns the process in the container by default (unimportant if importing as base64-encoded string). - Add
NEXT_PRIVATE_SIGNING_PASSPHRASEto your.envfile. - Add the same env var to the compose file. It doesn't need a value, it just needs to be declared under the documenso service node for its value to be imported from the aforementioned
.env. This is missing from the compose file pasted at the top of this issue.
I had this issues too, already exported the Base64 & .p12 key using -legacy but still encounter the private key bags error.
I dont know how to put the NEXT_PRIVATE_SIGNING_PASSPHRASE and the NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS correctly.
Here my environenment in my lab: Docker Image File: documenso/documenso:sha256:f5a5773e48e0284981ee14adc6cd33428748fba29b80445f4fe7ea8f916c51fe
compose.yml
name: documenso-production
services:
database:
container_name: postgres-documenso
hostname: postgres-documenso
image: postgres:15
networks:
- cf-tunnel
environment:
- POSTGRES_USER=${POSTGRES_USER:?err}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?err}
- POSTGRES_DB=${POSTGRES_DB:?err}
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER}']
interval: 10s
timeout: 5s
retries: 5
volumes:
- database:/var/lib/postgresql/data
documenso:
image: documenso/documenso:latest
networks:
- cf-tunnel
depends_on:
database:
condition: service_healthy
environment:
- PORT=${PORT:-3000}
- NEXTAUTH_URL=${NEXTAUTH_URL:-${NEXT_PUBLIC_WEBAPP_URL}}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET:?err}
- NEXT_PRIVATE_ENCRYPTION_KEY=${NEXT_PRIVATE_ENCRYPTION_KEY:?err}
- NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=${NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY:?err}
- NEXT_PRIVATE_GOOGLE_CLIENT_ID=${NEXT_PRIVATE_GOOGLE_CLIENT_ID}
- NEXT_PRIVATE_GOOGLE_CLIENT_SECRET=${NEXT_PRIVATE_GOOGLE_CLIENT_SECRET}
- NEXT_PUBLIC_WEBAPP_URL=${NEXT_PUBLIC_WEBAPP_URL:?err}
- NEXT_PUBLIC_MARKETING_URL=${NEXT_PUBLIC_MARKETING_URL:-https://documenso.com}
- NEXT_PRIVATE_DATABASE_URL=${NEXT_PRIVATE_DATABASE_URL:?err}
- NEXT_PRIVATE_DIRECT_DATABASE_URL=${NEXT_PRIVATE_DIRECT_DATABASE_URL:-${NEXT_PRIVATE_DATABASE_URL}}
- NEXT_PUBLIC_UPLOAD_TRANSPORT=${NEXT_PUBLIC_UPLOAD_TRANSPORT:-database}
- NEXT_PRIVATE_UPLOAD_ENDPOINT=${NEXT_PRIVATE_UPLOAD_ENDPOINT}
- NEXT_PRIVATE_UPLOAD_FORCE_PATH_STYLE=${NEXT_PRIVATE_UPLOAD_FORCE_PATH_STYLE}
- NEXT_PRIVATE_UPLOAD_REGION=${NEXT_PRIVATE_UPLOAD_REGION}
- NEXT_PRIVATE_UPLOAD_BUCKET=${NEXT_PRIVATE_UPLOAD_BUCKET}
- NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID=${NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID}
- NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY=${NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY}
- NEXT_PRIVATE_SMTP_TRANSPORT=${NEXT_PRIVATE_SMTP_TRANSPORT:?err}
- NEXT_PRIVATE_SMTP_HOST=${NEXT_PRIVATE_SMTP_HOST}
- NEXT_PRIVATE_SMTP_PORT=${NEXT_PRIVATE_SMTP_PORT}
- NEXT_PRIVATE_SMTP_USERNAME=${NEXT_PRIVATE_SMTP_USERNAME}
- NEXT_PRIVATE_SMTP_PASSWORD=${NEXT_PRIVATE_SMTP_PASSWORD}
- NEXT_PRIVATE_SMTP_APIKEY_USER=${NEXT_PRIVATE_SMTP_APIKEY_USER}
- NEXT_PRIVATE_SMTP_APIKEY=${NEXT_PRIVATE_SMTP_APIKEY}
- NEXT_PRIVATE_SMTP_SECURE=${NEXT_PRIVATE_SMTP_SECURE}
- NEXT_PRIVATE_SMTP_FROM_NAME=${NEXT_PRIVATE_SMTP_FROM_NAME:?err}
- NEXT_PRIVATE_SMTP_FROM_ADDRESS=${NEXT_PRIVATE_SMTP_FROM_ADDRESS:?err}
- NEXT_PRIVATE_RESEND_API_KEY=${NEXT_PRIVATE_RESEND_API_KEY}
- NEXT_PRIVATE_MAILCHANNELS_API_KEY=${NEXT_PRIVATE_MAILCHANNELS_API_KEY}
- NEXT_PRIVATE_MAILCHANNELS_ENDPOINT=${NEXT_PRIVATE_MAILCHANNELS_ENDPOINT}
- NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN=${NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN}
- NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR=${NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR}
- NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY=${NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY}
- NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=${NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT}
- NEXT_PUBLIC_POSTHOG_KEY=${NEXT_PUBLIC_POSTHOG_KEY}
- NEXT_PUBLIC_DISABLE_SIGNUP=${NEXT_PUBLIC_DISABLE_SIGNUP}
- NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=${NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH:-/opt/documenso/cert.p12}
ports:
- ${PORT:-7734}:${PORT:-3000}
volumes:
- ./:/opt/documenso/
user: "root"
volumes:
database:
networks:
cf-tunnel:
name: cf-tunnel
external: true
POSTGRES_USER=test
POSTGRES_PASSWORD=test
POSTGRES_DB=documenso
NEXTAUTH_SECRET="uBDJ1E7k95BGG/2Nj5oF9Q4zqub0LvJXPQilP28JHN+vzUALVXHA5+8oUanN+Xp9"
NEXT_PRIVATE_ENCRYPTION_KEY="M2BU+j9U4moRroG0NkZ+WK9Mo7vw56EkQNfJ/j2Xm2bPn450GN+DZSx8vk88rmSl"
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="ghzUojHjEnEPSaDUjFi7lGJcI7CMw6oK6BAH6j5KwN0q5x0Zg2bNXHOkdjC6e7Mw"
NEXT_PRIVATE_DATABASE_URL="postgres://test:test@postgres-documenso:5432/documenso"
NEXT_PRIVATE_DIRECT_DATABASE_URL="postgres://test:test@postgres-documenso:5432/documenso"
NEXT_PUBLIC_WEBAPP_URL="https://documenso.local"
NEXT_PRIVATE_SMTP_TRANSPORT="smtp-auth"
NEXT_PRIVATE_SMTP_HOST=inbucket
NEXT_PRIVATE_SMTP_PORT=2500
NEXT_PRIVATE_SMTP_USERNAME=test
NEXT_PRIVATE_SMTP_PASSWORD=test
NEXT_PRIVATE_SMTP_FROM_NAME="test"
NEXT_PRIVATE_SMTP_FROM_ADDRESS="[email protected]"
NEXT_PRIVATE_SIGNING_PASSPHRASE=test
NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS=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
Here's what worked for me.:
- Create the keys with -legacy flag as mentioned.
- Set the key owner to uid
1001on the host to match thenextjsuser of the same id that owns the process in the container by default (unimportant if importing as base64-encoded string).- Add
NEXT_PRIVATE_SIGNING_PASSPHRASEto your.envfile.- Add the same env var to the compose file. It doesn't need a value, it just needs to be declared under the documenso service node for its value to be imported from the aforementioned
.env. This is missing from the compose file pasted at the top of this issue.
Thank you for this! This is the only way it works. Documentation should be updated.
Hi, I create a new certificate with NEXT_PRIVATE_SIGNING_PASSPHRASE and the problem is solved. Thanks a lot
Here's what worked for me.:
- Create the keys with -legacy flag as mentioned.
- Set the key owner to uid
1001on the host to match thenextjsuser of the same id that owns the process in the container by default (unimportant if importing as base64-encoded string).- Add
NEXT_PRIVATE_SIGNING_PASSPHRASEto your.envfile.- Add the same env var to the compose file. It doesn't need a value, it just needs to be declared under the documenso service node for its value to be imported from the aforementioned
.env. This is missing from the compose file pasted at the top of this issue.
can confirm this works flawlessly. Thank you
Thanks everyone for finding the solution, the docs have been updated and the Docker compose file has been updated to support NEXT_PRIVATE_SIGNING_PASSPHRASE
If you still find the documentation lacking please feel free to update it.
Edit: Please note that the NEXT_PRIVATE_SIGNING_PASSPHRASE env change will be released in the next RC.
So if you are v1.7.2 RC4 and below you will still need to manually add it in the meantime.
If anyone is using Dokploy, here's a compose set up that should help you...
Docker Compose file for Documenso with self-generating certificate
services:
cert-generator:
image: alpine
volumes:
- certs-data-v5:/certs
environment:
- CERT_FILENAME=cert.p12
- CERT_PASSWORD=${DOCUMENSO_P12_PASSWORD:?err_provide_DOCUMENSO_P12_PASSWORD}
- CERT_CN=${DOCUMENSO_HOST:-documenso.local}
command: >
sh -c "
set -e
CERT_FILE_PATH=\"/certs/$${CERT_FILENAME}\"
KEY_FILE_PATH=\"/certs/temp_private.key\"
CRT_FILE_PATH=\"/certs/temp_certificate.crt\"
if [ ! -f \"$${CERT_FILE_PATH}\" ]; then
echo \"Certificate $${CERT_FILE_PATH} not found in volume certs-data-v4. Generating...\"
apk add --no-cache openssl
openssl genrsa -out \"$${KEY_FILE_PATH}\" 2048
openssl req -new -x509 -nodes -batch -key \"$${KEY_FILE_PATH}\" -out \"$${CRT_FILE_PATH}\" -days 3650 -subj \"/CN=$${CERT_CN}\"
openssl pkcs12 -export -provider legacy -provider default -out \"$${CERT_FILE_PATH}\" -inkey \"$${KEY_FILE_PATH}\" -in \"$${CRT_FILE_PATH}\" -passout pass:$${CERT_PASSWORD} -legacy
rm \"$${KEY_FILE_PATH}\" \"$${CRT_FILE_PATH}\"
chmod 644 \"$${CERT_FILE_PATH}\"
echo \"Testing generated legacy P12 file readability (with legacy provider)...\"
openssl pkcs12 -info -provider legacy -provider default -in \"$${CERT_FILE_PATH}\" -noout -passin pass:$${CERT_PASSWORD}
echo \"P12 read test successful.\"
echo \"Certificate generated successfully (using -legacy): $${CERT_FILE_PATH}\"
echo \"Set permissions to 644 for $${CERT_FILE_PATH}\"
else
if [ \"$(stat -c '%a' $${CERT_FILE_PATH})\" != \"644\" ]; then
echo \"Correcting permissions for existing file $${CERT_FILE_PATH} to 644.\"
chmod 644 \"$${CERT_FILE_PATH}\"
else
echo \"Certificate $${CERT_FILE_PATH} already exists in volume certs-data-v4 with correct permissions (644).\"
fi
# Optional: Add test for existing file too if needed
# echo \"Testing existing P12 file readability (with legacy provider)...\"
# openssl pkcs12 -info -provider legacy -provider default -in \"$${CERT_FILE_PATH}\" -noout -passin pass:$${CERT_PASSWORD} || echo 'WARN: Failed reading existing P12'
# echo \"Existing P12 test complete.\"
fi
"
documenso:
image: documenso/documenso:231f51bd1fced63244f7982e0384b1aeea6cb5b6
depends_on:
cert-generator:
condition: service_completed_successfully
environment:
- NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12
- NEXT_PRIVATE_SIGNING_PASSPHRASE=${DOCUMENSO_P12_PASSWORD}
- NEXT_PRIVATE_SIGNING_TRANSPORT=${NEXT_PRIVATE_SIGNING_TRANSPORT:-local}
- PORT=${DOCUMENSO_PORT}
- NEXTAUTH_URL=https://${DOCUMENSO_HOST}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- NEXT_PRIVATE_ENCRYPTION_KEY=${NEXT_PRIVATE_ENCRYPTION_KEY}
- NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=${NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY}
- NEXT_PUBLIC_WEBAPP_URL=https://${DOCUMENSO_HOST}
- NEXT_PRIVATE_DATABASE_URL=
- NEXT_PRIVATE_DIRECT_DATABASE_URL=
- NEXT_PUBLIC_UPLOAD_TRANSPORT=database
- NEXT_PRIVATE_SMTP_TRANSPORT=smtp-auth
- NEXT_PRIVATE_SMTP_HOST=${NEXT_PRIVATE_SMTP_HOST}
- NEXT_PRIVATE_SMTP_PORT=${NEXT_PRIVATE_SMTP_PORT}
- NEXT_PRIVATE_SMTP_USERNAME=${NEXT_PRIVATE_SMTP_USERNAME}
- NEXT_PRIVATE_SMTP_PASSWORD=${NEXT_PRIVATE_SMTP_PASSWORD}
- NEXT_PRIVATE_SMTP_SECURE=${NEXT_PRIVATE_SMTP_SECURE}
- NEXT_PRIVATE_SMTP_FROM_NAME=${NEXT_PRIVATE_SMTP_FROM_NAME:?err}
- NEXT_PRIVATE_SMTP_FROM_ADDRESS=${NEXT_PRIVATE_SMTP_FROM_ADDRESS:?err}
- NEXT_PRIVATE_INTERNAL_WEBAPP_URL=${NEXT_PRIVATE_INTERNAL_WEBAPP_URL}
- NEXT_PUBLIC_DISABLE_SIGNUP=${NEXT_PUBLIC_DISABLE_SIGNUP}
- NEXT_PRIVATE_JOBS_PROVIDER=${NEXT_PRIVATE_JOBS_PROVIDER}
ports:
- ${DOCUMENSO_PORT}
volumes:
- certs-data-v5:/opt/documenso:ro
command: >
sh -c "
echo '--- Running verification command inside documenso container ---'
echo 'User ID:'
id
echo 'Checking certificate file:'
ls -l /opt/documenso/cert.p12
echo 'Attempting to read first few bytes:'
head -c 100 /opt/documenso/cert.p12
echo
echo '--- Verification complete, proceeding with default command ---'
exec node /app/apps/remix/build/server/main.js
"
volumes:
certs-data-v5:
Hey guys, I just wanted to share a solution using a mounted p12 certificate on Windows system
This is my volumen mapped in docker compose - ./volumes/documenso/certificate.p12:/opt/documenso/cert.p12
I generated the p12 file from the container after runing docker compose up and I copied it inside ./volumes folder in windows directory system, you know what I mean, but I got the error of the step 4, I tried to grant permissions to this file using windows powershell using the command icacls .\volumes\documenso\certificate.p12 /grant *S-1-1-0:R with administrator permissions, I hope this comment can be useful in the future
If you're here searching for a solution to the problem, and your operating system is Windows, please use WSL (Windows Subsystem for Linux) when
- Generating the
certificate.p12file, - When changing the file owner of the certificate.p12 to
1001 - And when running the
docker-compose upcommand.
Using WSL will help you avoid many issues.
Just to add what worked for me:
- legacy option
- changing ownership to 1001 & chmod to 644
Also, adding headless browser with NEXT_PRIVATE_BROWSERLESS_URL has resolved all issues, works like a charm with a trusted eiDAS certificate (not self-generated).