Overleaf Community sucks (but I'm built different)
I’ve recently been deeply interested in self-hosting my own online services. Out of curiosity, an ominous thought occured to me: what if I ran my own Overleaf clone?
Every other small thingie we ran so far was basically working out of the box with little to no changes involved. Unlike those, Overleaf is not driven towards small self-hosting at home, and has no well-made admin wiki to help setting it up. It didn’t work out of the box, and required hours of browsing github and the broader internet to get it in working conditions.
So, without further ado, here is my own step by step guide on how to get a proper docker running.
The Docker Compose Configuration
The docker-compose.yml
file we can find on the github repo is utterly bloated with Overleaf Pro features, stores junk in the home user folder by default, and more importantly, the way it sets up the mongo database just doesn’t work (something to do with mongo needing to be accessed through its local IP address 192.168.1.XXX
rather than simply localhost
)…
I ended up using the following file, with 192.168.1.3
being the local IP of my server (use your own instead) and 6969
to port I used to access the webUI (on my local network, with Caddy taking care of the broader internet access over https):
services:
sharelatex:
restart: always
image: sharelatex/sharelatex
container_name: sharelatex
depends_on:
mongo:
condition: service_healthy
redis:
condition: service_started
ports:
- 6969:80
stop_grace_period: 60s
volumes:
- ./sharelatex_data:/var/lib/overleaf
environment:
OVERLEAF_APP_NAME: LaTeX@home
OVERLEAF_MONGO_URL: mongodb://mongo/sharelatex
OVERLEAF_REDIS_HOST: redis
REDIS_HOST: redis
ENABLED_LINKED_FILE_TYPES: 'project_file,project_output_file'
ENABLE_CONVERSIONS: 'true'
EMAIL_CONFIRMATION_DISABLED: 'true'
# OVERLEAF_SITE_URL: https://my.url.com/
OVERLEAF_NAV_TITLE: We already have Overleaf at home...
# OVERLEAF_HEADER_IMAGE_URL: http://example.com/mylogo.png
OVERLEAF_LEFT_FOOTER: '[{"text": "Beep"}]'
OVERLEAF_RIGHT_FOOTER: '[{"text": "Boop"}]'
SANDBOXED_COMPILES: 'false'
mongo:
restart: always
image: mongo:6.0
container_name: mongo
command: ["--replSet", "overleaf", "--bind_ip_all", "--port", "27017"]
ports:
- 27017:27017
volumes:
- ./mongo_data:/data/db
- ./bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
environment:
MONGO_INITDB_DATABASE: sharelatex
extra_hosts:
- mongo:192.168.1.3
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'overleaf',members:[{_id:0,host:'192.168.1.3:27017'}]}) }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 10s
retries: 5
redis:
restart: always
image: redis:6.2
container_name: redis
volumes:
- ./redis_data:/data
Wouldn’t it be great if this was enough?
Right?
This isn’t enough!
This isn’t enough because I like to use many packages that aren’t included in the basic texlive install, and of course the official overleaf sharelatex docker image doesn’t use texlive-full. I couldn’t find any well-maintained alternative, and I don’t want to maintain my an image, so here is how to make your own.
First, to enter the container and run commands from within, run docker exec -it sharelatex bash
in the folder where your docker-compose file is stored. Therein, tlmgr install scheme-full
should install texlive-full. A small but notable detail that took a long while to figure out: biber isn’t properly setup yet, so you also need to run ln /usr/local/texlive/2025/bin/x86_64-linux/biber /usr/local/bin/biber
in order to make it run. You can then exit the docker bash environment.
Of course, you do not want to do this each time you restart the docker, so you can then export your changes using docker commit sharelatex sharelatex/sharelatex:<commit-message>
, and then replace the line image: sharelatex/sharelatex
by image: sharelatex/sharelatex:<commit-message>
in docker-compose.yml
.
Et voilĂ .