Deployment guide

OpenDocMan

Overview

OpenDocMan is a free and open source, web-based document management system. It gives an organisation one controlled place to keep documents. Users check a file out before editing it and check it back in as a new revision, so two people cannot quietly overwrite one another and the revision history stays intact.

This SecureAnyCloud image serves OpenDocMan 2.6.0 with nginx and PHP 8.3 FPM on a hardened Ubuntu 24.04 LTS base, patched at build time. It includes a local MariaDB server, so the appliance is complete on its own.

There is no installer to reach. OpenDocMan's web installer has no already-installed lock, so a reachable installer would let a stranger rewrite the database configuration or drop every table. On this image, the installation was completed at build time over the loopback interface. The installer was then removed from the image entirely and its routes are blocked at the web server. nginx does not bind port 80 until the per-VM first boot has created your credentials.

What you get:

  • OpenDocMan 2.6.0 served by nginx and PHP 8.3 FPM, managed by systemd
  • Per-department and per-user access, with read, write, administer and view rights applied file by file, and an optional review step that holds a new or updated document until an administrator approves it
  • A bundled MariaDB 10.11 server holding the OpenDocMan database, with the schema already created
  • A unique administrator password and a unique database password generated on the first boot of every VM and written to a root-only file
  • No shipped default login: upstream's published admin credential is rotated away, and no known or blank credential authenticates
  • The installer removed from the image and every installer route blocked in nginx
  • nginx held shut until first boot completes, so the appliance never serves a request before your credentials exist
  • The document repository at /var/www/document_repository, outside the web root, so an uploaded file is never directly fetchable
  • MariaDB bound to 127.0.0.1 only (port 3306), never exposed to the network
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • nginx.service, php8.3-fpm.service and mariadb.service as enabled systemd units
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting size. Choose a larger size for bigger repositories or heavier content indexing.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the application. OpenDocMan serves plain HTTP on port 80, so for production terminate TLS in front of it with your own domain. The bundled MariaDB listens on 127.0.0.1 only, so port 3306 stays off the network.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for OpenDocMan by SecureAnyCloud, and select Create.

On the Basics tab, 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).

Select Review + create, then Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:opendocman-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name opendocman \
  --image sac1647283583153:opendocman-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Open port 80 for the application:

az vm open-port --resource-group <your-rg> --name opendocman --port 80

Step 3 - Confirm the services are running

SSH in as azureuser and confirm that nginx, PHP FPM and MariaDB are all active. MariaDB listens only on 127.0.0.1:3306, while nginx serves the application on port 80.

The opendocman-firstboot unit reports active once it has finished its one-shot run.

systemctl is-active nginx php8.3-fpm mariadb opendocman-firstboot
ss -tlnp | grep -E ':80 |:3306 '

Step 4 - Retrieve your per-VM credentials

Each VM generates its own administrator password and its own database password on first boot and writes them to a root-only file. Nothing is shared between deployments, and nothing is recoverable from the published image. Read the file with sudo:

sudo cat /root/opendocman-credentials.txt

Step 5 - Sign in

Browse to http://<your-vm-public-ip>/. Sign in with the user admin and the password from /root/opendocman-credentials.txt.

Step 6 - Add your first document

Choose Add Document. Pick the file to upload and choose its owner, department and category. Set the department and per-user permissions the document should carry, add a description, and submit.

OpenDocMan writes the file into /var/www/document_repository, outside the web root. It records the file's metadata, owner, department, permissions and revision in the database.

Step 7 - Review and approve it

OpenDocMan ships with the authorization setting on, so a newly uploaded document is held for review before other users can see it. On the home page, open Documents waiting to be reviewed, tick the document and choose Authorize (or Reject). Enter a comment to send to the author and confirm. OpenDocMan then publishes the document into the repository.

To publish documents immediately, turn the review step off. Open Admin, then Settings, and set authorization to False.

Step 8 - Browse the repository

Choose Home. The Files List shows every document you are allowed to see, with its ID, filename, description, lock status, created and modified dates, author, department and size.

Click a filename to download the document. The download goes through OpenDocMan's permission check rather than straight off disk.

Step 9 - Check a document out and back in

Open a document and choose Check Out. OpenDocMan locks the document, so its status changes from unlocked to locked. Nobody else can submit a competing revision while you hold it.

When you finish editing, choose Check-in in the navigation and upload the new copy. OpenDocMan stores it as the next revision and releases the lock. The previous revision stays in the document's history.

Step 10 - Manage departments, users and permissions

Choose Admin. From here you can add, update and delete users, departments and categories. You can also manage file types, define your own metadata fields, work through the review and rejection queues, list checked-out files, adjust the site settings and read the reports.

The available rights are Forbidden, None, View, Read, Write and Admin. They apply per department and per user on each document.

Step 11 - Verify the security posture

Confirm three things on your own VM. First, the installer is gone: every installer route returns 404 and the installer code is not on disk. Second, the administrator created at first boot is the only account that can sign in.

Third, run the credential round trip. It proves that the per-VM password works through the real sign-in form, and that a blank password, upstream's published default and common weak guesses are all rejected:

for r in installer installer/setup-config "installer?op=install&force_fresh=1" install/odm.php; do printf '%s -> ' "/$r"; curl -s -o /dev/null -w '%{http_code}\n' "http://127.0.0.1/$r"; done
sudo bash /usr/local/sbin/opendocman-cred-roundtrip.sh

Step 12 - Verify the stack and the first boot gate

Confirm the OpenDocMan version and the health endpoint, then look at the gate that keeps the appliance shut until your credentials exist.

nginx.service carries a ConditionPathExists on the first-boot sentinel, so on a fresh boot systemd skips nginx entirely. The first-boot service creates your credentials, writes the sentinel and only then starts nginx:

grep ODM_APP_VERSION /var/www/opendocman/application/version.php; curl -sI http://127.0.0.1/healthz | head -1
grep -h '^ConditionPathExists' /etc/systemd/system/nginx.service.d/*.conf; ls -l /var/lib/sac/data/

Where your data lives

The OpenDocMan application tree is at /var/www/opendocman, owned by www-data, with the document root at /var/www/opendocman/public. The configuration, including the database credentials, is at /var/www/opendocman/application/configs/config.php.

Your documents are not in the web tree. They live at /var/www/document_repository, so an uploaded file can never be fetched directly and every download goes through OpenDocMan's permission check.

The MariaDB database opendocman holds every user, department, permission, document record, revision and log entry. It uses the default datadir at /var/lib/mysql. Back up the document repository and the database together.

sudo mariadb --protocol=socket -uroot -N -e "SELECT COUNT(*) AS users FROM opendocman.odm_user"

Adding your own domain and TLS

The appliance serves plain HTTP on port 80. For production, front it with your own domain and a TLS certificate. OpenDocMan derives its base URL from the request host at runtime, so there is no address to configure in the application.

Once TLS terminates in front of the VM, turn the secure session cookie on:

sudo sed -i 's/^session.cookie_secure = Off/session.cookie_secure = On/' /etc/php/8.3/fpm/conf.d/99-opendocman.ini
sudo systemctl restart php8.3-fpm

You can terminate TLS with Azure Application Gateway, an nginx or Caddy reverse proxy, or a managed load balancer with a certificate for your domain.

Why the secure cookie ships off. A session.cookie_secure cookie is sent only over HTTPS. If it were on while the appliance serves plain HTTP, every sign-in would silently fail. Turn it on in the same change that puts TLS in front of the VM.

Security notes

  • No installer to attack. The installer is not in this image and every installer route returns 404, so nobody can rewrite your database configuration or drop your tables through a setup wizard.
  • Closed until your credentials exist. nginx does not bind port 80 until the first-boot service has written your per-VM credentials.
  • Unique credentials per VM. The administrator password and the database password are unique to each VM, and upstream's published default admin credential does not authenticate. Protect /root/opendocman-credentials.txt, and change the password from within OpenDocMan if you share access.
  • Documents stay out of the web root. They live at /var/www/document_repository, so no upload is directly fetchable and every download is permission-checked.
  • Keep MariaDB private. It listens on 127.0.0.1 only and is not reachable from the network. Administer it over SSH with sudo mariadb.
  • Encrypt web traffic. OpenDocMan serves plain HTTP on port 80. Beyond a trusted network, put it behind your own TLS-terminating reverse proxy or Azure Application Gateway with a certificate for your domain.
  • Restrict the NSG. Limit inbound 80/tcp to the networks that need the application.

Support

SecureAnyCloud maintains this image and provides 24/7 support. For help deploying or operating OpenDocMan on Azure, contact us at secureanycloud.com.

Deploy on Azure

Launch OpenDocMan on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure