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
ldev project init ~/projects/my-project
cd ~/projects/my-project
ldev start --activation-key-file /path/to/activation-key.xml
ldev oauth install --write-envOr, if you already have a repo that uses the ldev runtime layout:
ldev env init
ldev startBring production-like state into local
If your portal lives in Liferay Cloud (LCP):
ldev db sync --environment production --project my-lcp-project --force
ldev startIf your portal is self-hosted, db sync does not apply. Use a backup you already have:
ldev db import --file /path/to/backup.sql.gz --force
ldev startFor 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:
ldev start
ldev stop
ldev statusldev setup is an optional preparation step for pre-pulling Docker images or warming runtime directories before ldev start.
Advanced recovery lives under ldev env:
ldev env restart
ldev env recreate
ldev env restore
ldev env clean --forceScriptable diagnostics:
ldev env wait --timeout 600 --poll 10
ldev env is-healthy
ldev env diff --write-baseline
ldev env diffis-healthy returns 0 when healthy and 1 otherwise. diff compares the current environment against a saved baseline.
Logs and shell
ldev logs --service liferay --since 10m
ldev logs diagnose --since 10m --json
ldev shelllogs 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:
ldev worktree setup --name incident-123 --with-env
cd .worktrees/incident-123
ldev startIf the git worktree already exists elsewhere:
cd /path/to/external/worktree
ldev worktree setup --with-env
ldev startEach 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.