mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 21:23:45 +01:00
Merge branch 'main' into main
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
version: "2.2"
|
||||
services:
|
||||
sharelatex:
|
||||
overleaf:
|
||||
ports:
|
||||
- 30000:30000
|
||||
- 30150:30150
|
||||
|
||||
+9
-9
@@ -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
|
||||
@@ -81,9 +81,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"
|
||||
@@ -113,7 +113,7 @@ services:
|
||||
- ~/mongo_data:/data/db
|
||||
- ./bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
|
||||
environment:
|
||||
MONGO_INITDB_DATABASE: sharelatex
|
||||
MONGO_INITDB_DATABASE: overleaf
|
||||
extra_hosts:
|
||||
# Required when using the automatic database setup for initializing the replica set.
|
||||
# This override is not needed when running the setup after starting up mongo.
|
||||
|
||||
+181
@@ -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.
|
||||
@@ -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/tommybobbins/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
|
||||
@@ -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"
|
||||
Executable
+37
@@ -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."
|
||||
Executable
+26
@@ -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"
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
set -o errexit
|
||||
|
||||
# 1. Create registry container unless it already exists
|
||||
reg_name='kind-registry'
|
||||
reg_port='5001'
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
|
||||
docker run \
|
||||
-d --restart=always -p "127.0.0.1:${reg_port}:5000" --network bridge --name "${reg_name}" \
|
||||
registry:3
|
||||
fi
|
||||
|
||||
# 2. Create kind cluster with containerd registry config dir enabled
|
||||
#
|
||||
# NOTE: the containerd config patch is not necessary with images from kind v0.27.0+
|
||||
# It may enable some older images to work similarly.
|
||||
# If you're only supporting newer relases, you can just use `kind create cluster` here.
|
||||
#
|
||||
# See:
|
||||
# https://github.com/kubernetes-sigs/kind/issues/2875
|
||||
# https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration
|
||||
# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
|
||||
# 3. Add the registry config to the nodes
|
||||
#
|
||||
# This is necessary because localhost resolves to loopback addresses that are
|
||||
# network-namespace local.
|
||||
# In other words: localhost in the container is not localhost on the host.
|
||||
#
|
||||
# We want a consistent name that works from both ends, so we tell containerd to
|
||||
# alias localhost:${reg_port} to the registry container when pulling images
|
||||
REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}"
|
||||
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
|
||||
docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
|
||||
cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
|
||||
[host."http://${reg_name}:5000"]
|
||||
EOF
|
||||
done
|
||||
|
||||
# 4. Connect the registry to the cluster network if not already connected
|
||||
# This allows kind to bootstrap the network but ensures they're on the same network
|
||||
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
|
||||
docker network connect "kind" "${reg_name}"
|
||||
fi
|
||||
|
||||
# 5. Document the local registry
|
||||
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
|
||||
cat <<EOF | kubectl apply -f -
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: local-registry-hosting
|
||||
namespace: kube-public
|
||||
data:
|
||||
localRegistryHosting.v1: |
|
||||
host: "localhost:${reg_port}"
|
||||
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
|
||||
EOF
|
||||
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ARGOCD_NAMESPACE="argocd"
|
||||
|
||||
echo "==> Adding ArgoCD Helm repo..."
|
||||
helm repo add argo https://argoproj.github.io/argo-helm
|
||||
helm repo update argo
|
||||
|
||||
echo ""
|
||||
echo "==> Installing ArgoCD into namespace '${ARGOCD_NAMESPACE}'..."
|
||||
helm upgrade --install argocd argo/argo-cd \
|
||||
--namespace "${ARGOCD_NAMESPACE}" \
|
||||
--create-namespace \
|
||||
--values "${SCRIPT_DIR}/../argocd/values.yaml" \
|
||||
--timeout 10m \
|
||||
--wait
|
||||
|
||||
echo ""
|
||||
echo "==> Waiting for ArgoCD server..."
|
||||
kubectl rollout status deployment/argocd-server -n "${ARGOCD_NAMESPACE}" --timeout=300s
|
||||
|
||||
echo ""
|
||||
echo "==> Logging into ArgoCD CLI..."
|
||||
ARGOCD_PASSWORD=$(kubectl get secret argocd-initial-admin-secret \
|
||||
-n "${ARGOCD_NAMESPACE}" \
|
||||
-o jsonpath="{.data.password}" | base64 -d)
|
||||
|
||||
argocd login localhost:30080 \
|
||||
--username admin \
|
||||
--password "${ARGOCD_PASSWORD}" \
|
||||
--insecure
|
||||
|
||||
echo ""
|
||||
echo "==> Applying Overleaf Application..."
|
||||
kubectl apply -f "${SCRIPT_DIR}/../argocd/application.yaml"
|
||||
|
||||
echo ""
|
||||
echo "ArgoCD is up at http://localhost:30080"
|
||||
echo " User: admin / Password: ${ARGOCD_PASSWORD}"
|
||||
echo ""
|
||||
echo "To watch sync status:"
|
||||
echo " argocd app get overleaf"
|
||||
echo " argocd app sync overleaf"
|
||||
echo ""
|
||||
echo "Next: run 05-build-push.sh, then sync the app."
|
||||
Executable
+70
@@ -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"
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Deleting the overleaf cluster"
|
||||
kind delete cluster -n overleaf
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: v2
|
||||
name: overleaf
|
||||
description: Overleaf Community Edition — overleaf, mongo, redis
|
||||
version: 0.1.0
|
||||
appVersion: "latest"
|
||||
@@ -0,0 +1,4 @@
|
||||
{{- define "overleaf.labels" -}}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mongo-init
|
||||
labels:
|
||||
app: mongo
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
data:
|
||||
mongodb-init-replica-set.js: |
|
||||
rs.initiate({ _id: '{{ .Values.mongo.replicaSetName }}', members: [{ _id: 0, host: 'mongo:27017' }] })
|
||||
@@ -0,0 +1,82 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mongo
|
||||
labels:
|
||||
app: mongo
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mongo
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mongo
|
||||
spec:
|
||||
containers:
|
||||
- name: mongo
|
||||
image: "{{ .Values.mongo.image.repository }}:{{ .Values.mongo.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.mongo.image.pullPolicy }}
|
||||
command:
|
||||
- mongod
|
||||
args:
|
||||
- --replSet
|
||||
- {{ .Values.mongo.replicaSetName }}
|
||||
- --bind_ip_all
|
||||
env:
|
||||
- name: MONGO_INITDB_DATABASE
|
||||
value: overleaf
|
||||
- name: GLIBC_TUNABLES
|
||||
value: glibc.pthread.rseq=1
|
||||
ports:
|
||||
- containerPort: 27017
|
||||
lifecycle:
|
||||
postStart:
|
||||
exec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- sleep 60; mongosh overleaf /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
|
||||
|| true
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- "echo 'db.stats().ok' | mongosh localhost:27017/test --quiet"
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 10
|
||||
failureThreshold: 5
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- "echo 'db.stats().ok' | mongosh localhost:27017/test --quiet"
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data/db
|
||||
- name: init-script
|
||||
mountPath: /docker-entrypoint-initdb.d/mongodb-init-replica-set.js
|
||||
subPath: mongodb-init-replica-set.js
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: mongo-data
|
||||
- name: init-script
|
||||
configMap:
|
||||
name: mongo-init
|
||||
hostAliases:
|
||||
- hostnames:
|
||||
- mongo
|
||||
ip: 127.0.0.1
|
||||
restartPolicy: Always
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mongo-data
|
||||
labels:
|
||||
app: mongo
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.mongo.persistence.size }}
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mongo
|
||||
labels:
|
||||
app: mongo
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
app: mongo
|
||||
ports:
|
||||
- name: mongo
|
||||
port: 27017
|
||||
targetPort: 27017
|
||||
@@ -0,0 +1,33 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis
|
||||
labels:
|
||||
app: redis
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.redis.image.pullPolicy }}
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: redis-data
|
||||
restartPolicy: Always
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: redis-data
|
||||
labels:
|
||||
app: redis
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.redis.persistence.size }}
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis
|
||||
labels:
|
||||
app: redis
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
app: redis
|
||||
ports:
|
||||
- name: redis
|
||||
port: 6379
|
||||
targetPort: 6379
|
||||
@@ -0,0 +1,57 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: overleaf
|
||||
labels:
|
||||
app: overleaf
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: overleaf
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: overleaf
|
||||
spec:
|
||||
containers:
|
||||
- name: overleaf
|
||||
image: "{{ .Values.overleaf.image.repository }}:{{ .Values.overleaf.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.overleaf.image.pullPolicy }}
|
||||
ports:
|
||||
- containerPort: 80
|
||||
env:
|
||||
{{- range $key, $val := .Values.overleaf.env }}
|
||||
- name: {{ $key }}
|
||||
value: {{ $val | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.overleaf.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/overleaf
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /login
|
||||
port: 80
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /login
|
||||
port: 80
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 10
|
||||
failureThreshold: 5
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: overleaf-data
|
||||
terminationGracePeriodSeconds: 60
|
||||
restartPolicy: Always
|
||||
@@ -0,0 +1,28 @@
|
||||
{{- if .Values.ingress.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: overleaf
|
||||
labels:
|
||||
app: overleaf
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.host }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: overleaf
|
||||
port:
|
||||
name: http
|
||||
{{- end }}
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: overleaf-data
|
||||
labels:
|
||||
app: overleaf
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.overleaf.persistence.size }}
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: overleaf
|
||||
labels:
|
||||
app: overleaf
|
||||
{{- include "overleaf.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
app: overleaf
|
||||
type: {{ .Values.overleaf.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.overleaf.service.port }}
|
||||
targetPort: 80
|
||||
{{- if and (eq .Values.overleaf.service.type "NodePort") .Values.overleaf.service.nodePort }}
|
||||
nodePort: {{ .Values.overleaf.service.nodePort }}
|
||||
{{- end }}
|
||||
@@ -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: {}
|
||||
@@ -0,0 +1,40 @@
|
||||
kind: Cluster
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
#featureGates:
|
||||
# ValidatingAdmissionPolicy: true
|
||||
#runtimeConfig:
|
||||
# admissionregistration.k8s.io/v1beta1: true
|
||||
nodes:
|
||||
- role: control-plane
|
||||
image: kindest/node:v1.35.0@sha256:452d707d4862f52530247495d180205e029056831160e22870e37e3f6c1ac31f
|
||||
extraPortMappings:
|
||||
# Harbor HTTP NodePort
|
||||
- containerPort: 30002
|
||||
hostPort: 30002
|
||||
protocol: TCP
|
||||
# ArgoCD UI NodePort
|
||||
- containerPort: 30080
|
||||
hostPort: 30080
|
||||
protocol: TCP
|
||||
# Overleaf HTTP NodePort
|
||||
- containerPort: 30000
|
||||
hostPort: 30000
|
||||
protocol: TCP
|
||||
# Tell containerd to resolve localhost:5001 via the NodePort bound on the node itself.
|
||||
# kube-proxy binds NodePorts to 0.0.0.0 on the node, so localhost:5001 reaches localhost
|
||||
# from inside the node without needing cluster DNS.
|
||||
containerdConfigPatches:
|
||||
- |-
|
||||
[plugins."io.containerd.grpc.v1.cri".registry]
|
||||
config_path = "/etc/containerd/certs.d"
|
||||
#containerdConfigPatches:
|
||||
# - |-
|
||||
# [plugins."io.containerd.grpc.v1.cri".registry]
|
||||
# [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
|
||||
# [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5001"]
|
||||
# endpoint = ["http://localhost:30002"]
|
||||
# [plugins."io.containerd.grpc.v1.cri".registry.configs]
|
||||
# [plugins."io.containerd.grpc.v1.cri".registry.configs."localhost:5001".tls]
|
||||
# insecure_skip_verify = true
|
||||
# [plugins."io.containerd.grpc.v1.cri".registry.configs."localhost:5001".tls]
|
||||
# insecure_skip_verify = true
|
||||
+11
-4
@@ -18,14 +18,22 @@ COPY server-ce/genScript.js server-ce/services.js /overleaf/
|
||||
# Corepack setup, shared between all the images.
|
||||
ENV PATH="/overleaf/node_modules/.bin:$PATH"
|
||||
ENV COREPACK_HOME=/opt/corepack
|
||||
RUN corepack enable && corepack install -g yarn@4.14.1
|
||||
RUN corepack enable && corepack prepare yarn@4.14.1 --activate
|
||||
#RUN corepack enable && corepack prepare yarn --activate
|
||||
ENV COREPACK_ENABLE_NETWORK=0
|
||||
|
||||
# RUN npm install node-fetch
|
||||
# RUN yarn add node-fetch
|
||||
# RUN yarn install
|
||||
#RUN --mount=type=cache,target=/root/.cache \
|
||||
# --mount=type=cache,target=/root/.yarn/berry/cache,id=server-ce-yarn-cache \
|
||||
# --mount=type=tmpfs,target=/tmp yarn install | bash
|
||||
|
||||
|
||||
# Install yarn dependencies
|
||||
# -------------------------
|
||||
RUN --mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/root/.yarn/berry/cache,id=server-ce-yarn-cache \
|
||||
--mount=type=cache,target=/usr/local/share/.cache/yarn,id=server-ce-yarn-fallback-cache \
|
||||
--mount=type=tmpfs,target=/tmp node genScript install | bash
|
||||
|
||||
# Add the actual source files
|
||||
@@ -33,10 +41,9 @@ RUN --mount=type=cache,target=/root/.cache \
|
||||
COPY --parents libraries/ services/ tools/migrations/ /overleaf/
|
||||
RUN --mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/root/.yarn/berry/cache,id=server-ce-yarn-cache \
|
||||
--mount=type=cache,target=/usr/local/share/.cache/yarn,id=server-ce-yarn-fallback-cache \
|
||||
--mount=type=cache,target=/overleaf/services/web/node_modules/.cache,id=server-ce-webpack-cache \
|
||||
--mount=type=tmpfs,target=/tmp \
|
||||
node genScript compile | bash
|
||||
YARN_CACHE_FOLDER=/tmp/.yarn-cache node genScript compile | bash
|
||||
|
||||
# Copy runit service startup scripts to its location
|
||||
# --------------------------------------------------
|
||||
|
||||
@@ -2,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
|
||||
# -----------------------------------
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
POTENTIAL_OLD_PATHS="
|
||||
/etc/sharelatex
|
||||
/var/lib/sharelatex
|
||||
/var/log/sharelatex
|
||||
"
|
||||
|
||||
OLD_ITEMS=""
|
||||
for path in ${POTENTIAL_OLD_PATHS}; do
|
||||
if [[ -e "$path" ]]; then
|
||||
OLD_ITEMS="$OLD_ITEMS $path"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$OLD_ITEMS" == "" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
OLD_ITEMS=$(echo "$OLD_ITEMS" | xargs -n1 | sed 's/^/ - /')
|
||||
N=$(echo "$OLD_ITEMS" | wc -l)
|
||||
cat <<EOF
|
||||
------------------------------------------------------------------------
|
||||
|
||||
ShareLaTeX to Overleaf rebranding
|
||||
---------------------------------
|
||||
|
||||
Starting with version 5.0, ShareLaTeX branded file system paths are no
|
||||
longer supported as we are migrating to the Overleaf brand.
|
||||
|
||||
Your configuration still uses $N ShareLaTeX branded paths:
|
||||
$OLD_ITEMS
|
||||
|
||||
Please update the in-container bind-mount target to refer to the
|
||||
Overleaf equivalent:
|
||||
- /etc/sharelatex -> /etc/overleaf
|
||||
- /var/lib/sharelatex -> /var/lib/overleaf
|
||||
- /var/log/sharelatex -> /var/log/overleaf
|
||||
|
||||
Overleaf toolkit setups:
|
||||
|
||||
github.com/overleaf/toolkit$ bin/upgrade
|
||||
|
||||
|
||||
Legacy docker compose setups/Horizontal scaling setups:
|
||||
|
||||
before:
|
||||
|
||||
services:
|
||||
sharelatex:
|
||||
volumes:
|
||||
- /my/docker-host/path:/var/lib/sharelatex
|
||||
|
||||
after:
|
||||
|
||||
services:
|
||||
sharelatex:
|
||||
volumes:
|
||||
- /my/docker-host/path:/var/lib/overleaf
|
||||
|
||||
|
||||
Other deployment methods:
|
||||
|
||||
Adapt the docker compose example or get in touch with support.
|
||||
|
||||
|
||||
Server Pro: Please update SANDBOXED_COMPILES_HOST_DIR if needed.
|
||||
|
||||
|
||||
Refusing to startup, exiting in 10s.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
EOF
|
||||
|
||||
sleep 10
|
||||
exit 101
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
OLD_ITEMS=$(env | cut -d '=' -f1 | grep SHARELATEX | sed 's/^/ - /')
|
||||
|
||||
if [[ "$OLD_ITEMS" == "" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
N=$(echo "$OLD_ITEMS" | wc -l)
|
||||
cat <<EOF
|
||||
------------------------------------------------------------------------
|
||||
|
||||
ShareLaTeX to Overleaf rebranding
|
||||
---------------------------------
|
||||
|
||||
Starting with version 5.0, ShareLaTeX branded variables are no
|
||||
longer supported as we are migrating to the Overleaf brand.
|
||||
|
||||
Your configuration still uses $N ShareLaTeX environment variables:
|
||||
$OLD_ITEMS
|
||||
|
||||
Please either replace them with the "OVERLEAF_" prefix,
|
||||
e.g. SHARELATEX_MONGO_URL -> OVERLEAF_MONGO_URL, or
|
||||
remove old entries from your configuration.
|
||||
|
||||
You can use the following script for migrating your config.
|
||||
|
||||
Overleaf toolkit setups:
|
||||
|
||||
github.com/overleaf/toolkit$ bin/upgrade
|
||||
github.com/overleaf/toolkit$ bin/rename-env-vars-5-0.sh
|
||||
|
||||
|
||||
Legacy docker compose setups/Horizontal scaling setups:
|
||||
|
||||
github.com/overleaf/overleaf$ git pull
|
||||
github.com/overleaf/overleaf$ server-ce/bin/rename-env-vars-5-0.sh
|
||||
|
||||
# When using a docker-compose.override.yml file (or other file name):
|
||||
github.com/overleaf/overleaf$ server-ce/bin/rename-env-vars-5-0.sh docker-compose.override.yml
|
||||
|
||||
|
||||
Other deployment methods:
|
||||
|
||||
Try using the docker compose script or get in touch with support.
|
||||
|
||||
|
||||
Refusing to startup, exiting in 10s.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
EOF
|
||||
|
||||
sleep 10
|
||||
exit 101
|
||||
Reference in New Issue
Block a user