Skip to content

Environments ​

ldev treats a local Liferay environment as something that should be reproducible, inspectable and replaceable.

This is one of the areas where ldev does real work, not just convenience. project init + start will scaffold and run a working Docker-based Liferay from zero, and worktree setup --with-env will give a branch its own runtime state.

Bootstrap from zero ​

bash
ldev project init ~/projects/my-project
cd ~/projects/my-project
ldev start --activation-key-file /path/to/activation-key.xml
ldev oauth install --write-env
ldev oauth admin-unblock

Or, if you already have a repo that uses the ldev runtime layout:

bash
ldev env init
ldev start

Bring production-like state into local ​

If your portal lives in Liferay Cloud (LCP):

bash
ldev db sync --environment production --project my-lcp-project --force
ldev start

If your portal is self-hosted, db sync does not apply. Use a backup you already have:

bash
ldev db import --file /path/to/backup.sql.gz --force
ldev start

For Document Library content, see Data Transfer.

Docker as the runtime boundary ​

ldev uses Docker so startup, restart, reset and state transfer are explicit commands instead of tribal knowledge.

Top-level lifecycle:

bash
ldev start
ldev stop
ldev status

ldev setup is an optional preparation step for pre-pulling Docker images or warming runtime directories before ldev start.

Advanced recovery lives under ldev env:

bash
ldev env restart
ldev env recreate
ldev env restore
ldev env clean --force

Scriptable diagnostics:

bash
ldev env wait --timeout 600 --poll 10
ldev env is-healthy
ldev env diff --write-baseline
ldev env diff

is-healthy returns 0 when healthy and 1 otherwise. diff compares the current environment against a saved baseline.

Logs and shell ​

bash
ldev logs --service liferay --since 10m
ldev logs diagnose --since 10m --json
ldev shell

logs streams container output directly. logs diagnose reads recent logs, groups exceptions by class with regex, and applies a small set of keyword rules to suggest possible causes. Useful for triage; not deep diagnosis.

Worktrees for isolated debugging ​

When one branch is reproducing an incident and another is active development, use isolated worktrees:

bash
ldev worktree setup --name incident-123 --with-env
cd .worktrees/incident-123
ldev start

If the git worktree already exists elsewhere:

bash
cd /path/to/external/worktree
ldev worktree setup --with-env
ldev start

Each worktree gets its own Postgres, Liferay and OSGi state. On Linux + Btrfs, ldev uses subvolume snapshots to make worktree creation near-instant; refresh the base with ldev worktree btrfs-refresh-base when the main env changes.

Worktrees inherit the files that exist in the branch or commit used as their base. Make sure runtime Compose overrides (for example, docker-compose.liferay.volume.yml) are committed to that branch before creating the worktree.

See Worktrees for the full model.

Why this matters ​

A reproducible environment is a safety feature. It lets you:

  • debug locally before any production change
  • compare before-and-after behavior with env diff
  • verify a fix with the same commands every time
  • give an AI agent an environment it can stand up and reset on its own

Reproducibility and branch isolation are classic developer-experience moves; the agent benefit is a consequence. See Why ldev Exists for the full argument.

@mordonezdev/ldev for operational Liferay maintenance workflows. Built by Miguel Ordóñez