Automate your document workflows with MayanEDMS - installing without Traefik
Document management for teams who need powerful workflow automation. Here's how to set up your own open-source DMS
Recently I went on the hunt for a good, open source Document Management System. My criteria were relatively straightforward:
- Must have a docker image
- Must support workflows (ideally automated)
- Must support multiple users, groups and roles
- Must be able to either upload documents directly from the GUI, or otherwise drop documents into a folder which would then be automatically pulled into the software
I found a couple of contenders, and after playing with them all for a little while (or not, I spent a couple of hours trying to get two of them working without success) I settled on Mayan. The GUI is generally intuitive, and the built in workflow manager is leaps and bounds easier to use than something like OpenKM which requires a completely separate program to manage. Mayan just looks better too.
Before we get into it, it's worth noting that while my walkthrough below is based on the docker-compose.yml and .env file found in the Mayan documentation, I've modified the files a fair bit to remove some bloat, and more importantly, remove the reliance on Traefik. This can still be used with Traefik, but this is for all of you who may already have your own load balancer or reverse proxy set up, whether that's an existing traefik configuration, or an nginx-based service.
Let's get into it.
Prerequisites
- Docker and docker-compose installed on your machine
- An ability to use docker-compose.yml files with .env files, either via SSH access to your NAS (click the link if you don't know how to do that) or by using Portainer
- Sudo/root access (normally by using the same password as any user with admin permissions)
- Folder and file creation permissions
Creating the folder system
The docker-compose.yml we'll use will create named volumes inside your /@docker/volumes directory for most that we need, so we only need to create a few ourselves.
- SSH into your server and navigate to your
dockerdirectory - Create a folder called
mayan, and inside this folder create two more, one calledstagingand one calledwatch - We'll also create our
docker-compose.ymland.envfiles inside ourmayandirectory - All of the above can be done with the following single command from your docker directory:
mkdir mayan && cd mayan && mkdir staging watch && touch docker-compose.yml .envDone.
Populating our compose file
Whichever way you prefer to edit your files, copy paste the following into your docker-compose.yml:
version: '3.9'
networks:
default:
name: mayan
ipam:
config:
- subnet: 172.${SUBNET}.0.0/28
volumes:
app:
elasticsearch:
postgres:
rabbitmq:
redis:
x-mayan-container:
&mayan-container
env_file: .env
environment:
MAYAN_CELERY_BROKER_URL: amqp://${MAYAN_RABBITMQ_USER}:${MAYAN_RABBITMQ_PASSWORD}@rabbitmq:5672/${MAYAN_RABBITMQ_VHOST}
MAYAN_CELERY_RESULT_BACKEND: redis://:${MAYAN_REDIS_PASSWORD}@redis:6379/1
MAYAN_DATABASES: "{'default':{'ENGINE':'django.db.backends.postgresql','NAME':'${MAYAN_DATABASE_NAME}','PASSWORD':'${MAYAN_DATABASE_PASSWORD}','USER':'${MAYAN_DATABASE_USER}','HOST':'${MAYAN_DATABASE_HOST}'} }"
MAYAN_LOCK_MANAGER_BACKEND: mayan.apps.lock_manager.backends.redis_lock.RedisLock
MAYAN_LOCK_MANAGER_BACKEND_ARGUMENTS: "{'redis_url':'redis://:${MAYAN_REDIS_PASSWORD}@redis:6379/2'}"
image: mayanedms/mayanedms:${MAYAN_DOCKER_IMAGE_TAG}
restart: unless-stopped
volumes:
- app:/var/lib/mayan
# Optional volumes to access external data like staging or watch folders
- ./staging:/staging_folder
- ./watch:/watch_folder
x-mayan-frontend-ports:
&mayan-frontend-ports
ports:
- "${PORT}:8000"
services:
mayan-app:
<<: *mayan-container
<<: *mayan-frontend-ports
elasticsearch:
environment:
- bootstrap.memory_lock=true
- discovery.type=single-node
- http.max_content_length=400mb
- xpack.security.enabled=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- ELASTIC_PASSWORD=${MAYAN_ELASTICSEARCH_PASSWORD}
image: elasticsearch:7.17.7
# Enable to allow external access to the database.
# ports:
# - "9200:9200"
restart: unless-stopped
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- elasticsearch:/usr/share/elasticsearch/data
postgresql:
command:
- "postgres"
- "-c"
- "checkpoint_completion_target=0.6"
- "-c"
- "default_statistics_target=200"
- "-c"
- "maintenance_work_mem=128MB"
- "-c"
- "max_connections=150"
- "-c"
- "shared_buffers=256MB"
- "-c"
- "work_mem=8MB"
environment:
POSTGRES_DB: ${MAYAN_DATABASE_NAME}
POSTGRES_PASSWORD: ${MAYAN_DATABASE_PASSWORD}
POSTGRES_USER: ${MAYAN_DATABASE_USER}
image: postgres:13.8-alpine
# Enable to allow external access to the database.
# ports:
# - "5432:5432"
restart: unless-stopped
volumes:
- postgres:/var/lib/postgresql/data
redis:
command:
- redis-server
- --appendonly
- "no"
- --databases
- "3"
- --maxmemory
- "100mb"
- --maxclients
- "500"
- --maxmemory-policy
- "allkeys-lru"
- --save
- ""
- --tcp-backlog
- "256"
- --requirepass
- "${MAYAN_REDIS_PASSWORD}"
image: redis:7.0.5-alpine
restart: unless-stopped
volumes:
- redis:/data
rabbitmq:
image: rabbitmq:3.11.2-management-alpine
environment:
RABBITMQ_DEFAULT_USER: ${MAYAN_RABBITMQ_USER}
RABBITMQ_DEFAULT_PASS: ${MAYAN_RABBITMQ_PASSWORD}
RABBITMQ_DEFAULT_VHOST: ${MAYAN_RABBITMQ_VHOST}
# Enable to allow access to the administration interface.
# ports:
# - "15672:15672"
restart: unless-stopped
volumes:
- rabbitmq:/var/lib/rabbitmqThere's a lot to look at here, but the main points to take away:
- The devs who created the original compose are using both a
.envandx-containerfunction to pass variables to the relevant containers. Using thex-containerfunction isn't really necessary here imho but I've decided not to change it so that our compose doesn't change more than necessary from the original - The above doesn't need anything changed (other than if you want to uncomment out some ports for
rabbitmq,postgresorelasticsearchto access them or their interfaces directly). We'll be doing all changes in our.envin 3, 2, 1...
Configuring our .env file
...now.
- Open up your empty
.envfile and paste the following into it:
##################################################################
# These variables are passed to Docker Compose to change how the #
# `docker-compose.yml` file is interpreted. #
##################################################################
# Default project name. Can also change this using the
# docker-compose `-p, --project-name NAME` option
COMPOSE_PROJECT_NAME=mayan
# User alternate Mayan EDMS Docker tag
MAYAN_DOCKER_IMAGE_TAG="s4.4" #pay attention to versions which may change in the future
#Networks. You MUST input an empty docker network subnet here so that the network can be created properly
SUBNET=60
#Ports. Change this if necessary to avoid a port mapping clash on your system
PORT=8000
# Database. No need to change unless you've changed the postgresql `service` name (they need to match)
MAYAN_DATABASE_HOST=postgresql
# Security. Change these before the first run.
# Once these are set do not change them here. If you wish to change the
# passwords or usernames after the installation has completed, follow the
# documentation of each component individually and then update the password
# or username in this file. _PASSWORD_START_MARKER
MAYAN_DATABASE_NAME=mayandatabase #change if necessary
MAYAN_DATABASE_PASSWORD=amayanpassword #changeme
MAYAN_DATABASE_USER=amayandbuser #changeme
MAYAN_ELASTICSEARCH_PASSWORD=anelastisearchpwd #changeme
MAYAN_RABBITMQ_USER=arabbitmqusr #changeme
MAYAN_RABBITMQ_PASSWORD=arabbitmqpwd #changeme
MAYAN_RABBITMQ_VHOST=mayan #changeme
MAYAN_REDIS_PASSWORD=aredispassword #changeme
# Change if you use external services, otherwise don't touch
MAYAN_DOCKER_WAIT="postgresql:5432 rabbitmq:5672 redis:6379"
# Uncomment if you want to access RabbitMQ admin gui. Don't forget to uncomment in the `docker-compose.yml` too
# MAYAN_RABBITMQ_ADMIN_HTTP_PORT=15672
#########################################################
# These variables are passed to the running containers. #
# They are interpreted by Mayan EDMS. #
# Uncomment if you want to use them #
#########################################################
# To use block storage
# MAYAN_DOCUMENTS_STORAGE_BACKEND="storages.backends.s3boto3.S3Boto3Storage"
# MAYAN_DOCUMENTS_STORAGE_BACKEND_ARGUMENTS="{'access_key':'<access key>','secret_key':'<secret key>','bucket_name':'mayan','endpoint_url':'http://<URL:port>','verify':'False'}" # 'verify':'False' for local servers with self signed SSL certificate
# To add operating system packages, like additional OCR language,
# packages, put then in the variable below
# MAYAN_APT_INSTALLS="tesseract-ocr-deu tesseract-ocr-nld"
# To use LDAP authentication.
# Create a folder named `user_settings` in the `media` folder.
# Copy the file `contrib/settings/ldap_connection_settings.py` from the online
# repository and place in the new `user_settings` folder.
# Edit the `user_settings/ldap_connection_settings' file to work with your
# LDAP server.
# Example: https://django-auth-ldap.readthedocs.io/en/latest/example.html
# Restart the stack and test.
Again, quite a bit going on here. Change the following variables before spinning up the container stack:
SUBNET. If you're unsure which subnets you have free, choose a high number in the 10s, something around 60PORT. Only change this if necessary to avoid a port conflict on the host- Almost everything under
Security(passwords, usernames etc.
Once you've modified the file, you're now ready to spin up the stack with docker-compose up -d.
First steps after creation
It will take about 3-5 minutes to fully spin up all the containers. If you follow along in the logs you'll notice a few errors as the programs go through their various startups, some are to be expected.
Once you see the following in the mayan-app container logs you're good to go:
-------------- celery@mayan-edms-worker_d.1e8f7ab00ea8 v5.2.7 (dawn-chorus)
--- ***** -----
-- ******* ---- Linux-4.4.180+-x86_64-with-glibc2.31 2023-04-04 03:41:08
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app: mayan:0x7f049b596bb0
- ** ---------- .> transport: amqp://arabbitmqusr:**@rabbitmq:5672/mayan
- ** ---------- .> results: redis://:**@redis:6379/1
- *** --- * --- .> concurrency: 1 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> ocr exchange=ocr(direct) key=ocr
.> storage_periodic exchange=storage_periodic(direct) key=storage_periodic
.> tools exchange=tools(direct) key=toolsOpen your browser and navigate to http://yourhostIP:8000 (if you changed PORT in the .env then make sure to use that port here in the browser).
The following screen will pop up with a randomly generated password:

Type in the credentials and you're in!
The very first thing you should do is change your admin password, which can be done from User->Change password in the top right corner.

Take a look around, look at some of the tutorials and information in the documentation, and you'll have automated your document workflows in no time!
Related Articles


