Overleaf has become a popular choice for collaborative LaTeX editing, making it easy for academics, researchers, and engineers to work together directly in a web browser.
However, using Overleaf’s public cloud service involves more than just a financial cost. As projects become larger and more complex, the disadvantages of depending on a third-party Software-as-a-Service (SaaS) provider become increasingly difficult to overlook:
- Compile Timeouts: On Overleaf’s free plan, you are restricted to a short 10-second compilation window. The moment you add complex diagrams, heavy plots, or large high-resolution figures, your builds hit a wall and crash with timeout errors. Even paid subscription tiers cap your compile times.
- Data Privacy and IP Concerns: Uploading proprietary research, sensitive company documents, or unpublished papers to a cloud server means trusting an external platform with your intellectual property. For many institutions and privacy-conscious authors, storing raw LaTeX code online raises significant security and compliance concerns.
- Subscription Paywalls & Team Limits: Essential features such as real-time collaboration with more than one co-author, full project history, and Git integration are locked behind recurring monthly subscriptions.
- Vendor Lock-In & Internet Dependency: If your internet connection drops or Overleaf experiences downtime, access to your work instantly stops.
Fortunately, you don’t have to trade Overleaf's brilliant web-based interface for local command-line tools. By self-hosting Overleaf Community Edition via Docker and Docker Compose, you get the best of both worlds. Unlimited compilation power, zero data tracking, full offline availability, and complete control over your TeX environment. All running on your own server or local machine.
In this guide, we’ll walk through setting up your private Overleaf instance step by step using Docker and Docker Compose.

Docker Compose Setup
The docker compose stack for Overleaf consists of three components:
- MongoDB database
- Redis caching database
- Overleaf app
Setting Up MongoDB
Before spawning up the Overleaf stack, one has to define a MongoDB configuration file.
Luckily, the file can easily be downloaded and put aside next to your future docker-compose.yml file. Just run the following command on your Linux host:
curl -o mongodb-init-replica-set.js https://raw.githubusercontent.com/overleaf/overleaf/main/bin/shared/mongodb-init-replica-set.jsDownloading mongodb-init-replica-set.js
Alternatively, if you want to manually create it, please put the following content in a file named mongodb-init-replica-set.js:
/* eslint-disable no-undef */
rs.initiate({ _id: 'overleaf', members: [{ _id: 0, host: 'mongo:27017' }] })Content of mongodb-init-replica-set.js
Setting Up Overleaf
Next, we can create the docker-compose.yml, which defines all three containers.
OVERLEAF_INVITE_TOKEN_SECRET.services:
sharelatex:
image: sharelatex/sharelatex:6.3.0
container_name: sharelatex
restart: always
depends_on:
mongo:
condition: service_healthy
redis:
condition: service_started
ports:
- 8888:80
expose:
- 80
links:
- mongo
- redis
stop_grace_period: 60s
volumes:
- ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/sharelatex/data:/var/lib/overleaf
environment: # see https://docs.overleaf.com/on-premises/configuration/overleaf-toolkit/environment-variables
OVERLEAF_APP_NAME: Overleaf Community Edition
OVERLEAF_MONGO_URL: mongodb://mongo/sharelatex?replicaSet=overleaf
OVERLEAF_INVITE_TOKEN_SECRET: Distance-Rework-Iphone-Viewing # generate a secure value with openssl rand -base64 32
OVERLEAF_REDIS_HOST: redis
REDIS_HOST: redis
ENABLED_LINKED_FILE_TYPES: 'project_file,project_output_file'
ENABLE_CONVERSIONS: 'true'
EMAIL_CONFIRMATION_DISABLED: 'true'
# TEXMFVAR: /var/lib/sharelatex/tmp/texmf-var
# OVERLEAF_SITE_URL: http://overleaf.example.com
# OVERLEAF_NAV_TITLE: Overleaf Community Edition
# OVERLEAF_HEADER_IMAGE_URL: http://example.com/mylogo.png
# OVERLEAF_ADMIN_EMAIL: [email protected]
# OVERLEAF_LEFT_FOOTER: '[{"text": "Another page I want to link to can be found <a href=\"here\">here</a>"} ]'
# OVERLEAF_RIGHT_FOOTER: '[{"text": "Hello I am on the Right"} ]'
# OVERLEAF_EMAIL_FROM_ADDRESS: "[email protected]"
# OVERLEAF_EMAIL_AWS_SES_ACCESS_KEY_ID:
# OVERLEAF_EMAIL_AWS_SES_SECRET_KEY:
# OVERLEAF_EMAIL_SMTP_HOST: smtp.example.com
# OVERLEAF_EMAIL_SMTP_PORT: 587
# OVERLEAF_EMAIL_SMTP_SECURE: false
# OVERLEAF_EMAIL_SMTP_USER:
# OVERLEAF_EMAIL_SMTP_PASS:
# OVERLEAF_EMAIL_SMTP_TLS_REJECT_UNAUTH: true
# OVERLEAF_EMAIL_SMTP_IGNORE_TLS: false
# OVERLEAF_EMAIL_SMTP_NAME: '127.0.0.1'
# OVERLEAF_EMAIL_SMTP_LOGGER: true
# OVERLEAF_CUSTOM_EMAIL_FOOTER: "This system is run by department x"
# ENABLE_CRON_RESOURCE_DELETION: true
# OVERLEAF_LDAP_URL: 'ldap://ldap:389'
# OVERLEAF_LDAP_SEARCH_BASE: 'ou=people,dc=planetexpress,dc=com'
# OVERLEAF_LDAP_SEARCH_FILTER: '(uid={{username}})'
# OVERLEAF_LDAP_BIND_DN: 'cn=admin,dc=planetexpress,dc=com'
# OVERLEAF_LDAP_BIND_CREDENTIALS: 'GoodNewsEveryone'
# OVERLEAF_LDAP_EMAIL_ATT: 'mail'
# OVERLEAF_LDAP_NAME_ATT: 'cn'
# OVERLEAF_LDAP_LAST_NAME_ATT: 'sn'
# OVERLEAF_LDAP_UPDATE_USER_DETAILS_ON_LOGIN: 'true'
# OVERLEAF_TEMPLATES_USER_ID: "578773160210479700917ee5"
# OVERLEAF_NEW_PROJECT_TEMPLATE_LINKS: '[ {"name":"All Templates","url":"/templates/all"}]'
# OVERLEAF_PROXY_LEARN: "true"
# OVERLEAF_TRUSTED_PROXY_IPS: 127.0.0.1/32
#networks:
# - proxy
# - internal-db
#labels:
# - traefik.enable=true
# - traefik.docker.network=proxy
# - traefik.http.routers.overleaf.rule=Host(`overleaf.example.com`)
# - traefik.http.services.overleaf.loadbalancer.server.port=80
# # Optional part for traefik middlewares
# - traefik.http.routers.overleaf.middlewares=local-ipwhitelist@file,crowdsec@file
mongo:
restart: always
image: mongo:8.2
container_name: sharelatex-mongo
command: "--replSet overleaf"
expose:
- 27017
volumes:
- ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/sharelatex/mongo:/data/db
- ./mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js:ro
environment:
MONGO_INITDB_DATABASE: sharelatex
extra_hosts:
- mongo:127.0.0.1
healthcheck:
test: echo 'db.stats().ok' | mongosh localhost:27017/test --quiet
interval: 10s
timeout: 10s
retries: 5
#networks:
# - internal-db
redis:
restart: always
image: redis:8-alpine
container_name: sharelatex-redis
expose:
- 6379
volumes:
- ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/sharelatex/redis:/data
#networks:
# - internal-db
#networks:
# proxy:
# external: true
# internal-db:
# internal: trueThe stack works without TLS and a specific network configuration just fine. So you may just spawn it up for testing purposes and add a reverse proxy or custom networking later on.
Spawning the Stack
After having defined the docker-compose.yml as well as the mongodb-init-replica-set.js configuration file for MongoDB, we can start spawning up the stack via:
docker compose up -dAfterwards, the Overleaf web interface will be available on:
http://<YOUR-IP>:8888Creating your Admin User
To create the first admin user account, one can open the web URL path /launchpad. So please go ahead and open the following URL:
http://<YOUR-IP>:8888/launchpad Adhere to the account setup instructions and create your admin account.
You may proceed logging in.
Additional Packages
The Overleaf Community Docker image comes as lightweight installation and provides only a minimal install of TeXLive.
With this minimal installation, most real-world LaTex projects won't really compile and you won't be able to generate a PDF document.
Therefore, we have to add more packages using tlmgr.
Install Individual Packages
Depending on your LaTex project, you may want to install individual and selective packages only. Basically, just the things you need.
To install an individual package, you can run:
docker exec sharelatex tlmgr install <package-name>Command to install individual package
Here is an example:
docker exec -it sharelatex tlmgr install collection-langgerman collection-fontsrecommended collection-latexrecommended collection-latexextra collection-bibtexextraInstall the Full Scheme
In order to run an Overleaf instance with nearly all possible features supported, one have to install the full scheme.
To do so, please run the following command:
docker exec sharelatex tlmgr install scheme-fullCommand to install the full scheme with all packages
scheme-full may take a few minutes as multiple packages must be downloaded, installed and activated. Persist Package Data
Once individual packages or the full scheme were installed, your Overleaf instance is ready to go. Just define your project and LaTex files and PDF compilation should work flawlessly.
However, there is one downside.
tlmgr binary are not persisted accross container restarts. Therefore, one will loose all package installs and would have to install the individual packages or full-scheme each time the container is restarted. Quite a PAIN!
In order to persist installed packages, one have to use the docker commit command as follows:
docker commit sharelatex sharelatex/sharelatex:6.3.0-with-texlive-fullCommand to snapshot the container image with custom installed packages
Afterwars, one have to define this custom image at the docker-compose.yaml and restart the stack.
services:
sharelatex:
image: sharelatex/sharelatex:6.3.0-with-texlive-full
...Excerpt of the adjusted docker-compose.yml with the new image tag
After container restart, your Overleaf instance with individually installed packages is ready to use.
Summary
Self-hosting Overleaf Community Edition with Docker and Docker Compose gives you complete control over your LaTeX environment, bypassing SaaS constraints like strict compile timeouts, team size caps, and cloud privacy concerns.
Enjoy!
Discussion