Files
ProxmoxVE/install/docuseal-install.sh
T
Claude 39a27cb427 docuseal: use DocuSeal's patched PDFium build to fix service start
DocuSeal switched to its own PDFium fork (upstream commit "adjust pdfium",
2026-08-15) and now attaches functions that only exist in that build, e.g.
FPDFPage_GetAnnotCountRaw from the added fpdf_annots_raw.h. The generic
bblanchon/pdfium-binaries library the script installed does not export them,
so lib/pdfium.rb raises FFI::NotFoundError while Rails eager-loads and both
docuseal.service and docuseal-sidekiq.service fail to start:

  Unable to load application: FFI::NotFoundError: Function
  'FPDFPage_GetAnnotCountRaw' not found in [libpdfium.so]

Install the library from docusealco/pdfium-binaries instead, matching the
upstream Dockerfile. It is only published as a musl build (DocuSeal's image is
Alpine based), so the musl runtime is installed and its library directory is
added to the loader search path - the shared object needs "libc.so" (musl) at
dlopen time. Verified on glibc: the library loads, resolves the raw annotation
functions and renders pages correctly.

The update path now refreshes PDFium too, so existing containers are repaired
by running "update" even when DocuSeal itself is already up to date.
2026-08-21 19:29:50 +00:00

175 lines
5.4 KiB
Bash

#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.docuseal.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
git \
libpq-dev \
libssl-dev \
libyaml-dev \
libreadline-dev \
zlib1g-dev \
libffi-dev \
libleptonica-dev \
libleptonica6 \
libvips42 \
libvips-dev \
libheif1 \
redis-server \
fontconfig \
musl
msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
PG_VERSION="17" setup_postgresql
PG_DB_NAME="docuseal" PG_DB_USER="docuseal" setup_postgresql_db
msg_info "Downloading Fonts"
mkdir -p /opt/fonts /usr/share/fonts/noto
curl -fsSL -o /opt/fonts/GoNotoKurrent-Regular.ttf \
https://github.com/satbyy/go-noto-universal/releases/download/v7.0/GoNotoKurrent-Regular.ttf
curl -fsSL -o /opt/fonts/GoNotoKurrent-Bold.ttf \
https://github.com/satbyy/go-noto-universal/releases/download/v7.0/GoNotoKurrent-Bold.ttf
curl -fsSL -o /opt/fonts/DancingScript-Regular.otf \
https://github.com/impallari/DancingScript/raw/master/fonts/DancingScript-Regular.otf
ln -sf /opt/fonts/GoNotoKurrent-Regular.ttf /usr/share/fonts/noto/
ln -sf /opt/fonts/GoNotoKurrent-Bold.ttf /usr/share/fonts/noto/
$STD fc-cache -f
msg_ok "Downloaded Fonts"
# DocuSeal calls PDFium functions that only exist in its own patched build
# (FPDFPage_GetAnnotCountRaw & co.), so the upstream binaries are used. They are
# only published as musl builds, which need the musl runtime to be loadable.
fetch_and_deploy_gh_release "pdfium" "docusealco/pdfium-binaries" "prebuild" "latest" "/opt/pdfium" "pdfium-musl-$(uname -m).zip"
msg_info "Installing PDFium"
install -m 644 /opt/pdfium/lib/libpdfium.so /usr/lib/libpdfium.so
echo "/usr/lib/$(uname -m)-linux-musl" >/etc/ld.so.conf.d/musl.conf
$STD ldconfig
msg_ok "Installed PDFium"
fetch_and_deploy_gh_release "docuseal" "docusealco/docuseal" "tarball"
RUBY_VERSION=$(grep -m1 '^ruby ' /opt/docuseal/Gemfile | grep -oP '[0-9]+\.[0-9]+\.[0-9]+')
RUBY_VERSION="${RUBY_VERSION}" RUBY_INSTALL_RAILS="false" HOME=/root setup_ruby
msg_info "Downloading Field Detection Model"
mkdir -p /opt/docuseal/tmp
curl -fsSL -o /opt/docuseal/tmp/model.onnx \
"https://github.com/docusealco/fields-detection/releases/download/2.0.0/model_704_int8.onnx"
mkdir -p /opt/docuseal/public/fonts
ln -sf /opt/fonts/DancingScript-Regular.otf /opt/docuseal/public/fonts/DancingScript-Regular.otf
msg_ok "Downloaded Field Detection Model"
msg_info "Configuring DocuSeal"
SECRET_KEY=$(openssl rand -hex 64)
mkdir -p /opt/docuseal/data
cat <<EOF >/opt/docuseal/.env
RAILS_ENV=production
NODE_ENV=production
RAILS_LOG_TO_STDOUT=true
RAILS_SERVE_STATIC_FILES=true
SECRET_KEY_BASE=${SECRET_KEY}
DATABASE_URL=postgresql://docuseal:${PG_DB_PASS}@127.0.0.1:5432/docuseal
REDIS_URL=redis://localhost:6379/0
WORKDIR=/opt/docuseal/data
VIPS_MAX_COORD=17000
EOF
msg_ok "Configured DocuSeal"
msg_info "Building Application"
cd /opt/docuseal
export PATH="/root/.rbenv/bin:/root/.rbenv/shims:${PATH}"
eval "$(rbenv init - bash)" 2>/dev/null || true
export RAILS_ENV=production
export NODE_ENV=production
export SECRET_KEY_BASE_DUMMY=1
set -a
source /opt/docuseal/.env
set +a
$STD bundle config set --local deployment 'true'
$STD bundle config set --local without 'development:test'
$STD bundle install -j"$(nproc)"
$STD yarn install --network-timeout 1000000
$STD ./bin/shakapacker
$STD bundle exec rails db:migrate
$STD bundle exec bootsnap precompile -j 1 --gemfile app/ lib/
msg_ok "Built Application"
msg_info "Enabling Redis"
systemctl enable -q --now redis-server
msg_ok "Enabled Redis"
msg_info "Creating docuseal User"
id docuseal &>/dev/null || useradd -u 2000 -M -s /usr/sbin/nologin -d /opt/docuseal docuseal
chmod o+x /root
chmod -R o+rX /root/.rbenv
chown -R docuseal:docuseal /opt/docuseal /opt/fonts
msg_ok "Created docuseal User"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/docuseal.service
[Unit]
Description=DocuSeal Web
After=network.target postgresql.service redis-server.service
[Service]
Type=simple
User=docuseal
Group=docuseal
WorkingDirectory=/opt/docuseal
EnvironmentFile=/opt/docuseal/.env
Environment=HOME=/opt/docuseal
Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Environment=BUNDLE_GEMFILE=/opt/docuseal/Gemfile
Environment=BUNDLE_WITHOUT=development:test
ExecStart=/opt/docuseal/bin/bundle exec puma -C /opt/docuseal/config/puma.rb --dir /opt/docuseal -p 3000
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/docuseal-sidekiq.service
[Unit]
Description=DocuSeal Sidekiq
After=network.target postgresql.service redis-server.service
[Service]
Type=simple
User=docuseal
Group=docuseal
WorkingDirectory=/opt/docuseal
EnvironmentFile=/opt/docuseal/.env
Environment=HOME=/opt/docuseal
Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Environment=BUNDLE_GEMFILE=/opt/docuseal/Gemfile
Environment=BUNDLE_WITHOUT=development:test
ExecStart=/opt/docuseal/bin/bundle exec sidekiq
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now docuseal docuseal-sidekiq
msg_ok "Created Services"
motd_ssh
customize
cleanup_lxc