Deploying on cPanel
Deploying AutoDoc on cPanel
This guide describes deploying AutoDoc on a cPanel server using the Setup Python App feature and Phusion Passenger, plus the portable LibreOffice install required for real page counting and preview/generation.
Prerequisites
- Python 3.11 or later
- cPanel with Setup Python App
- Git installed on the server
- SSH access enabled
- GitHub SSH authentication configured
Repository Location
Clone outside the web root, e.g. /home/<cpanel-user>/autodoc. Do not place it inside public_html.
Python Application
Create a Python application in cPanel:
- Application Root:
autodoc - Startup File:
passenger_wsgi.py - Entry Point:
application
Dependencies
Includes both pyproject.toml and requirements.txt. Click Ensure Dependencies in cPanel after every git pull that touches either file — several features (python-docx, pypdf, python-multipart, markdown) were added incrementally, and a missed "Ensure Dependencies" step is a common cause of a generic 500 error after deploying a new feature.
Passenger Startup File
import os
import sys
from a2wsgi import ASGIMiddleware
BASE_DIR = os.path.dirname(__file__)
SRC_DIR = os.path.join(BASE_DIR, "src")
if SRC_DIR not in sys.path:
sys.path.insert(0, SRC_DIR)
from autodoc.app import app
application = ASGIMiddleware(app)
Environment variables (.env)
Beyond the standard DATABASE_URL/SECRET_KEY/APPLICATION_NAME, AutoDoc needs:
LIBREOFFICE_PATH=/home/<cpanel-user>/opt/libreoffice/opt/libreoffice24.8/program/soffice
ENABLE_PROJECT_GENERATOR should be left unset — AutoDoc is a leaf application, not a project-generator template; that feature is intentionally disabled here.
Installing LibreOffice (portable, no root)
Shared cPanel hosting has no root access, so a normal package-manager install isn't possible. LibreOffice's official tarballs can be extracted directly into the account's own home directory instead — no system-wide changes, isolated entirely to this account, trivially removable.
Check the server's glibc version first — this determines which LibreOffice release will actually run:
ldd --version | head -1
This server has glibc 2.28. The current LibreOffice release (26.x at time of writing) requires a newer glibc than that and fails at runtime with GLIBC_2.3x not found errors. LibreOffice 24.8.7.2 was confirmed to work on this server — if glibc is upgraded later, a newer LibreOffice release could be tried again (check https://download.documentfoundation.org/libreoffice/stable/ for current releases, or the old/ archive for earlier ones if the current release needs a newer glibc).
# Download and extract the bundle
mkdir -p ~/opt/libreoffice_src ~/opt/libreoffice
cd ~/opt/libreoffice_src
wget https://downloadarchive.documentfoundation.org/libreoffice/old/24.8.7.2/rpm/x86_64/LibreOffice_24.8.7.2_Linux_x86-64_rpm.tar.gz
tar xzf LibreOffice_24.8.7.2_Linux_x86-64_rpm.tar.gz
# Extract every .rpm inside into ~/opt/libreoffice WITHOUT installing them
# (rpm2cpio/cpio are standard tools on any RPM-based Linux, no root needed)
cd ~/opt/libreoffice_src/LibreOffice_24.8.7.2_Linux_x86-64_rpm/RPMS
for f in *.rpm; do rpm2cpio "$f" | (cd ~/opt/libreoffice && cpio -idm); done
# Find the soffice binary
find ~/opt/libreoffice -name soffice -type f
# -> /home/<cpanel-user>/opt/libreoffice/opt/libreoffice24.8/program/soffice
# Clean up the download/extraction leftovers (only ~/opt/libreoffice itself is needed)
rm -rf ~/opt/libreoffice_src
Test it directly before wiring it into the app:
echo "test" > /tmp/lo_test.txt
~/opt/libreoffice/opt/libreoffice24.8/program/soffice --headless --convert-to pdf --outdir /tmp -env:UserInstallation=file:///tmp/lo_profile /tmp/lo_test.txt
ls -la /tmp/lo_test.pdf # should exist
rm -f /tmp/lo_test.txt /tmp/lo_test.pdf
rm -rf /tmp/lo_profile
If this fails with a GLIBC_2.3x not found error, the chosen LibreOffice version is too new for this server — try an older release from the old/ archive.
Finally, add the path to .env (see above) and restart the app. The install is ~696MB.
Deployment Workflow
- Commit and push locally.
- SSH into the server,
cd ~/autodoc && git pull origin main. - Click Ensure Dependencies in cPanel if
requirements.txt/pyproject.tomlchanged. - Restart:
touch tmp/restart.txt. - Verify — check
/health, and if the change touched documents, actually upload a test.docxand confirm the response.
A recurring gotcha: NOT NULL columns need a manual step
The app auto-migrates nullable columns on every startup (sync_missing_columns() in database/config.py), but a NOT NULL column added to an existing model will not be added automatically to a table that already exists — the safe path is to DROP TABLE <table> (only when it holds no real data yet) and let it recreate on the next restart:
mysql -u indiapri_autodoc_user -p indiapri_autodoc -e "DROP TABLE IF EXISTS <table>;"
touch tmp/restart.txt
This has come up twice already (documents.values/page_count, then app_settings.min_font_size_pt) — if a deploy causes a generic 500 error right after adding a new required model field, this is the first thing to check.
Project Layout
/home/<cpanel-user>/
├── autodoc/
│ ├── passenger_wsgi.py
│ ├── requirements.txt
│ ├── pyproject.toml
│ ├── src/autodoc/
│ └── var/uploads/ # uploaded .docx templates, git-ignored
└── opt/
└── libreoffice/ # portable LibreOffice install, git-ignored, ~696MB