Most self-hosted document apps answer one question: where's that letter? Mayan EDMS answers a harder set: who approved this contract, which version did legal sign off on, who's allowed to see it, and when can we legally destroy it?
Mayan is an electronic document management system in the enterprise sense. It has OCR and search like the others, but its real strengths are structure and control: document types with required metadata, multi-step approval workflows, version history, digital signatures and permissions down to a single document. It's free and open source (GPL-2.0), written in Python on Django, has been developed for more than a decade, and is on the 4.12 release line.
The mental model
Mayan has more moving parts than a home-scanning app, and they make sense once you see how they fit together. Everything hangs off the document type:
DOCUMENT TYPE "Invoice", "Contract", "HR Record"
├─ metadata types vendor, amount, due date (required or optional)
├─ OCR + parsing on/off, language
├─ workflows which processes this type goes through
├─ retention trash after N days, delete after N more
└─ antivirus scan uploads with ClamAV or not
Then, on top of documents:
TAGS colored labels
CABINETS hand-made folder trees (a document can be in several)
INDEXES folder trees Mayan builds for you from templates
ACLs who can do what, per document, type or object
The distinction between cabinets and indexes is the most important one to grasp. Cabinets are folders you curate by hand. Indexes are generated automatically: you write a template once, and Mayan sorts every document into a virtual folder tree from its metadata, updating it as documents change.
Feature tour
- Metadata. Typed fields per document type, with defaults, lookups and validation. "Invoice" can require a vendor and an amount, while "Contract" requires parties and an expiry date.
- OCR and parsing. Tesseract is built in, and the work can be spread across several worker machines. Text from born-digital files is parsed directly. Built-in file metadata (author, camera settings, GPS) is extracted automatically.
- Workflows. Real state machines with states, transitions, actions on entry and exit, and automatic expiry and escalation. Every change is logged.
- Versions. Multiple versions of a document, each of which can be downloaded or restored, with an audit trail.
- Check-out and check-in, so two people don't edit the same document at once.
- Signatures. Verify embedded cryptographic signatures, attach detached ones, and record captured handwritten signatures.
- Smart links that connect related documents automatically by their metadata, such as a purchase order and its invoices.
- Duplicate detection, with exact-file and exact-label matching out of the box.
- Search. Full-text search over content and metadata. A built-in backend is the default, and Elasticsearch is available for big archives.
- Access control. Unlimited roles, a permission for every single operation, and ACLs on individual objects, with LDAP, OpenID Connect and other single sign-on options.
- Antivirus. Optional ClamAV scanning of uploads, switched on per document type.
- A full REST API with OpenAPI documentation, so other systems can push documents in and pull them out.
Install it with Docker
The official route is Docker Compose, and getting started really is three commands:
curl https://gitlab.com/mayan-edms/mayan-edms/-/raw/master/docker/docker-compose.yml -O
curl https://gitlab.com/mayan-edms/mayan-edms/-/raw/master/docker/.env -O
docker compose up --detach
Read this before you run the last command. The compose file falls back to default passwords for its database, message queue and cache (mayandbpass and friends). Set your own in .env before the first start, because they're baked into the database when it's created:
# add to .env
MAYAN_DATABASE_PASSWORD=a-long-random-string
MAYAN_RABBITMQ_PASSWORD=another-long-random-string
MAYAN_REDIS_PASSWORD=and-another-one
# the web UI listens on port 80 by default; move it if 80 is taken
MAYAN_FRONTEND_HTTP_PORT=8080
The stack is assembled with Compose profiles. The default in .env is:
COMPOSE_PROFILES=all_in_one,postgresql,rabbitmq,redis
That runs the Mayan app (web interface and workers in one container) with PostgreSQL for data, RabbitMQ for the task queue and Redis for locking and caching. Add profiles as you need them:
elasticsearch a faster search backend for large archives
traefik reverse proxy with automatic Let's Encrypt HTTPS
postgresql-backup scheduled database dumps
index_mirror expose an index as a read-only folder tree on the host
cabinet_mirror the same, for a cabinet
extra_worker_* split workers out to scale up
On first load, the login page shows automatically generated admin credentials. Log in with them, change the password straight away (the notice disappears once you do), and create real user accounts.
Be realistic about resources. Even the all-in-one setup runs four services, including a database and a message broker. Plan on a few gigabytes of RAM and a few CPU cores, more if you'll OCR a lot. This is a VPS or homelab-server app, not a Raspberry Pi one.
A worked example: invoice approval
Here's what Mayan is built for. Say invoices arrive by email, need a manager's approval, and must be kept for seven years.
1. The document type
Create an Invoice document type with required metadata types vendor, amount and due_date. Under its retention settings, keep files for seven years before they move to the trash. Turn on ClamAV for it, since email attachments are where malware arrives.
2. The source
Add an email source (IMAP or POP3) pointed at invoices@, assigned to the Invoice type. Attachments come in typed and ready for metadata. For paper, a watch folder that your scanner drops into works the same way, and a staging folder lets you preview files before uploading them.
3. The workflow
[Received] --submit--> [Awaiting approval] --approve--> [Approved] --pay--> [Paid]
|
+--reject--> [Rejected]
Awaiting approval: escalate to the finance lead if untouched for 3 days
Approved: action = add tag "approved", email accounts payable
Each transition can be limited to specific roles: only managers can approve, and only finance can mark something paid. Every step is recorded in the document's workflow log with who did it and when.
4. The index
Finally, an index that files invoices automatically by year, then vendor. Each level is a small template:
Level 1: {{ document.date_added|date:"Y" }}
Level 2: {{ document.metadata_value_of.vendor }}
Browse the index and you see 2026 / Electric Co / …, rebuilt live as invoices arrive. Turn on the index_mirror profile and the same tree appears as a read-only folder on the server, which is handy for backup tools or a file share.
Things to know before you commit
- There's a learning curve. Document types, metadata types, indexes, smart links and workflows are each separate screens. Budget an afternoon to model your documents before you upload anything, because restructuring later is much harder.
- The interface is functional, not fancy. It's a dense admin-style UI built for daily office work, not a slick consumer app.
- Back up two things: the PostgreSQL database (the
postgresql-backupprofile helps) and the app volume at/var/lib/mayan, which holds the files themselves. One without the other is useless. - Keep it private. Like any archive of sensitive paperwork, run it behind a VPN or an authenticated reverse proxy. The
traefikprofile handles HTTPS, but HTTPS alone doesn't make it safe to expose to the internet. - The docs are thorough, and the project also publishes books and a knowledge base if you're deploying it seriously.
Mayan EDMS or Paperless-ngx?
I covered Paperless-ngx in a separate transmission today, and they're the two names that come up every time. They solve different problems:
PAPERLESS-NGX MAYAN EDMS
Built for homes, small offices teams, organizations
Organizing tags, auto-classifier types, metadata, indexes
Workflows automation rules approval state machines
Versions yes yes, with check-out/in
Signatures no verify and capture
Permissions per user and document roles and ACLs
Setup effort an evening a weekend of planning
Hardware Raspberry Pi is fine a real server
License GPL-3.0 GPL-2.0
If your goal is "make the paper pile searchable and stop thinking about it", choose Paperless-ngx. If you're running a small business, a nonprofit or a club, where documents have owners, approvals, versions and retention rules, Mayan is the one built for that, and it's hard to beat for free software.
Verdict
Mayan EDMS is what you reach for when documents are part of a process rather than just a pile. It asks more of you up front, in planning and in hardware, and gives you something few open-source tools offer in return: a document system with real structure, audit trails and access control, running entirely on your own server.
Start with the documentation and the GitLab repository. Links are also in the downloads directory and the resource index.
End of transmission.