From 1367ddeb60893414b07f444299f803485f576a82 Mon Sep 17 00:00:00 2001 From: Tim Gibbon Date: Tue, 2 Jun 2026 19:28:36 +0100 Subject: [PATCH 1/4] Add sample kind setup --- docker-compose.debug.yml | 2 +- docker-compose.yml | 18 +- k8s/README.md | 181 +++++ k8s/argocd/application.yaml | 24 + k8s/argocd/values.yaml | 9 + k8s/bootstrap/01-prereqs.sh | 37 + k8s/bootstrap/02-cluster.sh | 26 + k8s/bootstrap/03-local-registry.sh | 58 ++ k8s/bootstrap/04-argocd.sh | 47 ++ k8s/bootstrap/05-build-push.sh | 70 ++ k8s/bootstrap/06-teardown.sh | 4 + k8s/charts/overleaf/Chart.yaml | 5 + k8s/charts/overleaf/templates/_helpers.tpl | 4 + .../overleaf/templates/mongo-configmap.yaml | 10 + .../overleaf/templates/mongo-deployment.yaml | 82 ++ k8s/charts/overleaf/templates/mongo-pvc.yaml | 13 + .../overleaf/templates/mongo-service.yaml | 14 + .../overleaf/templates/redis-deployment.yaml | 33 + k8s/charts/overleaf/templates/redis-pvc.yaml | 13 + .../overleaf/templates/redis-service.yaml | 14 + .../templates/sharelatex-deployment.yaml | 57 ++ .../templates/sharelatex-ingress.yaml | 28 + .../overleaf/templates/sharelatex-pvc.yaml | 13 + .../templates/sharelatex-service.yaml | 18 + k8s/charts/overleaf/values.yaml | 54 ++ k8s/copies/cm.yml | 81 ++ k8s/copies/dep.yml | 335 +++++++++ k8s/copies/pods.yml | 700 ++++++++++++++++++ k8s/copies/svcs.yml | 112 +++ k8s/kind/cluster.yaml | 40 + server-ce/Dockerfile | 15 +- server-ce/Dockerfile-base | 4 +- .../000_check_for_old_bind_mounts_5.sh | 78 -- .../000_check_for_old_env_vars_5.sh | 56 -- 34 files changed, 2105 insertions(+), 150 deletions(-) create mode 100644 k8s/README.md create mode 100644 k8s/argocd/application.yaml create mode 100644 k8s/argocd/values.yaml create mode 100755 k8s/bootstrap/01-prereqs.sh create mode 100755 k8s/bootstrap/02-cluster.sh create mode 100755 k8s/bootstrap/03-local-registry.sh create mode 100755 k8s/bootstrap/04-argocd.sh create mode 100755 k8s/bootstrap/05-build-push.sh create mode 100755 k8s/bootstrap/06-teardown.sh create mode 100644 k8s/charts/overleaf/Chart.yaml create mode 100644 k8s/charts/overleaf/templates/_helpers.tpl create mode 100644 k8s/charts/overleaf/templates/mongo-configmap.yaml create mode 100644 k8s/charts/overleaf/templates/mongo-deployment.yaml create mode 100644 k8s/charts/overleaf/templates/mongo-pvc.yaml create mode 100644 k8s/charts/overleaf/templates/mongo-service.yaml create mode 100644 k8s/charts/overleaf/templates/redis-deployment.yaml create mode 100644 k8s/charts/overleaf/templates/redis-pvc.yaml create mode 100644 k8s/charts/overleaf/templates/redis-service.yaml create mode 100644 k8s/charts/overleaf/templates/sharelatex-deployment.yaml create mode 100644 k8s/charts/overleaf/templates/sharelatex-ingress.yaml create mode 100644 k8s/charts/overleaf/templates/sharelatex-pvc.yaml create mode 100644 k8s/charts/overleaf/templates/sharelatex-service.yaml create mode 100644 k8s/charts/overleaf/values.yaml create mode 100644 k8s/copies/cm.yml create mode 100644 k8s/copies/dep.yml create mode 100644 k8s/copies/pods.yml create mode 100644 k8s/copies/svcs.yml create mode 100644 k8s/kind/cluster.yaml delete mode 100755 server-ce/init_scripts/000_check_for_old_bind_mounts_5.sh delete mode 100755 server-ce/init_scripts/000_check_for_old_env_vars_5.sh diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index b6530df019..74d0848a6b 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -1,6 +1,6 @@ version: "2.2" services: - sharelatex: + overleaf: ports: - 30000:30000 - 30150:30150 diff --git a/docker-compose.yml b/docker-compose.yml index fc2c01fa71..8118701e60 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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. diff --git a/k8s/README.md b/k8s/README.md new file mode 100644 index 0000000000..e1709f9c79 --- /dev/null +++ b/k8s/README.md @@ -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. diff --git a/k8s/argocd/application.yaml b/k8s/argocd/application.yaml new file mode 100644 index 0000000000..213d3a98d6 --- /dev/null +++ b/k8s/argocd/application.yaml @@ -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 diff --git a/k8s/argocd/values.yaml b/k8s/argocd/values.yaml new file mode 100644 index 0000000000..5133c2287d --- /dev/null +++ b/k8s/argocd/values.yaml @@ -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" diff --git a/k8s/bootstrap/01-prereqs.sh b/k8s/bootstrap/01-prereqs.sh new file mode 100755 index 0000000000..8e68d57c49 --- /dev/null +++ b/k8s/bootstrap/01-prereqs.sh @@ -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." diff --git a/k8s/bootstrap/02-cluster.sh b/k8s/bootstrap/02-cluster.sh new file mode 100755 index 0000000000..8f28854397 --- /dev/null +++ b/k8s/bootstrap/02-cluster.sh @@ -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" diff --git a/k8s/bootstrap/03-local-registry.sh b/k8s/bootstrap/03-local-registry.sh new file mode 100755 index 0000000000..713867402d --- /dev/null +++ b/k8s/bootstrap/03-local-registry.sh @@ -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 < 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." diff --git a/k8s/bootstrap/05-build-push.sh b/k8s/bootstrap/05-build-push.sh new file mode 100755 index 0000000000..4cef7e1938 --- /dev/null +++ b/k8s/bootstrap/05-build-push.sh @@ -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" diff --git a/k8s/bootstrap/06-teardown.sh b/k8s/bootstrap/06-teardown.sh new file mode 100755 index 0000000000..a42444cdc4 --- /dev/null +++ b/k8s/bootstrap/06-teardown.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +echo "Deleting the overleaf cluster" +kind delete cluster -n overleaf diff --git a/k8s/charts/overleaf/Chart.yaml b/k8s/charts/overleaf/Chart.yaml new file mode 100644 index 0000000000..09d805d58d --- /dev/null +++ b/k8s/charts/overleaf/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: overleaf +description: Overleaf Community Edition — overleaf, mongo, redis +version: 0.1.0 +appVersion: "latest" diff --git a/k8s/charts/overleaf/templates/_helpers.tpl b/k8s/charts/overleaf/templates/_helpers.tpl new file mode 100644 index 0000000000..062f1a92d3 --- /dev/null +++ b/k8s/charts/overleaf/templates/_helpers.tpl @@ -0,0 +1,4 @@ +{{- define "overleaf.labels" -}} +app.kubernetes.io/managed-by: {{ .Release.Service }} +helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }} +{{- end }} diff --git a/k8s/charts/overleaf/templates/mongo-configmap.yaml b/k8s/charts/overleaf/templates/mongo-configmap.yaml new file mode 100644 index 0000000000..ef28871536 --- /dev/null +++ b/k8s/charts/overleaf/templates/mongo-configmap.yaml @@ -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' }] }) diff --git a/k8s/charts/overleaf/templates/mongo-deployment.yaml b/k8s/charts/overleaf/templates/mongo-deployment.yaml new file mode 100644 index 0000000000..65ba718c27 --- /dev/null +++ b/k8s/charts/overleaf/templates/mongo-deployment.yaml @@ -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 diff --git a/k8s/charts/overleaf/templates/mongo-pvc.yaml b/k8s/charts/overleaf/templates/mongo-pvc.yaml new file mode 100644 index 0000000000..e23da8b4cd --- /dev/null +++ b/k8s/charts/overleaf/templates/mongo-pvc.yaml @@ -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 }} diff --git a/k8s/charts/overleaf/templates/mongo-service.yaml b/k8s/charts/overleaf/templates/mongo-service.yaml new file mode 100644 index 0000000000..5797dd07da --- /dev/null +++ b/k8s/charts/overleaf/templates/mongo-service.yaml @@ -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 diff --git a/k8s/charts/overleaf/templates/redis-deployment.yaml b/k8s/charts/overleaf/templates/redis-deployment.yaml new file mode 100644 index 0000000000..a6b88d3b10 --- /dev/null +++ b/k8s/charts/overleaf/templates/redis-deployment.yaml @@ -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 diff --git a/k8s/charts/overleaf/templates/redis-pvc.yaml b/k8s/charts/overleaf/templates/redis-pvc.yaml new file mode 100644 index 0000000000..ac5a5ec97d --- /dev/null +++ b/k8s/charts/overleaf/templates/redis-pvc.yaml @@ -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 }} diff --git a/k8s/charts/overleaf/templates/redis-service.yaml b/k8s/charts/overleaf/templates/redis-service.yaml new file mode 100644 index 0000000000..b99a35bfef --- /dev/null +++ b/k8s/charts/overleaf/templates/redis-service.yaml @@ -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 diff --git a/k8s/charts/overleaf/templates/sharelatex-deployment.yaml b/k8s/charts/overleaf/templates/sharelatex-deployment.yaml new file mode 100644 index 0000000000..da3830d113 --- /dev/null +++ b/k8s/charts/overleaf/templates/sharelatex-deployment.yaml @@ -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 diff --git a/k8s/charts/overleaf/templates/sharelatex-ingress.yaml b/k8s/charts/overleaf/templates/sharelatex-ingress.yaml new file mode 100644 index 0000000000..b3f4c85715 --- /dev/null +++ b/k8s/charts/overleaf/templates/sharelatex-ingress.yaml @@ -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 }} diff --git a/k8s/charts/overleaf/templates/sharelatex-pvc.yaml b/k8s/charts/overleaf/templates/sharelatex-pvc.yaml new file mode 100644 index 0000000000..b772e1d7fd --- /dev/null +++ b/k8s/charts/overleaf/templates/sharelatex-pvc.yaml @@ -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 }} diff --git a/k8s/charts/overleaf/templates/sharelatex-service.yaml b/k8s/charts/overleaf/templates/sharelatex-service.yaml new file mode 100644 index 0000000000..da443fed48 --- /dev/null +++ b/k8s/charts/overleaf/templates/sharelatex-service.yaml @@ -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 }} diff --git a/k8s/charts/overleaf/values.yaml b/k8s/charts/overleaf/values.yaml new file mode 100644 index 0000000000..4898cdf8ba --- /dev/null +++ b/k8s/charts/overleaf/values.yaml @@ -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: {} diff --git a/k8s/copies/cm.yml b/k8s/copies/cm.yml new file mode 100644 index 0000000000..f6f8dabb51 --- /dev/null +++ b/k8s/copies/cm.yml @@ -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: "" diff --git a/k8s/copies/dep.yml b/k8s/copies/dep.yml new file mode 100644 index 0000000000..a3beff9e3e --- /dev/null +++ b/k8s/copies/dep.yml @@ -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: "" diff --git a/k8s/copies/pods.yml b/k8s/copies/pods.yml new file mode 100644 index 0000000000..d1410eb5e4 --- /dev/null +++ b/k8s/copies/pods.yml @@ -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: "" diff --git a/k8s/copies/svcs.yml b/k8s/copies/svcs.yml new file mode 100644 index 0000000000..ba740e5cdb --- /dev/null +++ b/k8s/copies/svcs.yml @@ -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: "" diff --git a/k8s/kind/cluster.yaml b/k8s/kind/cluster.yaml new file mode 100644 index 0000000000..b4596e386e --- /dev/null +++ b/k8s/kind/cluster.yaml @@ -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 diff --git a/server-ce/Dockerfile b/server-ce/Dockerfile index b76f50c15f..7d702c9659 100644 --- a/server-ce/Dockerfile +++ b/server-ce/Dockerfile @@ -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 # -------------------------------------------------- diff --git a/server-ce/Dockerfile-base b/server-ce/Dockerfile-base index 1677469009..5b6912fd89 100644 --- a/server-ce/Dockerfile-base +++ b/server-ce/Dockerfile-base @@ -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 # -------------------- diff --git a/server-ce/init_scripts/000_check_for_old_bind_mounts_5.sh b/server-ce/init_scripts/000_check_for_old_bind_mounts_5.sh deleted file mode 100755 index 6c501c78f3..0000000000 --- a/server-ce/init_scripts/000_check_for_old_bind_mounts_5.sh +++ /dev/null @@ -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 < /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 diff --git a/server-ce/init_scripts/000_check_for_old_env_vars_5.sh b/server-ce/init_scripts/000_check_for_old_env_vars_5.sh deleted file mode 100755 index 2beb008d90..0000000000 --- a/server-ce/init_scripts/000_check_for_old_env_vars_5.sh +++ /dev/null @@ -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 < 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 From fe01e7787ffa1b0269de0bfefcb3c7cf940a17a1 Mon Sep 17 00:00:00 2001 From: Tim Gibbon Date: Tue, 2 Jun 2026 19:36:49 +0100 Subject: [PATCH 2/4] Remove WIP pod copies --- k8s/copies/cm.yml | 81 ----- k8s/copies/dep.yml | 335 --------------------- k8s/copies/pods.yml | 700 -------------------------------------------- k8s/copies/svcs.yml | 112 ------- 4 files changed, 1228 deletions(-) delete mode 100644 k8s/copies/cm.yml delete mode 100644 k8s/copies/dep.yml delete mode 100644 k8s/copies/pods.yml delete mode 100644 k8s/copies/svcs.yml diff --git a/k8s/copies/cm.yml b/k8s/copies/cm.yml deleted file mode 100644 index f6f8dabb51..0000000000 --- a/k8s/copies/cm.yml +++ /dev/null @@ -1,81 +0,0 @@ -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: "" diff --git a/k8s/copies/dep.yml b/k8s/copies/dep.yml deleted file mode 100644 index a3beff9e3e..0000000000 --- a/k8s/copies/dep.yml +++ /dev/null @@ -1,335 +0,0 @@ -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: "" diff --git a/k8s/copies/pods.yml b/k8s/copies/pods.yml deleted file mode 100644 index d1410eb5e4..0000000000 --- a/k8s/copies/pods.yml +++ /dev/null @@ -1,700 +0,0 @@ -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: "" diff --git a/k8s/copies/svcs.yml b/k8s/copies/svcs.yml deleted file mode 100644 index ba740e5cdb..0000000000 --- a/k8s/copies/svcs.yml +++ /dev/null @@ -1,112 +0,0 @@ -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: "" From 632c61d8429bc6f759bc06e147046272267b18ef Mon Sep 17 00:00:00 2001 From: Tim Gibbon Date: Tue, 2 Jun 2026 19:42:06 +0100 Subject: [PATCH 3/4] Point to my branch --- k8s/argocd/application.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8s/argocd/application.yaml b/k8s/argocd/application.yaml index 213d3a98d6..145b05012d 100644 --- a/k8s/argocd/application.yaml +++ b/k8s/argocd/application.yaml @@ -7,7 +7,7 @@ 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 + repoURL: https://github.com/tommybobbins/overleaf.git targetRevision: HEAD path: k8s/charts/overleaf helm: From 60d2dc25ab9eca6ba3737c3d7860917642d15a9c Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 7 Jul 2026 02:06:08 +1000 Subject: [PATCH 4/4] Add \proof environment to autocomplete list amsthm's \proof environment wasn't in the built-in environment completions, so it only appeared in the autocomplete dropdown after being typed several times elsewhere in the document. --- .../languages/latex/completions/data/environments.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/frontend/js/features/source-editor/languages/latex/completions/data/environments.ts b/services/web/frontend/js/features/source-editor/languages/latex/completions/data/environments.ts index df82a3a315..29414313d9 100644 --- a/services/web/frontend/js/features/source-editor/languages/latex/completions/data/environments.ts +++ b/services/web/frontend/js/features/source-editor/languages/latex/completions/data/environments.ts @@ -58,6 +58,7 @@ export const environments = new Map([ ], ['multline', snippet('multline')], ['multline*', snippet('multline*')], + ['proof', snippet('proof')], ['quote', snippet('quote')], ['split', snippet('split')], [