Merge pull request #1 from tommybobbins/add-kubernetes-in-podman-demo

Add sample kind setup
This commit is contained in:
Tim Gibbon
2026-06-02 19:32:25 +01:00
committed by GitHub
34 changed files with 2105 additions and 150 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
version: "2.2"
services:
sharelatex:
overleaf:
ports:
- 30000:30000
- 30150:30150
+9 -9
View File
@@ -1,10 +1,10 @@
services:
sharelatex:
overleaf:
restart: always
# Server Pro users:
# image: quay.io/sharelatex/sharelatex-pro
image: sharelatex/sharelatex
container_name: sharelatex
# image: quay.io/overleaf/overleaf-pro
image: overleaf/overleaf
container_name: overleaf
depends_on:
mongo:
condition: service_healthy
@@ -14,7 +14,7 @@ services:
- 80:80
stop_grace_period: 60s
volumes:
- ~/sharelatex_data:/var/lib/overleaf
- ~/overleaf_data:/var/lib/overleaf
########################################################################
#### Server Pro: Uncomment the following line to mount the docker ####
#### socket, required for Sibling Containers to work ####
@@ -23,7 +23,7 @@ services:
environment:
OVERLEAF_APP_NAME: Overleaf Community Edition
OVERLEAF_MONGO_URL: mongodb://mongo/sharelatex
OVERLEAF_MONGO_URL: mongodb://mongo/overleaf
# Same property, unfortunately with different names in
# different locations
@@ -78,9 +78,9 @@ services:
## Sandboxed Compiles: https://docs.overleaf.com/on-premises/configuration/overleaf-toolkit/server-pro-only-configuration/sandboxed-compiles
SANDBOXED_COMPILES: "true"
### Bind-mount source for /var/lib/overleaf/data/compiles inside the container.
SANDBOXED_COMPILES_HOST_DIR_COMPILES: "/home/user/sharelatex_data/data/compiles"
SANDBOXED_COMPILES_HOST_DIR_COMPILES: "/home/user/overleaf_data/data/compiles"
### Bind-mount source for /var/lib/overleaf/data/output inside the container.
SANDBOXED_COMPILES_HOST_DIR_OUTPUT: "/home/user/sharelatex_data/data/output"
SANDBOXED_COMPILES_HOST_DIR_OUTPUT: "/home/user/overleaf_data/data/output"
### Backwards compatibility (before Server Pro 5.5)
DOCKER_RUNNER: "true"
SANDBOXED_COMPILES_SIBLING_CONTAINERS: "true"
@@ -110,7 +110,7 @@ services:
- ~/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
MONGO_INITDB_DATABASE: overleaf
extra_hosts:
# Required when using the automatic database setup for initializing the replica set.
# This override is not needed when running the setup after starting up mongo.
+181
View File
@@ -0,0 +1,181 @@
# Overleaf — Local Kubernetes Bootstrap
Runs Overleaf Community Edition on a local [kind](https://kind.sigs.k8s.io/) cluster
[Argo CD](https://argo-cd.readthedocs.io/) for GitOps deployment.
All runtime images are pulled exclusively from localhost:5001 once bootstrapped.
## Architecture
```
macOS (podman)
│
├── kind cluster (podman provider)
│ ├── local-repo :5001 — local OCI registry
│ ├── Argo CD :30080 — GitOps controller
│ └── overleaf namespace
│ ├── overleaf :30000
│ ├── mongo
│ └── redis
│
└── podman build → push → localhost:5001
```
## Prerequisites
- macOS with [Homebrew](https://brew.sh/)
- `brew install kind kubectl helm podman argocd`
Run the prereqs check:
```bash
./k8s/bootstrap/01-prereqs.sh
```
This also initialises and starts the podman machine if one isn't running.
## Step 1 — Create the kind cluster
```bash
./k8s/bootstrap/02-cluster.sh
```
What it does:
- Creates a single-node kind cluster named `overleaf` using `k8s/kind/cluster.yaml`
- Adds `localhost:5001` as an insecure registry in `~/.config/containers/registries.conf`
> **Podman note**: kind uses `KIND_EXPERIMENTAL_PROVIDER=podman` automatically.
> Port bindings go through the podman machine — `localhost:5001` on macOS reaches the local registry in podman
## Step 2 — Install Local Registry
```bash
./k8s/bootstrap/03-local-registry.sh
```
Access at **http://localhost:5001/v2**
## Step 3 — Install Argo CD
```bash
./k8s/bootstrap/04-argocd.sh
```
Installs Argo CD via Helm and registers the Overleaf `Application` from
`k8s/argocd/application.yaml`. Argo CD watches `k8s/charts/overleaf/` in the
configured git repo and syncs on every commit.
Access at **http://localhost:30080** — credentials printed by the script.
> By default `application.yaml` points at `https://github.com/overleaf/overleaf.git`.
> For a fully sandboxed setup, deploy [Gitea](https://gitea.io/) inside the cluster
> and update `repoURL` to point there.
## Step 4 — Build overleaf and push all images to Local Registry
```bash
./k8s/bootstrap/05-build-push.sh
```
Builds the overleaf image locally from `server-ce/` using podman, then pushes
all three images to Local Registry:
| Image | Local Registry tag |
|-------|-----------|
| built from `server-ce/Dockerfile-base` | `localhost:5001/overleaf/overleaf-base:local` |
| built from `server-ce/Dockerfile` | `localhost:5001/overleaf/overleaf:local` |
| `mongo:8.0` (mirrored from Docker Hub) | `localhost:5001/overleaf/mongo:8.0` |
| `redis:6.2` (mirrored from Docker Hub) | `localhost:5001/overleaf/redis:6.2` |
After this step the cluster is fully sandboxed for runtime — no external pulls happen.
> **Podman version**: `COPY --parents` in `server-ce/Dockerfile` requires
> **podman 4.8+ / Buildah 1.32+**. Check with `podman --version`.
>
> Override the image tag with `TAG=myfeature ./k8s/bootstrap/05-build-push.sh`,
> then set `overleaf.image.tag: myfeature` in `k8s/charts/overleaf/values.yaml`.
## Step 5 — Sync and access Overleaf
```bash
argocd app sync overleaf
argocd app wait overleaf --health
```
Overleaf will be available at **http://localhost:30000**.
Create an admin account:
```bash
kubectl exec -n overleaf deploy/overleaf -- \
/bin/bash -c "cd /overleaf/services/web && node modules/server-ce-scripts/scripts/create-user --admin --email admin@example.com"
```
## Day-to-day workflow
### Rebuild and redeploy
```bash
# Build with a custom tag
TAG=myfeature ./k8s/bootstrap/05-build-push.sh
# Update the tag and sync
# Edit k8s/charts/overleaf/values.yaml: overleaf.image.tag: myfeature
argocd app sync overleaf
```
Or build manually:
```bash
cp server-ce/.dockerignore .
podman build -f server-ce/Dockerfile-base -t localhost:5001/overleaf/overleaf-base:dev .
podman build -f server-ce/Dockerfile \
--build-arg OVERLEAF_BASE_TAG=localhost:5001/overleaf/overleaf-base:dev \
-t localhost:5001/overleaf/overleaf:dev .
podman push localhost:5001/overleaf/overleaf:dev --tls-verify=false
```
### Iterate on Helm chart changes
Edit files under `k8s/charts/overleaf/`, commit, push to the tracked branch,
then `argocd app sync overleaf`. Argo CD can also auto-sync on every push if
the webhook is configured.
### Tear down
```bash
kind delete cluster --name overleaf
```
## File layout
```
k8s/
├── README.md
├── kind/
│ └── cluster.yaml kind cluster config (podman, port mappings, containerd registry mirror)
├── argocd/
│ ├── values.yaml Argo CD Helm values (NodePort, insecure mode)
│ └── application.yaml Argo CD Application pointing to k8s/charts/overleaf
├── charts/
│ └── overleaf/
│ ├── Chart.yaml
│ ├── values.yaml Image refs, resource limits, env vars
│ └── templates/
│ ├── mongo-* Deployment, Service, PVC, ConfigMap (replica-set init)
│ ├── redis-* Deployment, Service, PVC
│ └── overleaf-* Deployment, Service (NodePort 30000), PVC, Ingress (disabled by default)
└── bootstrap/
├── 01-prereqs.sh
├── 02-cluster.sh
├── 03-local-registry.sh
├── 04-argocd.sh
└── 05-build-push.sh
```
## Known limitations
- **Sandboxed compiles** (`SANDBOXED_COMPILES`) are disabled. That feature requires
Docker sibling containers, which needs a privileged DinD sidecar in Kubernetes.
- Local Repo is HTTP-only.
- The Argo CD `Application` uses the public GitHub remote. For offline use, add
Gitea to the cluster and mirror the repo there.
+24
View File
@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: overleaf
namespace: argocd
spec:
project: default
source:
# Update repoURL to your fork or a local Gitea instance for true air-gap operation
repoURL: https://github.com/overleaf/overleaf.git
targetRevision: HEAD
path: k8s/charts/overleaf
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: overleaf
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+9
View File
@@ -0,0 +1,9 @@
server:
service:
type: NodePort
nodePortHttp: 30080
configs:
params:
# Disable TLS on the ArgoCD API server so NodePort HTTP access works without cert errors
server.insecure: "true"
+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail
REQUIRED_TOOLS=(kind kubectl helm podman argocd)
MISSING=()
for tool in "${REQUIRED_TOOLS[@]}"; do
if ! command -v "$tool" &>/dev/null; then
MISSING+=("$tool")
else
echo " [ok] $tool $(${tool} version --short 2>/dev/null || ${tool} --version 2>/dev/null | head -1)"
fi
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo ""
echo "Missing tools: ${MISSING[*]}"
echo ""
echo "Install via Homebrew:"
echo " brew install kind kubectl helm podman"
echo " brew install argocd"
exit 1
fi
echo ""
echo "Checking podman machine..."
if ! podman machine list 2>/dev/null | grep -q running; then
echo " No running podman machine found. Starting default machine..."
podman machine init --memory 8192 --cpus 4 --disk-size 20 2>/dev/null || true
#podman machine init 2>/dev/null || true
podman machine start
else
echo " [ok] podman machine running"
fi
echo ""
echo "All prerequisites satisfied."
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CLUSTER_NAME="${CLUSTER_NAME:-overleaf}"
export KIND_EXPERIMENTAL_PROVIDER=podman
echo "==> Creating kind cluster '${CLUSTER_NAME}'..."
if kind get clusters 2>/dev/null | grep -q "^${CLUSTER_NAME}$"; then
echo " Cluster '${CLUSTER_NAME}' already exists, skipping."
else
KIND_EXPERIMENTAL_PROVIDER=podman kind create cluster \
--name "${CLUSTER_NAME}" \
--config "${SCRIPT_DIR}/../kind/cluster.yaml" \
--wait 120s
echo " [ok] Cluster created."
fi
echo ""
echo "==> Setting kubectl context..."
kubectl cluster-info --context "kind-${CLUSTER_NAME}"
echo ""
echo "Cluster ready. Next: run 03-local-registry.sh"
+58
View File
@@ -0,0 +1,58 @@
#!/bin/sh
set -o errexit
# 1. Create registry container unless it already exists
reg_name='kind-registry'
reg_port='5001'
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
docker run \
-d --restart=always -p "127.0.0.1:${reg_port}:5000" --network bridge --name "${reg_name}" \
registry:3
fi
# 2. Create kind cluster with containerd registry config dir enabled
#
# NOTE: the containerd config patch is not necessary with images from kind v0.27.0+
# It may enable some older images to work similarly.
# If you're only supporting newer relases, you can just use `kind create cluster` here.
#
# See:
# https://github.com/kubernetes-sigs/kind/issues/2875
# https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration
# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
# 3. Add the registry config to the nodes
#
# This is necessary because localhost resolves to loopback addresses that are
# network-namespace local.
# In other words: localhost in the container is not localhost on the host.
#
# We want a consistent name that works from both ends, so we tell containerd to
# alias localhost:${reg_port} to the registry container when pulling images
REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}"
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
[host."http://${reg_name}:5000"]
EOF
done
# 4. Connect the registry to the cluster network if not already connected
# This allows kind to bootstrap the network but ensures they're on the same network
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
docker network connect "kind" "${reg_name}"
fi
# 5. Document the local registry
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry-hosting
namespace: kube-public
data:
localRegistryHosting.v1: |
host: "localhost:${reg_port}"
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ARGOCD_NAMESPACE="argocd"
echo "==> Adding ArgoCD Helm repo..."
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update argo
echo ""
echo "==> Installing ArgoCD into namespace '${ARGOCD_NAMESPACE}'..."
helm upgrade --install argocd argo/argo-cd \
--namespace "${ARGOCD_NAMESPACE}" \
--create-namespace \
--values "${SCRIPT_DIR}/../argocd/values.yaml" \
--timeout 10m \
--wait
echo ""
echo "==> Waiting for ArgoCD server..."
kubectl rollout status deployment/argocd-server -n "${ARGOCD_NAMESPACE}" --timeout=300s
echo ""
echo "==> Logging into ArgoCD CLI..."
ARGOCD_PASSWORD=$(kubectl get secret argocd-initial-admin-secret \
-n "${ARGOCD_NAMESPACE}" \
-o jsonpath="{.data.password}" | base64 -d)
argocd login localhost:30080 \
--username admin \
--password "${ARGOCD_PASSWORD}" \
--insecure
echo ""
echo "==> Applying Overleaf Application..."
kubectl apply -f "${SCRIPT_DIR}/../argocd/application.yaml"
echo ""
echo "ArgoCD is up at http://localhost:30080"
echo " User: admin / Password: ${ARGOCD_PASSWORD}"
echo ""
echo "To watch sync status:"
echo " argocd app get overleaf"
echo " argocd app sync overleaf"
echo ""
echo "Next: run 05-build-push.sh, then sync the app."
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env bash
# Builds overleaf from server-ce/ using podman and pushes all images to Registry
# Requires podman 4.8+ (Buildah 1.32+) for COPY --parents support.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
SERVER_CE="${REPO_ROOT}/server-ce"
REGISTRY="localhost:5001"
PROJECT="overleaf"
PASSWORD="passwordr12345"
TAG="${TAG:-local}"
BASE_IMAGE="${REGISTRY}/${PROJECT}/overleaf-base:${TAG}"
APP_IMAGE="${REGISTRY}/${PROJECT}/overleaf:${TAG}"
echo "==> Logging podman into Registry..."
podman login "${REGISTRY}" \
--username admin \
--password "${PASSWORD}" \
--tls-verify=false
# The Dockerfiles expect the build context to be the repo root.
# server-ce/.dockerignore must be present at the repo root before building.
echo ""
echo "==> Copying .dockerignore to repo root..."
cp "${SERVER_CE}/.dockerignore" "${REPO_ROOT}/.dockerignore"
echo ""
echo "==> Building base image (server-ce/Dockerfile-base)..."
podman build \
--progress=plain \
--file "${SERVER_CE}/Dockerfile-base" \
--tag "${BASE_IMAGE}" \
"${REPO_ROOT}"
echo ""
echo "==> Building app image (server-ce/Dockerfile)..."
podman build \
--progress=plain \
--file "${SERVER_CE}/Dockerfile" \
--build-arg "OVERLEAF_BASE_TAG=${BASE_IMAGE}" \
--tag "${APP_IMAGE}" \
"${REPO_ROOT}"
echo ""
echo "==> Pushing images to Registry..."
podman push "${BASE_IMAGE}" --tls-verify=false
podman push "${APP_IMAGE}" --tls-verify=false
echo ""
echo "==> Mirroring mongo and redis into Local Registry..."
for PAIR in "mongo:8.0" "redis:6.2"; do
DST="${REGISTRY}/${PROJECT}/${PAIR}"
echo " ${PAIR} → ${DST}"
podman pull "${PAIR}"
podman tag "${PAIR}" "${DST}"
podman push "${DST}" --tls-verify=false
done
echo ""
echo "Done. Images in Registry:"
echo " ${BASE_IMAGE}"
echo " ${APP_IMAGE}"
echo " ${REGISTRY}/${PROJECT}/mongo:8.0"
echo " ${REGISTRY}/${PROJECT}/redis:6.2"
echo ""
echo "Update k8s/charts/overleaf/values.yaml if TAG is not 'local', then:"
echo " argocd app sync overleaf"
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
echo "Deleting the overleaf cluster"
kind delete cluster -n overleaf
+5
View File
@@ -0,0 +1,5 @@
apiVersion: v2
name: overleaf
description: Overleaf Community Edition — overleaf, mongo, redis
version: 0.1.0
appVersion: "latest"
@@ -0,0 +1,4 @@
{{- define "overleaf.labels" -}}
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
{{- end }}
@@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-init
labels:
app: mongo
{{- include "overleaf.labels" . | nindent 4 }}
data:
mongodb-init-replica-set.js: |
rs.initiate({ _id: '{{ .Values.mongo.replicaSetName }}', members: [{ _id: 0, host: 'mongo:27017' }] })
@@ -0,0 +1,82 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
labels:
app: mongo
{{- include "overleaf.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app: mongo
strategy:
type: Recreate
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongo
image: "{{ .Values.mongo.image.repository }}:{{ .Values.mongo.image.tag }}"
imagePullPolicy: {{ .Values.mongo.image.pullPolicy }}
command:
- mongod
args:
- --replSet
- {{ .Values.mongo.replicaSetName }}
- --bind_ip_all
env:
- name: MONGO_INITDB_DATABASE
value: overleaf
- name: GLIBC_TUNABLES
value: glibc.pthread.rseq=1
ports:
- containerPort: 27017
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- sleep 60; mongosh overleaf /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
|| true
livenessProbe:
exec:
command:
- /bin/sh
- -c
- "echo 'db.stats().ok' | mongosh localhost:27017/test --quiet"
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 10
failureThreshold: 5
readinessProbe:
exec:
command:
- /bin/sh
- -c
- "echo 'db.stats().ok' | mongosh localhost:27017/test --quiet"
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
volumeMounts:
- name: data
mountPath: /data/db
- name: init-script
mountPath: /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
subPath: mongodb-init-replica-set.js
volumes:
- name: data
persistentVolumeClaim:
claimName: mongo-data
- name: init-script
configMap:
name: mongo-init
hostAliases:
- hostnames:
- mongo
ip: 127.0.0.1
restartPolicy: Always
@@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongo-data
labels:
app: mongo
{{- include "overleaf.labels" . | nindent 4 }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.mongo.persistence.size }}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: mongo
labels:
app: mongo
{{- include "overleaf.labels" . | nindent 4 }}
spec:
selector:
app: mongo
ports:
- name: mongo
port: 27017
targetPort: 27017
@@ -0,0 +1,33 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app: redis
{{- include "overleaf.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app: redis
strategy:
type: Recreate
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}"
imagePullPolicy: {{ .Values.redis.image.pullPolicy }}
ports:
- containerPort: 6379
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-data
restartPolicy: Always
@@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-data
labels:
app: redis
{{- include "overleaf.labels" . | nindent 4 }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.redis.persistence.size }}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: redis
{{- include "overleaf.labels" . | nindent 4 }}
spec:
selector:
app: redis
ports:
- name: redis
port: 6379
targetPort: 6379
@@ -0,0 +1,57 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: overleaf
labels:
app: overleaf
{{- include "overleaf.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app: overleaf
strategy:
type: Recreate
template:
metadata:
labels:
app: overleaf
spec:
containers:
- name: overleaf
image: "{{ .Values.overleaf.image.repository }}:{{ .Values.overleaf.image.tag }}"
imagePullPolicy: {{ .Values.overleaf.image.pullPolicy }}
ports:
- containerPort: 80
env:
{{- range $key, $val := .Values.overleaf.env }}
- name: {{ $key }}
value: {{ $val | quote }}
{{- end }}
resources:
{{- toYaml .Values.overleaf.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: /var/lib/overleaf
readinessProbe:
httpGet:
path: /login
port: 80
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
livenessProbe:
httpGet:
path: /login
port: 80
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: overleaf-data
terminationGracePeriodSeconds: 60
restartPolicy: Always
@@ -0,0 +1,28 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: overleaf
labels:
app: overleaf
{{- include "overleaf.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
- host: {{ .Values.ingress.host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: overleaf
port:
name: http
{{- end }}
@@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: overleaf-data
labels:
app: overleaf
{{- include "overleaf.labels" . | nindent 4 }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.overleaf.persistence.size }}
@@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: overleaf
labels:
app: overleaf
{{- include "overleaf.labels" . | nindent 4 }}
spec:
selector:
app: overleaf
type: {{ .Values.overleaf.service.type }}
ports:
- name: http
port: {{ .Values.overleaf.service.port }}
targetPort: 80
{{- if and (eq .Values.overleaf.service.type "NodePort") .Values.overleaf.service.nodePort }}
nodePort: {{ .Values.overleaf.service.nodePort }}
{{- end }}
+54
View File
@@ -0,0 +1,54 @@
overleaf:
image:
repository: localhost:5001/overleaf/overleaf
tag: local
pullPolicy: Always
persistence:
size: 10Gi
service:
type: NodePort
port: 80
nodePort: 30000
env:
OVERLEAF_APP_NAME: "Overleaf Community Edition"
OVERLEAF_MONGO_URL: "mongodb://mongo/overleaf"
OVERLEAF_REDIS_HOST: redis
REDIS_HOST: redis
ENABLED_LINKED_FILE_TYPES: "project_file,project_output_file"
ENABLE_CONVERSIONS: "true"
EMAIL_CONFIRMATION_DISABLED: "true"
# Sandboxed compiles require Docker sibling containers — not supported in k8s without DinD
SANDBOXED_COMPILES: "false"
DOCKER_RUNNER: "false"
resources:
requests:
memory: 1Gi
cpu: 500m
limits:
memory: 4Gi
cpu: 2000m
mongo:
image:
repository: localhost:5001/overleaf/mongo
tag: "8.0"
pullPolicy: IfNotPresent
persistence:
size: 10Gi
replicaSetName: overleaf
redis:
image:
repository: localhost:5001/overleaf/redis
tag: "6.2"
pullPolicy: IfNotPresent
persistence:
size: 1Gi
persistence:
size: 1Gi
ingress:
enabled: false
className: nginx
host: overleaf.local
annotations: {}
+81
View File
@@ -0,0 +1,81 @@
apiVersion: v1
items:
- apiVersion: v1
data:
ca.crt: |
-----BEGIN CERTIFICATE-----
MIIDBTCCAe2gAwIBAgIICy770MnfOrQwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE
AxMKa3ViZXJuZXRlczAeFw0yNjA1MzEyMTI2NTRaFw0zNjA1MjgyMTMxNTRaMBUx
EzARBgNVBAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCfPa4zkpVWrXryR7J0Uu/sXTeZC4m7MBepTWiiJ48GCICi4rHvFOENBUdo
beNIP3nv9Moyblna787Tobs0qMuTu/Sxpl4riR0+4g8cMsxbcc9p9+8jo4g5sbyE
e+GBl23P2rZWesURQoh67f/l/l28atOHVvvQKKgQ28pZsCJ8v09KPGCvojOICMZV
cgbtpKlV5GYU1fy72Kg1AUeVqXw5nRvNGXI1isMi01aAhSEzNjRpvfbVbk2YYkrJ
eN0TzjD0AQYSGZRkRFtUyOCvT9li797G/oLDvfdVajFFjO4I4UU4eFWvENeMj++D
8jpMSc47rfMzN+KftqBWjtM0RczRAgMBAAGjWTBXMA4GA1UdDwEB/wQEAwICpDAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgtRDcOUxvlZVWm4j7FKRWarWByjAV
BgNVHREEDjAMggprdWJlcm5ldGVzMA0GCSqGSIb3DQEBCwUAA4IBAQCc6faB9Uyv
NDVDDD3TUQncahH5YKCcGKX2b0vw38LV3sJJ4ynRemE0JQPEf27ywJW44hIATFRx
fhG6eUXxkd8VTfeshNt6FzVvexkiMakF6WZg6c0tjfrmncs6lqkb2K9jYMaudk7f
wvYBpX1ckdPkjyBkYMmbpnDEOOE/tu0XkiGn2e/DtU0oEx1ShQFN7iTQmhq0ABFm
aIXzEw2CI9gZJOSLh2Ob6GXH2x/RN0BpFsoj+rnDqh7fOKXRnPLLgX9AUOwNjbqf
AyWERb+6o9gsYrFKMJ58sjM8U8Fx1PUVY89sfAQTRbkfPtQy2ufjHuKBog3inWdU
x5eD6greM+9x
-----END CERTIFICATE-----
kind: ConfigMap
metadata:
annotations:
kubernetes.io/description: Contains a CA bundle that can be used to verify the
kube-apiserver when using internal endpoints such as the internal service
IP or kubernetes.default.svc. No other usage is guaranteed across distributions
of Kubernetes clusters.
creationTimestamp: "2026-05-31T21:33:22Z"
name: kube-root-ca.crt
namespace: overleaf
resourceVersion: "843"
uid: a3eb92ac-b555-4b9d-978d-0b9f165ec031
- apiVersion: v1
data:
mongodb-init-replica-set.js: |
rs.initiate({ _id: 'overleaf', members: [{ _id: 0, host: 'mongo:27017' }] })
kind: ConfigMap
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:/ConfigMap:overleaf/mongo-init
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"mongodb-init-replica-set.js":"rs.initiate({ _id: 'overleaf', members: [{ _id: 0, host: 'mongo:27017' }] })\n"},"kind":"ConfigMap","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:/ConfigMap:overleaf/mongo-init"},"labels":{"app":"mongo","app.kubernetes.io/managed-by":"Helm","helm.sh/chart":"overleaf-0.1.0"},"name":"mongo-init","namespace":"overleaf"}}
creationTimestamp: "2026-05-31T21:33:22Z"
labels:
app: mongo
app.kubernetes.io/managed-by: Helm
helm.sh/chart: overleaf-0.1.0
name: mongo-init
namespace: overleaf
resourceVersion: "845"
uid: e20f7740-ad61-4188-b03f-95593b3107b0
- apiVersion: v1
data:
EMAIL_CONFIRMATION_DISABLED: "true"
EXTERNAL_AUTH: none
OVERLEAF_APP_NAME: kind Overleaf
OVERLEAF_MONGO_URL: mongodb://mongo/overleaf
OVERLEAF_PORT_80_TCP: "30080"
OVERLEAF_PORT_80_TCP_ADDR: "30081"
OVERLEAF_REDIS_HOST: redis
OVERLEAF_SERVICE_HOST: overleaf
REDIS_HOST: redis
REDIS_PORT: "6379"
kind: ConfigMap
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:/ConfigMap:overleaf/overleaf-variables
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"EMAIL_CONFIRMATION_DISABLED":"true","EXTERNAL_AUTH":"none","OVERLEAF_APP_NAME":"kind Overleaf","OVERLEAF_MONGO_URL":"mongodb://mongo/overleaf","OVERLEAF_PORT_80_TCP":"30080","OVERLEAF_PORT_80_TCP_ADDR":"30081","OVERLEAF_REDIS_HOST":"redis","OVERLEAF_SERVICE_HOST":"overleaf","REDIS_HOST":"redis","REDIS_PORT":"6379"},"kind":"ConfigMap","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:/ConfigMap:overleaf/overleaf-variables"},"name":"overleaf-variables","namespace":"overleaf"}}
creationTimestamp: "2026-05-31T21:33:22Z"
name: overleaf-variables
namespace: overleaf
resourceVersion: "846"
uid: 328975dc-fec0-425f-9a8c-2ebf4173730d
kind: List
metadata:
resourceVersion: ""
+335
View File
@@ -0,0 +1,335 @@
apiVersion: v1
items:
- apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:apps/Deployment:overleaf/mongo
deployment.kubernetes.io/revision: "1"
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:apps/Deployment:overleaf/mongo"},"labels":{"app":"mongo","app.kubernetes.io/managed-by":"Helm","helm.sh/chart":"overleaf-0.1.0"},"name":"mongo","namespace":"overleaf"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"mongo"}},"template":{"metadata":{"labels":{"app":"mongo"}},"spec":{"containers":[{"args":["--replSet","overleaf","--bind_ip_all"],"command":["mongod"],"env":[{"name":"MONGO_INITDB_DATABASE","value":"overleaf"},{"name":"GLIBC_TUNABLES","value":"glibc.pthread.rseq=1"}],"image":"localhost:5001/overleaf/mongo:8.0","imagePullPolicy":"IfNotPresent","lifecycle":{"postStart":{"exec":{"command":["/bin/sh","-c","sleep 60; mongosh overleaf /docker-entrypoint-initdb.d/mongodb-init-replica-set.js || true"]}}},"livenessProbe":{"exec":{"command":["/bin/sh","-c","echo 'db.stats().ok' | mongosh localhost:27017/test --quiet"]},"failureThreshold":5,"initialDelaySeconds":30,"periodSeconds":10,"timeoutSeconds":10},"name":"mongo","ports":[{"containerPort":27017}],"readinessProbe":{"exec":{"command":["/bin/sh","-c","echo 'db.stats().ok' | mongosh localhost:27017/test --quiet"]},"failureThreshold":3,"initialDelaySeconds":15,"periodSeconds":10,"timeoutSeconds":5},"volumeMounts":[{"mountPath":"/data/db","name":"data"},{"mountPath":"/docker-entrypoint-initdb.d/mongodb-init-replica-set.js","name":"init-script","subPath":"mongodb-init-replica-set.js"}]}],"hostAliases":[{"hostnames":["mongo"],"ip":"127.0.0.1"}],"restartPolicy":"Always","volumes":[{"name":"data","persistentVolumeClaim":{"claimName":"mongo-data"}},{"configMap":{"name":"mongo-init"},"name":"init-script"}]}}}}
creationTimestamp: "2026-06-01T19:25:07Z"
generation: 1
labels:
app: mongo
app.kubernetes.io/managed-by: Helm
helm.sh/chart: overleaf-0.1.0
name: mongo
namespace: overleaf
resourceVersion: "7490"
uid: c03f67d4-4e98-43e5-8a72-057fe615cf99
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: mongo
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: mongo
spec:
containers:
- args:
- --replSet
- overleaf
- --bind_ip_all
command:
- mongod
env:
- name: MONGO_INITDB_DATABASE
value: overleaf
- name: GLIBC_TUNABLES
value: glibc.pthread.rseq=1
image: localhost:5001/overleaf/mongo:8.0
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- sleep 60; mongosh overleaf /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
|| true
livenessProbe:
exec:
command:
- /bin/sh
- -c
- echo 'db.stats().ok' | mongosh localhost:27017/test --quiet
failureThreshold: 5
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
name: mongo
ports:
- containerPort: 27017
protocol: TCP
readinessProbe:
exec:
command:
- /bin/sh
- -c
- echo 'db.stats().ok' | mongosh localhost:27017/test --quiet
failureThreshold: 3
initialDelaySeconds: 15
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data/db
name: data
- mountPath: /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
name: init-script
subPath: mongodb-init-replica-set.js
dnsPolicy: ClusterFirst
hostAliases:
- hostnames:
- mongo
ip: 127.0.0.1
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: data
persistentVolumeClaim:
claimName: mongo-data
- configMap:
defaultMode: 420
name: mongo-init
name: init-script
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2026-06-01T19:25:07Z"
lastUpdateTime: "2026-06-01T19:26:09Z"
message: ReplicaSet "mongo-84b6dfc9b4" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
- lastTransitionTime: "2026-06-01T19:38:32Z"
lastUpdateTime: "2026-06-01T19:38:32Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
observedGeneration: 1
readyReplicas: 1
replicas: 1
terminatingReplicas: 0
updatedReplicas: 1
- apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:apps/Deployment:overleaf/overleaf
deployment.kubernetes.io/revision: "1"
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:apps/Deployment:overleaf/overleaf"},"labels":{"app":"overleaf","app.kubernetes.io/managed-by":"Helm","helm.sh/chart":"overleaf-0.1.0"},"name":"overleaf","namespace":"overleaf"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"overleaf"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"overleaf"}},"spec":{"containers":[{"env":[{"name":"DOCKER_RUNNER","value":"false"},{"name":"EMAIL_CONFIRMATION_DISABLED","value":"true"},{"name":"EXTERNAL_AUTH","value":"none"},{"name":"OVERLEAF_APP_NAME","value":"Overleaf Community Edition"},{"name":"OVERLEAF_MONGO_URL","value":"mongodb://mongo.overleaf.svc.cluster.local/overleaf"},{"name":"OVERLEAF_REDIS_HOST","value":"redis"},{"name":"REDIS_HOST","value":"redis"},{"name":"REDIS_PORT","value":"tcp://redis:6379"},{"name":"SANDBOXED_COMPILES","value":"false"}],"envFrom":[{"configMapRef":{"name":"overleaf-variables"}}],"image":"localhost:5001/overleaf/overleaf:latest","imagePullPolicy":"Always","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/login","port":80},"initialDelaySeconds":30,"periodSeconds":30,"timeoutSeconds":10},"name":"overleaf","ports":[{"containerPort":80}],"readinessProbe":{"failureThreshold":6,"httpGet":{"path":"/login","port":80},"initialDelaySeconds":30,"periodSeconds":30,"timeoutSeconds":10},"resources":{"limits":{"cpu":"2000m","memory":"4Gi"},"requests":{"cpu":1,"memory":"1Gi"}},"volumeMounts":[{"mountPath":"/var/lib/overleaf","name":"data"}]}],"restartPolicy":"Always","terminationGracePeriodSeconds":60,"volumes":[{"name":"data","persistentVolumeClaim":{"claimName":"overleaf-data"}}]}}}}
creationTimestamp: "2026-05-31T21:33:22Z"
generation: 1
labels:
app: overleaf
app.kubernetes.io/managed-by: Helm
helm.sh/chart: overleaf-0.1.0
name: overleaf
namespace: overleaf
resourceVersion: "7521"
uid: 0c7c1e73-54e4-4cc5-bd25-05ef108e20e9
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: overleaf
strategy:
type: Recreate
template:
metadata:
labels:
app: overleaf
spec:
containers:
- env:
- name: DOCKER_RUNNER
value: "false"
- name: EMAIL_CONFIRMATION_DISABLED
value: "true"
- name: EXTERNAL_AUTH
value: none
- name: OVERLEAF_APP_NAME
value: Overleaf Community Edition
- name: OVERLEAF_MONGO_URL
value: mongodb://mongo.overleaf.svc.cluster.local/overleaf
- name: OVERLEAF_REDIS_HOST
value: redis
- name: REDIS_HOST
value: redis
- name: REDIS_PORT
value: tcp://redis:6379
- name: SANDBOXED_COMPILES
value: "false"
envFrom:
- configMapRef:
name: overleaf-variables
image: localhost:5001/overleaf/overleaf:latest
imagePullPolicy: Always
livenessProbe:
failureThreshold: 5
httpGet:
path: /login
port: 80
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
name: overleaf
ports:
- containerPort: 80
protocol: TCP
readinessProbe:
failureThreshold: 6
httpGet:
path: /login
port: 80
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/overleaf
name: data
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 60
volumes:
- name: data
persistentVolumeClaim:
claimName: overleaf-data
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2026-05-31T21:33:23Z"
lastUpdateTime: "2026-05-31T21:40:32Z"
message: ReplicaSet "overleaf-7f5f6759cb" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
- lastTransitionTime: "2026-06-01T19:38:52Z"
lastUpdateTime: "2026-06-01T19:38:52Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
observedGeneration: 1
readyReplicas: 1
replicas: 1
terminatingReplicas: 0
updatedReplicas: 1
- apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:apps/Deployment:overleaf/redis
deployment.kubernetes.io/revision: "1"
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:apps/Deployment:overleaf/redis"},"labels":{"app":"redis","app.kubernetes.io/managed-by":"Helm","helm.sh/chart":"overleaf-0.1.0"},"name":"redis","namespace":"overleaf"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"redis"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"redis"}},"spec":{"containers":[{"args":["--appendonly","yes"],"command":["redis-server"],"image":"localhost:5001/overleaf/redis:6.2","imagePullPolicy":"IfNotPresent","name":"redis","ports":[{"containerPort":6379}],"volumeMounts":[{"mountPath":"/data","name":"data"}]}],"restartPolicy":"Always","volumes":[{"name":"data","persistentVolumeClaim":{"claimName":"redis-data"}}]}}}}
creationTimestamp: "2026-05-31T21:33:23Z"
generation: 1
labels:
app: redis
app.kubernetes.io/managed-by: Helm
helm.sh/chart: overleaf-0.1.0
name: redis
namespace: overleaf
resourceVersion: "1641"
uid: 75fc2e27-18e6-460b-bd21-2503d3aa7ba8
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: redis
strategy:
type: Recreate
template:
metadata:
labels:
app: redis
spec:
containers:
- args:
- --appendonly
- "yes"
command:
- redis-server
image: localhost:5001/overleaf/redis:6.2
imagePullPolicy: IfNotPresent
name: redis
ports:
- containerPort: 6379
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: data
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-data
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2026-05-31T21:39:08Z"
lastUpdateTime: "2026-05-31T21:39:08Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2026-05-31T21:33:23Z"
lastUpdateTime: "2026-05-31T21:39:08Z"
message: ReplicaSet "redis-6466bbc86f" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 1
replicas: 1
terminatingReplicas: 0
updatedReplicas: 1
kind: List
metadata:
resourceVersion: ""
+700
View File
@@ -0,0 +1,700 @@
apiVersion: v1
items:
- apiVersion: v1
kind: Pod
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:/Pod:overleaf/busybox-sleep
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:/Pod:overleaf/busybox-sleep"},"name":"busybox-sleep","namespace":"overleaf"},"spec":{"containers":[{"args":["sleep","1000000"],"image":"busybox:1.28","name":"busybox"}]}}
creationTimestamp: "2026-05-31T21:33:22Z"
generation: 1
name: busybox-sleep
namespace: overleaf
resourceVersion: "7201"
uid: df2e32e8-99d5-4d14-9387-fe4ad6ba416e
spec:
containers:
- args:
- sleep
- "1000000"
image: busybox:1.28
imagePullPolicy: IfNotPresent
name: busybox
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-b5mjl
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: overleaf-control-plane
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-b5mjl
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:37:30Z"
observedGeneration: 1
status: "True"
type: PodReadyToStartContainers
- lastProbeTime: null
lastTransitionTime: "2026-05-31T21:33:22Z"
observedGeneration: 1
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:37:30Z"
observedGeneration: 1
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:37:30Z"
observedGeneration: 1
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2026-05-31T21:33:22Z"
observedGeneration: 1
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://1142d00a3c5c7f63763ccfcc030b8a35b6eb6656017e3da1c42b24770b31410e
image: docker.io/library/busybox:1.28
imageID: docker.io/library/busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47
lastState:
terminated:
containerID: containerd://dede2119be82664c72d486cdcbaca7e557287ae3f3e04f40bea04c5e532d08fd
exitCode: 255
finishedAt: "2026-06-01T19:37:26Z"
reason: Unknown
startedAt: "2026-06-01T19:32:14Z"
name: busybox
ready: true
resources: {}
restartCount: 3
started: true
state:
running:
startedAt: "2026-06-01T19:37:30Z"
user:
linux:
gid: 0
supplementalGroups:
- 0
- 10
uid: 0
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-b5mjl
readOnly: true
recursiveReadOnly: Disabled
hostIP: 10.89.0.2
hostIPs:
- ip: 10.89.0.2
observedGeneration: 1
phase: Running
podIP: 10.244.0.2
podIPs:
- ip: 10.244.0.2
qosClass: BestEffort
startTime: "2026-05-31T21:33:22Z"
- apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2026-06-01T19:25:07Z"
generateName: mongo-84b6dfc9b4-
generation: 1
labels:
app: mongo
pod-template-hash: 84b6dfc9b4
name: mongo-84b6dfc9b4-9k2j4
namespace: overleaf
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: mongo-84b6dfc9b4
uid: 865ace0d-2a98-4a8a-906d-e61e92138bf6
resourceVersion: "7486"
uid: 2b7a0ac0-aea4-4e78-8a12-f54b9c0df9af
spec:
containers:
- args:
- --replSet
- overleaf
- --bind_ip_all
command:
- mongod
env:
- name: MONGO_INITDB_DATABASE
value: overleaf
- name: GLIBC_TUNABLES
value: glibc.pthread.rseq=1
image: localhost:5001/overleaf/mongo:8.0
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- sleep 60; mongosh overleaf /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
|| true
livenessProbe:
exec:
command:
- /bin/sh
- -c
- echo 'db.stats().ok' | mongosh localhost:27017/test --quiet
failureThreshold: 5
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
name: mongo
ports:
- containerPort: 27017
protocol: TCP
readinessProbe:
exec:
command:
- /bin/sh
- -c
- echo 'db.stats().ok' | mongosh localhost:27017/test --quiet
failureThreshold: 3
initialDelaySeconds: 15
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data/db
name: data
- mountPath: /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
name: init-script
subPath: mongodb-init-replica-set.js
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-ftgfx
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
hostAliases:
- hostnames:
- mongo
ip: 127.0.0.1
nodeName: overleaf-control-plane
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: data
persistentVolumeClaim:
claimName: mongo-data
- configMap:
defaultMode: 420
name: mongo-init
name: init-script
- name: kube-api-access-ftgfx
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:38:31Z"
observedGeneration: 1
status: "True"
type: PodReadyToStartContainers
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:25:07Z"
observedGeneration: 1
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:38:32Z"
observedGeneration: 1
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:38:32Z"
observedGeneration: 1
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:25:07Z"
observedGeneration: 1
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://be4472221c035c897de260c14c164f0201ec0459dbfdafb035c6d622d158b775
image: localhost:5001/overleaf/mongo:8.0
imageID: localhost:5001/overleaf/mongo@sha256:99d4ee4cc1d64439847c5016d4ea12d0e05d900bd773bc75912f199c0bde785a
lastState:
terminated:
containerID: containerd://e9beeca4fe29ead2a3a824d5891d026b675b97e3fdc25ca0d9b971f25b0a93ad
exitCode: 255
finishedAt: "2026-06-01T19:37:26Z"
reason: Unknown
startedAt: "2026-06-01T19:32:14Z"
name: mongo
ready: true
resources: {}
restartCount: 2
started: true
state:
running:
startedAt: "2026-06-01T19:37:30Z"
user:
linux:
gid: 0
supplementalGroups:
- 0
uid: 0
volumeMounts:
- mountPath: /data/db
name: data
- mountPath: /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
name: init-script
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-ftgfx
readOnly: true
recursiveReadOnly: Disabled
hostIP: 10.89.0.2
hostIPs:
- ip: 10.89.0.2
observedGeneration: 1
phase: Running
podIP: 10.244.0.12
podIPs:
- ip: 10.244.0.12
qosClass: BestEffort
startTime: "2026-06-01T19:25:07Z"
- apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2026-06-01T19:27:18Z"
generateName: overleaf-7f5f6759cb-
generation: 1
labels:
app: overleaf
pod-template-hash: 7f5f6759cb
name: overleaf-7f5f6759cb-7f4qz
namespace: overleaf
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: overleaf-7f5f6759cb
uid: 064c6503-7625-4fd5-85e7-2a097d6d38f4
resourceVersion: "7517"
uid: 26f14019-67a2-4912-a711-140871cfa4d0
spec:
containers:
- env:
- name: DOCKER_RUNNER
value: "false"
- name: EMAIL_CONFIRMATION_DISABLED
value: "true"
- name: EXTERNAL_AUTH
value: none
- name: OVERLEAF_APP_NAME
value: Overleaf Community Edition
- name: OVERLEAF_MONGO_URL
value: mongodb://mongo.overleaf.svc.cluster.local/overleaf
- name: OVERLEAF_REDIS_HOST
value: redis
- name: REDIS_HOST
value: redis
- name: REDIS_PORT
value: tcp://redis:6379
- name: SANDBOXED_COMPILES
value: "false"
envFrom:
- configMapRef:
name: overleaf-variables
image: localhost:5001/overleaf/overleaf:latest
imagePullPolicy: Always
livenessProbe:
failureThreshold: 5
httpGet:
path: /login
port: 80
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
name: overleaf
ports:
- containerPort: 80
protocol: TCP
readinessProbe:
failureThreshold: 6
httpGet:
path: /login
port: 80
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/overleaf
name: data
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-vhx2n
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: overleaf-control-plane
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 60
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: data
persistentVolumeClaim:
claimName: overleaf-data
- name: kube-api-access-vhx2n
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:37:30Z"
observedGeneration: 1
status: "True"
type: PodReadyToStartContainers
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:27:18Z"
observedGeneration: 1
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:38:52Z"
observedGeneration: 1
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:38:52Z"
observedGeneration: 1
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:27:18Z"
observedGeneration: 1
status: "True"
type: PodScheduled
containerStatuses:
- allocatedResources:
cpu: "1"
memory: 1Gi
containerID: containerd://78d118381c9dd21fff0a08345ed4195af47969a09db05d3fd2131c791a047131
image: localhost:5001/overleaf/overleaf:latest
imageID: localhost:5001/overleaf/overleaf@sha256:2542ee85e4ef3c4c8c9877c8d81c2631dbfe9906dbac6e76e9ce5be9e6986428
lastState:
terminated:
containerID: containerd://2599d05993c28514ac770e6e5b8508369d55b06b8ebe0b3219c0d356131c23d5
exitCode: 255
finishedAt: "2026-06-01T19:37:26Z"
reason: Unknown
startedAt: "2026-06-01T19:32:35Z"
name: overleaf
ready: true
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 1Gi
restartCount: 2
started: true
state:
running:
startedAt: "2026-06-01T19:37:48Z"
user:
linux:
gid: 0
supplementalGroups:
- 0
uid: 0
volumeMounts:
- mountPath: /var/lib/overleaf
name: data
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-vhx2n
readOnly: true
recursiveReadOnly: Disabled
hostIP: 10.89.0.2
hostIPs:
- ip: 10.89.0.2
observedGeneration: 1
phase: Running
podIP: 10.244.0.14
podIPs:
- ip: 10.244.0.14
qosClass: Burstable
startTime: "2026-06-01T19:27:18Z"
- apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2026-05-31T21:33:23Z"
generateName: redis-6466bbc86f-
generation: 1
labels:
app: redis
pod-template-hash: 6466bbc86f
name: redis-6466bbc86f-bq56t
namespace: overleaf
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: redis-6466bbc86f
uid: 9550c2a5-b898-459a-8b4b-e1cd566cabb4
resourceVersion: "7204"
uid: 18eaf288-7d92-4d1c-91e6-1326b71dff06
spec:
containers:
- args:
- --appendonly
- "yes"
command:
- redis-server
image: localhost:5001/overleaf/redis:6.2
imagePullPolicy: IfNotPresent
name: redis
ports:
- containerPort: 6379
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: data
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-fzvmv
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: overleaf-control-plane
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-data
- name: kube-api-access-fzvmv
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:37:30Z"
observedGeneration: 1
status: "True"
type: PodReadyToStartContainers
- lastProbeTime: null
lastTransitionTime: "2026-05-31T21:33:27Z"
observedGeneration: 1
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:37:30Z"
observedGeneration: 1
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2026-06-01T19:37:30Z"
observedGeneration: 1
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2026-05-31T21:33:27Z"
observedGeneration: 1
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://38ec171e2bdf64aefecdb098417f6dadaca60c4287f04cc13a4ead6b99f412d8
image: localhost:5001/overleaf/redis:6.2
imageID: localhost:5001/overleaf/redis@sha256:c30491f3143c61c179527cc66c8a942b9e1d1f8e75f6d879694bdb15c1553615
lastState:
terminated:
containerID: containerd://3e04166dd203fcbfa17741900610b719719bfe56d053cbcc55ce05fe2a447bbd
exitCode: 255
finishedAt: "2026-06-01T19:37:26Z"
reason: Unknown
startedAt: "2026-06-01T19:32:14Z"
name: redis
ready: true
resources: {}
restartCount: 3
started: true
state:
running:
startedAt: "2026-06-01T19:37:30Z"
user:
linux:
gid: 0
supplementalGroups:
- 0
uid: 0
volumeMounts:
- mountPath: /data
name: data
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-fzvmv
readOnly: true
recursiveReadOnly: Disabled
hostIP: 10.89.0.2
hostIPs:
- ip: 10.89.0.2
observedGeneration: 1
phase: Running
podIP: 10.244.0.15
podIPs:
- ip: 10.244.0.15
qosClass: BestEffort
startTime: "2026-05-31T21:33:27Z"
kind: List
metadata:
resourceVersion: ""
+112
View File
@@ -0,0 +1,112 @@
apiVersion: v1
items:
- apiVersion: v1
kind: Service
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:/Service:overleaf/mongo
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:/Service:overleaf/mongo"},"labels":{"app":"mongo","app.kubernetes.io/managed-by":"Helm","helm.sh/chart":"overleaf-0.1.0"},"name":"mongo","namespace":"overleaf"},"spec":{"ports":[{"name":"mongo","port":27017,"targetPort":27017}],"selector":{"app":"mongo"}}}
creationTimestamp: "2026-05-31T21:33:22Z"
labels:
app: mongo
app.kubernetes.io/managed-by: Helm
helm.sh/chart: overleaf-0.1.0
name: mongo
namespace: overleaf
resourceVersion: "857"
uid: 834cd8be-3d59-40ca-9cc8-b0eab00ec5f8
spec:
clusterIP: 10.96.234.168
clusterIPs:
- 10.96.234.168
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: mongo
port: 27017
protocol: TCP
targetPort: 27017
selector:
app: mongo
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
- apiVersion: v1
kind: Service
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:/Service:overleaf/overleaf
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:/Service:overleaf/overleaf"},"labels":{"app":"overleaf","app.kubernetes.io/managed-by":"Helm","helm.sh/chart":"overleaf-0.1.0"},"name":"overleaf","namespace":"overleaf"},"spec":{"externalTrafficPolicy":"Cluster","internalTrafficPolicy":"Cluster","ports":[{"name":"http","nodePort":30000,"port":80,"targetPort":80}],"selector":{"app":"overleaf"},"type":"NodePort"}}
creationTimestamp: "2026-05-31T21:33:22Z"
labels:
app: overleaf
app.kubernetes.io/managed-by: Helm
helm.sh/chart: overleaf-0.1.0
name: overleaf
namespace: overleaf
resourceVersion: "866"
uid: 25d13b4a-c530-4260-83be-d2896e85a6b7
spec:
clusterIP: 10.96.115.172
clusterIPs:
- 10.96.115.172
externalTrafficPolicy: Cluster
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
nodePort: 30000
port: 80
protocol: TCP
targetPort: 80
selector:
app: overleaf
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
- apiVersion: v1
kind: Service
metadata:
annotations:
argocd.argoproj.io/tracking-id: overleaf:/Service:overleaf/redis
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"argocd.argoproj.io/tracking-id":"overleaf:/Service:overleaf/redis"},"labels":{"app":"redis","app.kubernetes.io/managed-by":"Helm","helm.sh/chart":"overleaf-0.1.0"},"name":"redis","namespace":"overleaf"},"spec":{"ports":[{"name":"redis","port":6379,"targetPort":6379}],"selector":{"app":"redis"}}}
creationTimestamp: "2026-05-31T21:33:22Z"
labels:
app: redis
app.kubernetes.io/managed-by: Helm
helm.sh/chart: overleaf-0.1.0
name: redis
namespace: overleaf
resourceVersion: "861"
uid: bad10e52-6e7a-44f8-9390-d9eef417bef7
spec:
clusterIP: 10.96.194.245
clusterIPs:
- 10.96.194.245
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: redis
port: 6379
protocol: TCP
targetPort: 6379
selector:
app: redis
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
kind: List
metadata:
resourceVersion: ""
+40
View File
@@ -0,0 +1,40 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
#featureGates:
# ValidatingAdmissionPolicy: true
#runtimeConfig:
# admissionregistration.k8s.io/v1beta1: true
nodes:
- role: control-plane
image: kindest/node:v1.35.0@sha256:452d707d4862f52530247495d180205e029056831160e22870e37e3f6c1ac31f
extraPortMappings:
# Harbor HTTP NodePort
- containerPort: 30002
hostPort: 30002
protocol: TCP
# ArgoCD UI NodePort
- containerPort: 30080
hostPort: 30080
protocol: TCP
# Overleaf HTTP NodePort
- containerPort: 30000
hostPort: 30000
protocol: TCP
# Tell containerd to resolve localhost:5001 via the NodePort bound on the node itself.
# kube-proxy binds NodePorts to 0.0.0.0 on the node, so localhost:5001 reaches localhost
# from inside the node without needing cluster DNS.
containerdConfigPatches:
- |-
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
#containerdConfigPatches:
# - |-
# [plugins."io.containerd.grpc.v1.cri".registry]
# [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
# [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5001"]
# endpoint = ["http://localhost:30002"]
# [plugins."io.containerd.grpc.v1.cri".registry.configs]
# [plugins."io.containerd.grpc.v1.cri".registry.configs."localhost:5001".tls]
# insecure_skip_verify = true
# [plugins."io.containerd.grpc.v1.cri".registry.configs."localhost:5001".tls]
# insecure_skip_verify = true
+11 -4
View File
@@ -18,14 +18,22 @@ COPY server-ce/genScript.js server-ce/services.js /overleaf/
# Corepack setup, shared between all the images.
ENV PATH="/overleaf/node_modules/.bin:$PATH"
ENV COREPACK_HOME=/opt/corepack
RUN corepack enable && corepack install -g yarn@4.14.1
RUN corepack enable && corepack prepare yarn@4.14.1 --activate
#RUN corepack enable && corepack prepare yarn --activate
ENV COREPACK_ENABLE_NETWORK=0
# RUN npm install node-fetch
# RUN yarn add node-fetch
# RUN yarn install
#RUN --mount=type=cache,target=/root/.cache \
# --mount=type=cache,target=/root/.yarn/berry/cache,id=server-ce-yarn-cache \
# --mount=type=tmpfs,target=/tmp yarn install | bash
# Install yarn dependencies
# -------------------------
RUN --mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/root/.yarn/berry/cache,id=server-ce-yarn-cache \
--mount=type=cache,target=/usr/local/share/.cache/yarn,id=server-ce-yarn-fallback-cache \
--mount=type=tmpfs,target=/tmp node genScript install | bash
# Add the actual source files
@@ -33,10 +41,9 @@ RUN --mount=type=cache,target=/root/.cache \
COPY --parents libraries/ services/ tools/migrations/ /overleaf/
RUN --mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/root/.yarn/berry/cache,id=server-ce-yarn-cache \
--mount=type=cache,target=/usr/local/share/.cache/yarn,id=server-ce-yarn-fallback-cache \
--mount=type=cache,target=/overleaf/services/web/node_modules/.cache,id=server-ce-webpack-cache \
--mount=type=tmpfs,target=/tmp \
node genScript compile | bash
YARN_CACHE_FOLDER=/tmp/.yarn-cache node genScript compile | bash
# Copy runit service startup scripts to its location
# --------------------------------------------------
+2 -2
View File
@@ -2,7 +2,7 @@
# Overleaf Base Image (sharelatex/sharelatex-base)
# --------------------------------------------------
FROM phusion/baseimage:noble-1.0.3
FROM phusion/baseimage:noble-1.0.2
# Makes sure LuaTex cache is writable
# -----------------------------------
@@ -10,7 +10,7 @@ ENV TEXMFVAR=/var/lib/overleaf/tmp/texmf-var
# Update to ensure dependencies are updated
# ------------------------------------------
ENV REBUILT_AFTER="2026-05-21"
ENV REBUILT_AFTER="2026-01-13"
# Install dependencies
# --------------------
@@ -1,78 +0,0 @@
#!/bin/bash
set -e
POTENTIAL_OLD_PATHS="
/etc/sharelatex
/var/lib/sharelatex
/var/log/sharelatex
"
OLD_ITEMS=""
for path in ${POTENTIAL_OLD_PATHS}; do
if [[ -e "$path" ]]; then
OLD_ITEMS="$OLD_ITEMS $path"
fi
done
if [[ "$OLD_ITEMS" == "" ]]; then
exit 0
fi
OLD_ITEMS=$(echo "$OLD_ITEMS" | xargs -n1 | sed 's/^/ - /')
N=$(echo "$OLD_ITEMS" | wc -l)
cat <<EOF
------------------------------------------------------------------------
ShareLaTeX to Overleaf rebranding
---------------------------------
Starting with version 5.0, ShareLaTeX branded file system paths are no
longer supported as we are migrating to the Overleaf brand.
Your configuration still uses $N ShareLaTeX branded paths:
$OLD_ITEMS
Please update the in-container bind-mount target to refer to the
Overleaf equivalent:
- /etc/sharelatex -> /etc/overleaf
- /var/lib/sharelatex -> /var/lib/overleaf
- /var/log/sharelatex -> /var/log/overleaf
Overleaf toolkit setups:
github.com/overleaf/toolkit$ bin/upgrade
Legacy docker compose setups/Horizontal scaling setups:
before:
services:
sharelatex:
volumes:
- /my/docker-host/path:/var/lib/sharelatex
after:
services:
sharelatex:
volumes:
- /my/docker-host/path:/var/lib/overleaf
Other deployment methods:
Adapt the docker compose example or get in touch with support.
Server Pro: Please update SANDBOXED_COMPILES_HOST_DIR if needed.
Refusing to startup, exiting in 10s.
------------------------------------------------------------------------
EOF
sleep 10
exit 101
@@ -1,56 +0,0 @@
#!/bin/bash
set -e
OLD_ITEMS=$(env | cut -d '=' -f1 | grep SHARELATEX | sed 's/^/ - /')
if [[ "$OLD_ITEMS" == "" ]]; then
exit 0
fi
N=$(echo "$OLD_ITEMS" | wc -l)
cat <<EOF
------------------------------------------------------------------------
ShareLaTeX to Overleaf rebranding
---------------------------------
Starting with version 5.0, ShareLaTeX branded variables are no
longer supported as we are migrating to the Overleaf brand.
Your configuration still uses $N ShareLaTeX environment variables:
$OLD_ITEMS
Please either replace them with the "OVERLEAF_" prefix,
e.g. SHARELATEX_MONGO_URL -> OVERLEAF_MONGO_URL, or
remove old entries from your configuration.
You can use the following script for migrating your config.
Overleaf toolkit setups:
github.com/overleaf/toolkit$ bin/upgrade
github.com/overleaf/toolkit$ bin/rename-env-vars-5-0.sh
Legacy docker compose setups/Horizontal scaling setups:
github.com/overleaf/overleaf$ git pull
github.com/overleaf/overleaf$ server-ce/bin/rename-env-vars-5-0.sh
# When using a docker-compose.override.yml file (or other file name):
github.com/overleaf/overleaf$ server-ce/bin/rename-env-vars-5-0.sh docker-compose.override.yml
Other deployment methods:
Try using the docker compose script or get in touch with support.
Refusing to startup, exiting in 10s.
------------------------------------------------------------------------
EOF
sleep 10
exit 101