- Shell 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| .githooks | ||
| .env.example | ||
| .gitignore | ||
| install.sh | ||
| ldcmd | ||
| README.md | ||
| VERSION | ||
ldcmd
Generic Limedoc operator + pack developer bridge. Install once on your host. Do not vendor this script into pack repositories.
Repository: https://git.belowtoxic.cloud/belowtoxic.eu/ldcmd
Packages: https://git.belowtoxic.cloud/api/packages/belowtoxic.eu/generic/ldcmd/
Deploy bundle (generic archive): https://git.belowtoxic.cloud/api/packages/belowtoxic.eu/generic/limedoc/ (files limedoc-deploy-{version}.zip)
Install
curl -sSf https://git.belowtoxic.cloud/belowtoxic.eu/ldcmd/raw/branch/main/install.sh | sh
Installs to ~/.local/bin/ldcmd by default (LDCMD_PREFIX / --prefix override).
Operators — production bootstrap (no app git clone)
Requires Docker + Compose. Fetches the limedoc-deploy zip from generic
package limedoc, runs the questionnaire inside the published limedoc
image (--network host so port probes see the host; --user matches
the invoking host UID/GID so .env can be written to the deploy directory),
then compose pull && up for redis + app only.
Sidecar Compose lives in plugin packs (deploy.json + worker/docker-compose.yml),
not in the deploy zip. After packs are installed (Pack Store or bootstrap
recommended install), start them on the host:
cd "$LIMEDOC_DEPLOY_DIR" # flat deploy directory
ldcmd sidecar configure # probe ports + sidecar env → deploy .env
ldcmd sidecar up # all installed sidecars
# or: ldcmd sidecar up collabora web-render # merges into sidecars/active.json
# or: ldcmd sidecar up --configure # configure then up
ldcmd up # core + sidecars
ldcmd down # all tracked + installed sidecars, then core
ldcmd status
Partial sidecar up <id> calls merge into sidecars/active.json so every
started sidecar is remembered. ldcmd down stops all entries there plus any
installed sidecar packs reported by the app (packs:sidecars), then clears
active.json.
Sidecar configure runs inside the published LIMEDOC_IMAGE with
--network host so TCP port probes see the host. It merges *_HOST_PORT,
Collabora public/WOPI keys, and sidecar image refs into the deploy .env.
Use --force on sidecar up to skip the preflight gate.
Host pack trees for Compose:
- Default: download the catalog pack zip (content-hash verified via
deno run … /app/scripts/pack_dir_hash.tsinsideLIMEDOC_IMAGE; requires ldcmd ≥ 0.3.9 and a current app image) intosidecars/<id>@<version>/. - Bind-mount: set
LIMEDOC_PLUGINS_DIRto the host plugins path and ldcmd uses$LIMEDOC_PLUGINS_DIR/<id>.plugin/directly.
ldcmd bootstrap
# Interactive: prompts for deploy directory name under cwd (default limedoc).
# Compose project name = that directory basename (containers {name}-app-1).
# Default DOCKER_NETWORK_NAME = {basename}_internal (multi-instance isolation).
# Sidecars: {basename}-sidecar-{pluginId}. Distinct APP_HOST_PORT / worker ports
# still required for >1 deploy on one host.
# Then: optional path to a previous deploy env file (any name; relative to
# invocation cwd, or absolute / ~/…). ldcmd copies → deploy/.env; wizard merges
# answers onto it so COLLABORA_* / custom keys survive. Secrets not shown.
# Non-interactive / override: LIMEDOC_DEPLOY_DIR=/opt/wiki (validated; no system roots)
# optional: LIMEDOC_IMAGE=…:1.2.3 LIMEDOC_VERSION=1.2.3
# After compose up: if install registry is non-empty → restore packs (withDeps)
# or wipe only if volumes still empty (wipe archives data/config to
# backups/pack-wipe-*.tar.gz). Partial restore continues to sidecar configure.
# Sidecar configure seeds prompts from deploy .env; bootstrap then runs ldcmd up.
# Greenfield: Plugins prompt for recommended packs + sidecar up --configure + up.
# Manual recovery: ldcmd packs restore --force && ldcmd up
Data: named volumes ↔ host directory
Wiki data (/app/data) and the vectorsearch cache share one unified host tree
layout (vectorsearch under cache/vectorsearch). Named-volume deploys split that
across two Docker volumes; host-directory deploys keep everything under one path.
Wizard host path forms: bare name under the deploy dir (default data →
./data), . / ./name under the host parent of the deploy dir (stored as
absolute paths; bootstrap injects LIMEDOC_HOST_DEPLOY_PARENT so the in-container
/host-deploy mount is not used as parent), or an absolute /path.
ldcmd bootstrap / ldcmd up create or validate the directory on the host
(empty = new; non-empty must be a Limedoc data tree; no nested data dirs; leaf
mkdir only).
cd "$LIMEDOC_DEPLOY_DIR"
# Volume mode → portable / host-shaped tree (default DIR=./data):
ldcmd data export ./data
# Then set in .env:
# LIMEDOC_DATA_MOUNT=./data
# VECTORSEARCH_CACHE_MOUNT=./data/cache/vectorsearch
# and: ldcmd up
# Host tree → named volumes (mounts must be limedoc_data / limedoc_vectorsearch_cache):
ldcmd data import ./data
ldcmd up
Export stops the app (and vectorsearch sidecar if present) for a consistent copy.
Pack developers — limedoc-dev reach-in (no app git clone)
Your pack repo is the only source you need. ldcmd pulls limedoc-dev and
runs tasks inside app-dev against your bind-mounted pack code.
cd my-plugin # scaffolded pack — no limedoc clone
ldcmd init
ldcmd setup && ldcmd up # also starts pack composeFiles when deploy.json present
ldcmd test # compose exec into app-dev
ldcmd check
ldcmd pack
Requirements
- Docker (or Podman with
DOCKER_CMD=podman) - Pack commands: cwd with
compose.dev.yml(usuallylimedoc.project.json) - Bootstrap / sidecar: network access to the package + container registries
python3,curl,unzipfor sidecar download/extract
Install / list / uninstall packs (running app)
Works from a prod deploy dir (docker-compose.yml + .env, or
LIMEDOC_DEPLOY_DIR) or a pack-dev cwd (compose.dev.yml). Does not
require .env.ldcmd:
ldcmd plugin ls # available from store; ✓ = installed
ldcmd plugin ls --installed # install registry only
ldcmd plugin install collabora --with-deps
# Packs with deploy.json print summary + operatorNotes, then:
# ldcmd sidecar up <id> --configure
# Finish with ldcmd up so the app recreates and picks up .env / mounts.
ldcmd packs restore --force # when registry exists but pack volumes are empty
ldcmd plugin uninstall collabora # refuses if dependents exist
ldcmd plugin uninstall web-render --force # cascade-uninstall dependents
ldcmd plugin deactivate drawio
ldcmd template activate email
ldcmd skin select lime
ldcmd skin palette midnight # or: none
Plugin uninstall in a prod deploy dir also runs ldcmd sidecar down <id>.
Configuration (.env.ldcmd)
On first pack-dev use (or ldcmd init), ldcmd resolves pack id/kind and
writes .env.ldcmd. PACK_DIR / PACK_TASK / registry owner are derived from
kind (main Limedoc registry by default; choose custom to set URL + owner).
See .env.example.
Commands
| Command | Purpose |
|---|---|
ldcmd bootstrap / install |
Prod bootstrap (deploy bundle + wizard + compose) |
ldcmd up / down / status |
Prod deploy dir or pack-dev stack |
ldcmd data export|import [DIR] |
Unified host tree ↔ named data + vectorsearch vols |
ldcmd packs restore [--force] |
Re-fetch packs from install registry (compose run) |
ldcmd sidecar status|up|down |
Pack-owned sidecars on prod host |
ldcmd plugin|skin|template install|ls|uninstall |
Install / list / uninstall packs in the running app |
ldcmd plugin|template activate|deactivate |
Soft enable/disable (templates + plugins) |
ldcmd skin select|palette |
Choose active full-skin + optional palette overlay |
ldcmd init |
Re-detect / prompt and rewrite .env.ldcmd |
ldcmd version |
Print tool version |
ldcmd setup |
Pull limedoc-dev, seed .env |
ldcmd logs / sh |
Logs / shell in a service |
ldcmd test / fmt / lint / check |
Reach-in to app-dev |
ldcmd pack / publish |
Build zip+sha / upload to package registry |
Releasing ldcmd (maintainers)
- Bump
VERSION. - Commit and push to
main. - Tag
v{VERSION}and push the tag (or run the Release workflow manually).
Secrets: PACKAGE_TOKEN with package + release write.