Applications Azure

Documenso on Ubuntu 24.04 LTS on Azure

| Product: Documenso on Ubuntu 24.04 LTS

Overview

Documenso is an open source document e signing platform, a self hosted alternative to services like DocuSign. You upload a PDF, place signature, text and date fields, invite one or more recipients by email, and collect signatures that are recorded with a full audit trail and sealed with the instance's own signing certificate. Because it runs entirely on your own infrastructure, your documents and signer data stay under your control.

The cloudimg image runs Documenso 2.15.0 as its official upstream container stack, with PostgreSQL, behind nginx on a hardened, fully patched Ubuntu 24.04 LTS base. The application is reverse proxied by nginx on port 80; the container itself is bound to the loopback interface only.

The image is deliberately shipped unprovisioned, with no database, no application secrets and no signing certificate. On the first boot of every VM a one shot service generates every secret uniquely (the authentication secret, two encryption keys, the database password and the signing certificate passphrase), generates a per VM self signed document signing certificate, runs the database migrations, and seeds a single administrator account with a strong per VM password written to a root only file. Open signup is then disabled and nothing is published on port 80 until that finishes — so no instance is ever reachable from the network in an unclaimed, unconfigured state, and no secret is ever shared between customers. Backed by 24/7 cloudimg support.

What is included:

  • Documenso 2.15.0 (the official upstream container image, pinned) with PostgreSQL 15, managed by systemd through Docker Compose
  • The Documenso web interface on :80, reverse proxied by nginx, requiring an administrator sign in
  • A per VM administrator account, application secrets and document signing certificate generated on first boot and recorded in a root only file
  • Open signup disabled by default, so only the seeded administrator can invite further users
  • A self contained PostgreSQL database, shipped empty so no build data is carried into your instance
  • docker.service and documenso.service as enabled systemd units
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point for a team; size up for heavy signing volume. NSG inbound: allow 22/tcp from your management network, and 80/tcp (plus 443/tcp once you terminate TLS on the VM) so browsers can reach Documenso.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Documenso by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create and Create.

Step 2 - Deploy from the Azure CLI

Prefer the command line? The following creates the VM from the cloudimg offer, opens ports 22 and 80, and prints the public IP.

az vm create \
  --resource-group my-rg \
  --name documenso \
  --image cloudimg:documenso-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
az vm open-port --resource-group my-rg --name documenso --port 80 --priority 900
az vm show --resource-group my-rg --name documenso --show-details --query publicIps -o tsv

First boot pulls no images (they are pre cached) but does generate secrets, run database migrations and seed the administrator, which takes about a minute. Give the VM a moment after it boots before the web interface answers.

Step 3 - Confirm the services are running

Connect over SSH with the administrator user you chose at deploy time, then confirm the stack is up and that first boot initialisation has completed.

systemctl is-active docker documenso.service
test -f /var/lib/cloudimg/documenso-firstboot.done && echo "first boot: complete"
cd /opt/documenso && sudo docker compose ps --format '{{.Service}} {{.State}}'
curl -s http://127.0.0.1/api/health | head -c 120; echo

You should see active for both units, the first boot completion line, both containers running, and a health response whose status is ok.

The docker and documenso services reporting active, both containers running, the first boot sentinel present, and the Documenso health endpoint responding

Step 4 - Retrieve this VM's administrator credentials

The administrator account was created on this VM's first boot, with a password unique to this machine. It is written to a root only file:

sudo cat /root/documenso-credentials.txt

The file lists the administrator e mail, the per VM password and the URL to sign in at. Every application secret (the authentication secret, the encryption keys, the database password and the signing certificate passphrase) is generated per VM into /opt/documenso/.env, and none of them is the placeholder that ships in the image. You can confirm the file permissions and that no placeholder secret remains without revealing the secrets:

sudo stat -c '%a %U:%G' /root/documenso-credentials.txt
sudo grep -c UNSET_FIRSTBOOT_WILL_GENERATE /opt/documenso/.env || true

The credentials file is 600 root:root, and the placeholder count is 0 — every secret was rotated to a per VM value on first boot.

The credentials file reported at mode 600 owned by root, the administrator e mail, and every application secret confirmed rotated to a per VM value with no placeholder remaining

Step 5 - Sign in to Documenso

Open http://<your-vm-public-ip>/ in a browser. Documenso presents its sign in page. Enter the e mail <DOCUMENSO_ADMIN_EMAIL> and the password <DOCUMENSO_ADMIN_PASSWORD> from the credentials file, and choose Sign In. Open signup is disabled on this image, so the only way in is the administrator account seeded on first boot.

The Documenso sign in page, protected by the administrator account generated on this VM's first boot

After signing in you land on your documents workspace, the home of the application, with the Documents and Templates areas in the navigation and an Upload Document action.

The Documenso documents workspace after signing in with the per VM administrator account

Step 6 - Prepare a document for signature

Choose Upload Document and select a PDF. Documenso opens the document editor: a three step workflow that walks you through Document & Recipients (attach documents and add the people who need to sign), Add Fields (place signature, text, date and other fields on the pages), and Preview before you send. When you are ready, Send Document delivers signing requests to your recipients by e mail and tracks each signature to completion with a full audit trail.

The Documenso document editor with an uploaded PDF, showing the signing workflow: document and recipients, add fields, and send for signature

Step 7 - Administer the instance

The seeded account is an administrator, so it can reach the Admin Panel at /admin. From there you manage users, organisations and documents, review instance statistics, and configure site wide settings. Add further users here (open signup stays disabled), and promote or manage them as needed.

The Documenso admin panel showing instance statistics, the application version, and the users, organisations and documents management areas

Step 8 - Configure SMTP so invitations and notifications are delivered

Documenso sends signing invitations, reminders and completion notices by e mail, so you must point it at a mail server you control. The image ships with placeholder SMTP settings; edit /opt/documenso/.env and set your provider's details, for example:

NEXT_PRIVATE_SMTP_TRANSPORT=smtp-auth
NEXT_PRIVATE_SMTP_HOST=smtp.your-provider.example
NEXT_PRIVATE_SMTP_PORT=587
NEXT_PRIVATE_SMTP_USERNAME=your-smtp-username
NEXT_PRIVATE_SMTP_PASSWORD=your-smtp-password
NEXT_PRIVATE_SMTP_FROM_NAME=Documenso
NEXT_PRIVATE_SMTP_FROM_ADDRESS=documents@your-domain.example

Then recreate the application container so the new settings take effect:

cd /opt/documenso && sudo docker compose up -d --force-recreate documenso

Step 9 - Set your public URL for a custom domain

Documenso protects its sign in against cross origin requests: it only accepts a sign in whose browser origin matches NEXT_PUBLIC_WEBAPP_URL. First boot sets that to the VM's public IP, so signing in at http://<your-vm-public-ip>/ works out of the box. If you put a domain name or a reverse proxy in front of the instance, update the URL to match what your browser uses in /opt/documenso/.env:

NEXT_PUBLIC_WEBAPP_URL=https://sign.your-domain.example

Then recreate the container (sudo docker compose up -d --force-recreate documenso). If sign in ever returns an error immediately after submitting the form, this value not matching your browser's address is the usual cause.

Step 10 - Verify the security posture

The image is secure by default. Confirm that the health and sign in endpoints answer and that public signup is refused:

curl -s -o /dev/null -w 'health:  HTTP %{http_code}\n' http://127.0.0.1/api/health
curl -s -o /dev/null -w 'sign-in page: HTTP %{http_code}\n' http://127.0.0.1/signin
curl -s -o /dev/null -w 'public signup: HTTP %{http_code} (expect 400 - disabled)\n' -X POST http://127.0.0.1/api/auth/email-password/signup -H 'Content-Type: application/json' --data '{"name":"x","email":"x@x.local","password":"abcdefghijklmnopqrstuvwxyz012"}'
grep NEXT_PUBLIC_DISABLE_SIGNUP /opt/documenso/.env

Health and the sign in page return 200, public signup returns 400 because it is disabled, and the environment confirms NEXT_PUBLIC_DISABLE_SIGNUP=true. No stranger can register on your instance.

The health and sign in endpoints returning 200, public signup refused with HTTP 400, and signup disabled in the environment, confirming the secure by default posture

Step 11 - Confirm first boot and ongoing patching

The one shot first boot service leaves a sentinel and enables unattended security upgrades so the OS keeps patching itself.

systemctl is-enabled documenso-firstboot.service documenso.service
systemctl is-active unattended-upgrades.service
uname -r
apt-mark showhold

Both units are enabled, unattended-upgrades is active, and apt-mark showhold prints nothing — no package is held back from security updates.

The first boot and application services enabled, unattended-upgrades active for security patching, the running kernel, and no held packages

Step 12 - Enable HTTPS with Let's Encrypt

Before collecting real signatures, terminate TLS. Point a DNS record at the VM, allow 443/tcp in the NSG, then install a certificate with certbot for your domain:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d sign.your-domain.example

Certbot obtains the certificate and rewrites the nginx vhost to serve Documenso over HTTPS with automatic renewal. Remember to set NEXT_PUBLIC_WEBAPP_URL to your https:// domain (Step 9) so sign in accepts your browser's origin.

Step 13 - Back up and maintain your VM

Documenso's state is the PostgreSQL database (which stores your documents when NEXT_PUBLIC_UPLOAD_TRANSPORT=database, the shipped default) plus the per VM environment and signing certificate. Back them up together:

cd /opt/documenso
sudo docker compose exec -T database pg_dump -U documenso documenso | gzip > <backup-dir>/documenso-db-$(date +%F).sql.gz
sudo tar czf <backup-dir>/documenso-config-$(date +%F).tgz -C /opt/documenso .env cert.p12

Keep the /root/documenso-credentials.txt file somewhere safe, and change the administrator password from your account settings after your first sign in.

Security notes

  • The image ships with no database, no application secrets and no signing certificate; all of them are generated per VM on first boot, so nothing secret is shared between customers.
  • Documenso is bound to loopback until first boot completes and the administrator exists, so an unconfigured instance is never reachable from the network on port 80.
  • Open signup is disabled by default — only the seeded administrator can add users, from the admin panel.
  • Change the administrator password after first sign in, configure SMTP so invitations are delivered, and enable HTTPS before exposing the instance.
  • Keep the VM patched. Unattended security upgrades are enabled by default.

Architecture summary

Component Detail
Application Documenso 2.15.0 (open source document e signing, AGPL-3.0)
Deployment Official upstream container stack via Docker Compose
Web server nginx reverse proxy on port 80 to the loopback bound container
Database PostgreSQL 15 (self contained container)
App directory /opt/documenso (compose, .env, signing certificate)
Admin interface http://<vm>/ (port 80; add TLS on 443), admin panel at /admin
First boot service documenso-firstboot.service (per VM secrets, certificate and administrator)
Credentials file /root/documenso-credentials.txt (mode 600, root)
Base OS Ubuntu 24.04 LTS, hardened and fully patched

Support

Every cloudimg image is backed by 24/7 support. Email support@cloudimg.co.uk with the VM name and, where relevant, the output of the commands in this guide. Documenso is open source software licensed under the GNU Affero General Public License, Version 3 (AGPL-3.0); the verbatim licence text ships in the image at /opt/documenso/LICENSE.