DocuSeal - Open Source Online Document Signing Platform

Introduction⌗
While browsing Daily.dev earlier, I discovered an interesting project called DocuSeal. This project is developed with a Ruby backend, open-sourced on Github, and supports self-hosting.
Later, due to business needs, I considered using this solution as a foundation to integrate with existing business processes, creating contract signing services for users through APIs!
Next, I’ll share some experiences about service deployment, integration, and challenges encountered.
Deployment⌗
The official documentation provides concise and intuitive instructions. Here I mainly use Docker Compose for deployment:
curl https://raw.githubusercontent.com/docusealco/docuseal/master/docker-compose.yml > docker-compose.yml
The official docker-compose.yaml content is as follows:
version: '3'
services:
app:
depends_on:
postgres:
condition: service_healthy
image: docuseal/docuseal:latest
ports:
- 3000:3000
volumes:
- .:/data
environment:
- FORCE_SSL=${HOST}
- DATABASE_URL=postgresql://postgres:postgres@postgres:5432/docuseal
postgres:
image: postgres:15
volumes:
- './pg_data:/var/lib/postgresql/data'
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: docuseal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
caddy:
image: caddy:latest
command: caddy reverse-proxy --from $HOST --to app:3000
ports:
- 80:80
- 443:443
- 443:443/udp
volumes:
- .:/data
environment:
- HOST=${HOST}
If you don’t plan to assign a domain name to the service and only use it for local development, you can delete the caddy container and remove the FORCE_SSL environment variable from the app container!
docker compose up -d
After startup, you can access DocuSeal through http://localhost:3000!
Setup⌗
Creating a template:
API Calls⌗
For calling methods, refer to the official API documentation. The main API used here is Create a submission
:
curl --location 'https://app.docuseal.orb.local/api/submissions' \
--header 'X-Auth-Token: cfKXy7c6PyciBqrZJsAiAEiCxXqMMfidEkvzTzkhZEH' \
--header 'Content-Type: application/json' \
--data-raw '{
"template_id": 1,
"send_email": true,
"submitters": [
{
"name": "Betterde Inc.",
"role": "Party A",
"email": "[email protected]",
"fields": [
{
"name": "Company Name",
"default_value": "Betterde Inc."
},
{
"name": "Representative",
"default_value": "George"
},
{
"name": "Contact Phone",
"default_value": "021-3828272"
}
]
}
]
}'
After successful creation, if the SMTP configuration is correct, Party A should receive an email. If they don’t receive it, you can also copy the link from the backend and send it privately!
After the end user completes the signing, the following content will be displayed:
Challenges Encountered⌗
Due to font issues, the content entered by signers cannot include Chinese characters, otherwise it will cause the backend to fail when creating PDFs, which prevents users from downloading the signed content!
Currently, my solution is to integrate Chinese fonts in the Dockerfile:
FROM ruby:3.2.2-alpine3.18 as fonts
WORKDIR /fonts
COPY PingFang-zh-CN.ttf /fonts
COPY PingFang-zh-TW.ttf /fonts
RUN apk --no-cache add fontforge wget ttf-liberation && cp /usr/share/fonts/liberation/LiberationSans-Regular.ttf /usr/share/fonts/liberation/LiberationSans-Bold.ttf . && wget https://cdn.jsdelivr.net/gh/notofonts/notofonts.github.io/fonts/NotoSansArabic/hinted/ttf/NotoSansArabic-Regular.ttf && wget https://github.com/impallari/DancingScript/raw/master/fonts/DancingScript-Regular.otf && wget https://github.com/impallari/DancingScript/raw/master/OFL.txt
RUN fontforge -lang=py -c 'font1 = fontforge.open("LiberationSans-Regular.ttf"); font2 = fontforge.open("NotoSansArabic-Regular.ttf"); font3 = fontforge.open("PingFang-zh-CN.ttf"); font4 = fontforge.open("PingFang-zh-TW.ttf"); font1.mergeFonts(font2); font1.mergeFonts(font3); font1.mergeFonts(font4); font1.generate("LiberationSans-Regular.ttf")'
Then build your own Docker Image!
I hope this is helpful, Happy hacking…