{"id":634,"date":"2025-03-15T08:43:02","date_gmt":"2025-03-15T08:43:02","guid":{"rendered":"https:\/\/www.alanknipmeyer.phd\/?p=634"},"modified":"2025-03-15T08:53:57","modified_gmt":"2025-03-15T08:53:57","slug":"self-hosting-overleaf-community-edition","status":"publish","type":"post","link":"https:\/\/www.alanknipmeyer.phd\/index.php\/2025\/03\/15\/self-hosting-overleaf-community-edition\/","title":{"rendered":"Self-Hosting Overleaf Community Edition"},"content":{"rendered":"\n<p>In this blog posting I show you how to use <a href=\"https:\/\/github.com\/overleaf\/overleaf\">Overleaf Community Edition<\/a> and store the resulting container on on self-hosted gitlab.<\/p>\n\n\n\n<p>I used to use Bangors Overleaf to write my Masters thesis, but Bournemouth (as of March 2025) didnt have a overleaf server available. I found quickly that the free <a href=\"https:\/\/www.overleaf.com\/\">overleaf server online <\/a>gives a limited amount of compile time and I also wanted to secure my own backups. With that I decided to self-host an overleaf server in the testlab.<\/p>\n\n\n\n<p>Having recently migrated my test Active Directory servers to proxmox, I had two spare physical servers. The latest version of Overleaf uses a mongodb version (6.0) that requires virtualization (VXd) from the CPU, so it was a good idea in terms of both systems management (backups\/load) to use a dedicated host as well. Previous versions of mongodb can be swapped out, but I didnt have a specific need to do so in this case.<\/p>\n\n\n\n<p>I installed Ubuntu 22.04 and Docker 28.0.1 &#8211; there was nothing particularly different in the standard install processes to complete this.<\/p>\n\n\n\n<p>I then started to following this <a href=\"https:\/\/docs.vultr.com\/how-to-install-overleaf-community-edition-on-ubuntu-20-04-lts\">good tutorial from Vultr<\/a> which got me off the ground, however I soon started running into issues as I wanted various templates and fonts available, and the packages where either not found or the fonts unavailable.<\/p>\n\n\n\n<p>The issue came because the Docker image doesnt include the necssary fonts. These cant be added to the running container as overleaf needs to be restarted and the fonts are not picked up correctly, therefore they must be built into the Dockerfile. I modified the provided Docker file (opt\/overleaf\/lib\/Dockerfile)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM sharelatex\/sharelatex:5.3.1\n \n# Install required packages\nRUN apt-get update &amp;&amp; apt-get upgrade -y &amp;&amp;  apt-get install -y \\\n    texlive \\\n    texlive-latex-extra \\\n    texlive-fonts-recommended \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*<\/code><\/pre>\n\n\n\n<p>When re-running the build scripts, the required fonts where then loaded onto the system. The docker image at this point is about 4.5G in size.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>su - overleaf\ncd $HOME # (should be \/opt\/overleaf)\nbin\/stop &amp;&amp; bin\/docker-compose rm -f sharelatex\nbin\/up -d --build\n\ndocker images # truncated for brevity<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>sharelatex\/sharelatex  5.3.1   841a2e9c7e63   12 days ago    4.48GB<\/code><\/pre>\n\n\n\n<p>With the container now running with the required fonts, IEEE templates could be loaded directly into the document itself and rendered correctly.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"203\" src=\"https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1024x203.png\" alt=\"\" class=\"wp-image-635\" srcset=\"https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1024x203.png 1024w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-300x59.png 300w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-768x152.png 768w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1536x304.png 1536w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-2048x405.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>However, the correct way to do this is to load the required packages into overleaf itself. This is done by spawning a root bash shell and loading the required packages in. This takes some time and its good to choose a local <a href=\"https:\/\/ctan.org\/mirrors\">mirror<\/a> to speed things up.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>su - overleaf\ncd \/opt\/overleafbin\/shell # launches a docker shell\ntlmgr update --selftlmgr option repository https:\/\/mirrors.mit.edu\/CTAN\/systems\/texlive\/tlnet\/ # change repo as required from CTAN mirrors https:\/\/ctan.org\/mirrors\nnohup tlmgr install scheme-full &amp; tail nohup.out # wait for updated\ntlmgr update --self --all \nexit<\/code><\/pre>\n\n\n\n<p>After sometime, the packages are now all installed and I can pretty much run any template\/function I need, i.e. Gannt Charts, IEEE templates,etc.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\\usepackage&#91;a4paper, margin=0.8in]{geometry} % Adjust page size and margins\n\\usepackage{pgfgantt} % Gantt chart package\n\\usepackage{graphicx} % For figures if needed\n\\usepackage{lscape} % roate specific pages\n\\usepackage{pdflscape} % rotate specific pages (final PDF output)\n\\usepackage{afterpage}\n%%%\n\\subsection{2025 - 2027}\n\\begin{center}\n\\begin{ganttchart}&#91;\n    x unit=.06mm, % Reduce column width\n    y unit title=0.8cm,\n    y unit chart=0.8cm,\n    %vgrid, hgrid,\n    title label font=\\bfseries,\n    time slot format=isodate\n]{2025-01-01}{2027-12-31} % First 3 years\n\\gantttitlecalendar{year} \\\\\n\\ganttbar{Literature Review}{2025-01-01}{2027-12-31} \\\\\n\\ganttbar{Lab Setup}{2025-01-01}{2025-12-01} \\\\\n\\ganttbar{Quantum Algorithm Research}{2025-04-01}{2027-06-30} \\\\\n\\ganttbar{Simulation and Testing}{2027-07-01}{2027-12-31}\n\\end{ganttchart}\n\\end{center}<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"283\" src=\"https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1-1024x283.png\" alt=\"\" class=\"wp-image-636\" srcset=\"https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1-1024x283.png 1024w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1-300x83.png 300w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1-768x213.png 768w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1-1536x425.png 1536w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-1.png 1900w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Whilst this allowed me to use the current running docker container, I wanted to ensure that I could use this container each time the server rebooted for patching\/operations as well be able to storage the package in selfhost gitlab which uses letsencrypt certs on nginx for its secure connections.<\/p>\n\n\n\n<p>First I wrote out the update docker container, note this is whilst it is still running &#8211; i have just exited out of the root shell to get back to the OS.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker commit sharelatex sharelatex\/sharelatex:with-texlive-full\ndocker images\nREPOSITORY TAG                            IMAGE ID      CREATED        SIZE\nsharelatex\/sharelatex with-texlive-full   527025329b2f  12 days ago    8.57GB\nsharelatex\/sharelatex 5.3.1               841a2e9c7e63  12 days ago    4.48GB<\/code><\/pre>\n\n\n\n<p>Modify the Overleaf config to use the updated image<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vi \/opt\/overleaf\/lib\/docker-compose.override.yml \n---\nversion: '2.2'\nservices:\nsharelatex:\nimage: sharelatex\/sharelatex:with-texlive-full<\/code><\/pre>\n\n\n\n<p>Now that I have a fully working container I want to push it to Gitlab&#8217;s container registry. As docker wont &#8216;trust&#8217; lets-encrypt certs and they are renewed every 3 months, I allowed the repo in the &#8216;<code>insecure-registries<\/code>&#8216; by modifying the docker config on the overleaf server to allow it. This assumes that DNS\/Host resolution is setup correctly, change the name and port accordingly.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/etc\/docker\/daemon.json\n{\n    \"insecure-registries\": &#91;\"alan-3209ay1.alanknipmeyer.science\",\"alan-3209ay1:5050\",\"alan-3209ay1.alanknipmeyer.science:5050\"],\n    \"log-driver\": \"json-file\",\n        \"log-opts\": {\n            \"max-size\": \"10m\",\n            \"max-file\": \"3\"\n        }\n}\n<\/code><\/pre>\n\n\n\n<p>I then generated an token so I could authenticate docker using it, these are located within user settings reached via your icon and preferences, then access tokens.<\/p>\n\n\n\n<p>I then was able to login to my own gitlab ready to push the image.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker login alan-3209ay1:5050\nUsername: alan\n \ni Info \u2192 A Personal Access Token (PAT) can be used instead.\n         To create a PAT, visit https:\/\/app.docker.com\/settings\n          \n          \nPassword: &lt;paste token&gt;\n \nWARNING! Your credentials are stored unencrypted in '\/root\/.docker\/config.json'.\nConfigure a credential helper to remove this warning. See\nhttps:&#47;&#47;docs.docker.com\/go\/credential-store\/\n \nLogin Succeeded<\/code><\/pre>\n\n\n\n<p>As the message says, its better to use a credentail helper but for brevity of this post the link is included <a href=\"https:\/\/docs.docker.com\/go\/credential-store\/\">here<\/a>.<\/p>\n\n\n\n<p>Next it was time to tag the image so it can be pushed to the repo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker tag 527025329b2f alan-3209ay1:5050\/knipmeyer-it\/overleaf\ndocker images\nREPOSITORY TAG                            IMAGE ID       CREATED       SIZE\nsharelatex\/sharelatex with-texlive-full   527025329b2f   12 ago        8.57GB\ndocker push alan-3209ay1:5050\/knipmeyer-it\/overleaf\nUsing default tag: latest\nThe push refers to repository &#91;alan-3209ay1:5050\/knipmeyer-it\/overleaf]\na714a521a8ca: Pushing &#91;==================================================&gt;]  4.241GB\n..\nlatest: digest: sha256:896e7e0d322af9cc480058ca102b34f768c153d22cb080b5da8288ba00241f34 size: 9697<\/code><\/pre>\n\n\n\n<p>I then confirmed the digest file was the same in gitlab.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"262\" src=\"https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-3-1024x262.png\" alt=\"\" class=\"wp-image-638\" srcset=\"https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-3-1024x262.png 1024w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-3-300x77.png 300w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-3-768x197.png 768w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-3-1536x394.png 1536w, https:\/\/www.alanknipmeyer.phd\/wp-content\/uploads\/2025\/03\/image-3-2048x525.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>With automated backups of gitlab already in place and the modify build code pushed along with the container, I&#8217;m now able to build and run my own overleaf server with no compile time restrictions.<\/p>\n\n\n\n<p>Hope this helps and thanks for following the blog!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog posting I show you how to use Overleaf Community Edition and store the resulting container on on self-hosted gitlab. I used to use Bangors Overleaf to write my Masters thesis, but Bournemouth (as of March 2025) didnt have a overleaf server available. I found quickly that the free overleaf server online gives [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-634","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/posts\/634","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/comments?post=634"}],"version-history":[{"count":4,"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/posts\/634\/revisions"}],"predecessor-version":[{"id":643,"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/posts\/634\/revisions\/643"}],"wp:attachment":[{"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/media?parent=634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/categories?post=634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.alanknipmeyer.phd\/index.php\/wp-json\/wp\/v2\/tags?post=634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}