Quick Start¶
See the specific installation guides for your OS.
- Docker Engine: Required for container orchestration.
- Docker Desktop (Windows/Mac)
- Colima or OrbStack (Mac alternatives)
- Native Docker Engine (Linux)
- Docker Compose: v2 (Plugin) is mandatory. Legacy v1 standalone is not supported. (Note: Docker Desktop includes Docker Compose automatically).
- Resources: Recommended 4 CPUs and 8GB RAM allocated to Docker.
- Note:
ldm doctorexpects these minimums. If you allocate exactly 8GB, Docker may report ~7.7GB due to system overhead; the tool accounts for this by allowing a 7.5GB threshold. - Python: 3.10+ (required for source installations and for macOS/Linux standalone binaries, as they are packaged as ZipApps. Not required for Windows standalone binaries).
For a detailed breakdown of all third-party dependencies, why they are needed, and feature impact, see the THIRD_PARTY_TOOLS.md guide.
๐ช Windows Setup & Tools¶
Windows does not include all the optional developer tools by default.
Important
Terminal Encoding: Older Windows consoles (cmd.exe / PowerShell 5) may have trouble displaying Unicode symbols (โ, โ ). LDM v2.4.26-beta.37+ automatically detects these terminals and switches to safe ASCII fallbacks. For the best experience, we recommend using Windows Terminal.
1. Enable Telnet Client (Administrator PowerShell)¶
Open PowerShell as an Administrator to enable Telnet (required for OSGi Gogo Shell access):
2. Install SSL Tools (Chocolatey or Scoop)¶
To enable "Green Lock" SSL on Windows, you must install mkcert and openssl. You can use either Chocolatey or Scoop.
Option A: Chocolatey (Requires Administrator PowerShell)
Option B: Scoop (Run as a Standard User!) Note: Scoop refuses to run as Administrator. Run these in a standard, non-elevated PowerShell:
# 1. Install Scoop (The Package Manager)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser; iwr -useb get.scoop.sh | iex
# 2. Install Git (Required for Scoop Buckets and OpenSSL)
scoop install git
# 3. Add the Extras Bucket (Required for mkcert)
scoop bucket add extras
# 4. Install SSL Tools
# Note: We use openssl-mingw instead of the default openssl to bypass a broken
# global Scoop dependency (innounp 404 error) that affects the standard installer.
scoop install mkcert openssl-mingw
After Scoop finishes, open an Administrator PowerShell to initialize the trust store:
๐ Install SSL Tools (macOS)¶
Using Homebrew:
# Install Docker CLI and SSL tools
brew install docker docker-compose mkcert nss openssl
mkcert -install
Using MacPorts:
# Install Docker CLI and SSL tools
sudo port install docker docker-compose mkcert nss openssl
mkcert -install
๐ง Install SSL Tools (Native Linux)¶
...
๐ณ Linux & WSL Docker Permissions¶
If ldm doctor reports Docker Engine: Not reachable or you see Permission Denied errors on Linux/WSL, your user needs permission to talk to the Docker socket.
Run these commands to grant access:
# 1. Add your user to the docker group
sudo usermod -aG docker $USER
# 2. Create a path bridge (if /var/run/docker.sock is missing)
sudo ln -s /run/docker.sock /var/run/docker.sock
# 3. Apply changes (or restart your terminal)
newgrp docker
๐ ๏ธ Environment Setup & Troubleshooting¶
Global Configuration (The common/ Folder)¶
LDM allows you to synchronize files (e.g., OSGi configs, licenses, LPKG modules) to every project stack automatically.
1. Baseline Assets (init-common)¶
LDM bundles a "Gold Standard" development baseline internally. To initialize or recreate this baseline in your global common/ folder, run:
This will create:
portal-ext.properties: Developer-mode overrides and modern image support.env-blacklist.txt: Standard exclusions for environment variables (OAuth2 secrets, etc.).com.liferay...config: OSGi configuration to prevent session timeouts during local demos.
Global Preferences (config)¶
LDM supports global user preferences stored in ~/.ldmrc. You can manage these settings without editing files manually:
# View all current settings
ldm config
# Set a preference (e.g., enable verbose mode by default)
ldm config verbose true
# Remove a preference
ldm config verbose --remove
2. Mandatory Infrastructure Settings¶
LDM is designed to be self-healing. Even if you do not use a common/ folder, the tool will automatically ensure that every project's portal-ext.properties contains the essential settings for SSL and virtual hosting (web.server.host, web.server.protocol, etc.).
Docker Resource Alignment (Windows/WSL2/macOS)¶
Run ldm doctor --detailed and read two lines:
A green tick on Docker Memory does not mean the allocation is a good one
for Liferay. See Why 7.6 GB is the number to watch below.
Where the allocation is actually configured¶
Docker Desktop on Windows has two backends, and they are configured in different places. Check which one you have before changing anything: open Docker Desktop โ Settings โ Resources. If the CPU and memory sliders are greyed out and it says resource allocation is managed by Windows, you are on the WSL2 backend and the sliders will do nothing.
| Backend / provider | Where you change it |
|---|---|
| Docker Desktop, WSL2 (the Windows default) | %UserProfile%\.wslconfig |
| Docker Desktop, Hyper-V | Settings โ Resources sliders |
| Docker Desktop, macOS | Settings โ Resources sliders |
| Colima | colima stop && colima start --cpu 4 --memory 8 |
Windows with the WSL2 backend¶
.wslconfig does not exist until you create it, and its absence is why the
default applies. WSL2 with no config file takes 50% of host RAM, which is
how a 16 GB machine ends up reporting 7.6 GB to Docker.
Create C:\Users\<you>\.wslconfig โ in the Windows user profile, not
inside WSL:
Then apply it:
Docker Memory should move. If it does not, the backend is not WSL2 and the
Docker Desktop sliders are the right control after all.
Do not set processors lower than the host has. WSL2 already gives the VM
every logical processor by default, so adding processors=8 on a 12-core
machine removes four cores. Leave the line out unless you specifically want
to restrict it.
Leave RAM for Windows. On a 16 GB host, memory=11GB leaves about 4.7 GB,
which is workable on a machine dedicated to this and tight on a daily driver.
memory=12GB or higher starts to starve the OS.
Why 7.6 GB is the number to watch¶
LDM sizes the Liferay JVM heap in tiers from whichever is smaller, the host RAM or the Docker allocation. There is a step change at 8 GB:
| Docker reports | -Xmx |
-Xms |
|---|---|---|
| 7.6 GB | 3072m | 2048m |
| 8.0 GB | 3072m | 2048m |
| 9.7 GB | 4096m | 2048m |
| 10.7 GB | 5120m | 2048m |
At or below 8 GB the heap is a flat 3 GB that does not scale, and in sidecar search mode an embedded Elasticsearch shares that same container, with a database container alongside it.
Note also that Docker reports slightly less than you allocate, after VM
overhead โ memory=10GB showed as 9.7 GB and memory=11GB as 10.7 GB. Since
the tier is derived from the reported figure, the difference can be a whole
gigabyte of heap.
Measured, same Windows 11 machine, same Liferay tag, same cached seed:
.wslconfig |
Docker reports | -Xmx |
Time to Liferay ready |
|---|---|---|---|
| (absent โ the default) | 7.6 GB | 3072m | 9m 31s |
memory=11GB |
10.7 GB | 5120m | 2m 42s |
One file that did not exist, and ldm doctor reported a green tick throughout.
The "Lenient" Threshold (LDM v1.6.36+)¶
- 2-3 CPUs or 4GB-7.5GB RAM trigger a Warning (โ ๏ธ) rather than a hard failure, so LDM still runs on older hardware with degraded performance.
- Because that warning stops at 7.5 GB, a WSL2 default of 7.6 GB passes it silently while sitting on the lowest heap tier. Read the figure itself rather than the tick.
๐ ๏ธ Troubleshooting: Version Loop & Integrity Issues¶
If ldm doctor reports Executable Integrity: TAMPERED or if you are stuck in a "Version Loop" (where you upgrade but the version doesn't change), follow these steps:
1. The "Intel Hash Mismatch" (macOS Intel)¶
Earlier versions of LDM (v1.6.32-v1.6.33) had an integrity check that was not fully architecture-aware. This often caused Intel Macs to flag official binaries as "TAMPERED" because their hash didn't match the Apple Silicon metadata.
The Fix: Upgrade to v1.6.36+, which introduces architecture-specific integrity verification.
2. Force a Repair¶
If your binary is corrupted or misbehaving, force a re-download of the official assets:
3. The "Manual Reset" (Last Resort)¶
If the tool is too broken to self-repair, manually overwrite the binary with the latest version:
# For macOS (Intel or Apple Silicon)
sudo curl -L https://github.com/peterrichards-lr/liferay-docker-manager/releases/latest/download/ldm-macos -o /usr/local/bin/ldm
sudo chmod +x /usr/local/bin/ldm
4. Version Shadowing¶
If you have cloned the repository and also have the binary installed, ldm doctor may report a "Shadowed" version.
- Recommendation: Use
./ldm(local wrapper) for development andldm(global binary) for daily use.
3. Manual Recovery (Binary Replacement)¶
If the automatic upgrade fails (due to network issues or permission constraints), you can always perform a manual replacement of the binary.
macOS / Linux / WSL2¶
# Replace <tag> and <asset> with appropriate values (e.g. v2.4.25 and ldm-linux)
sudo curl -L https://github.com/peterrichards-lr/liferay-docker-manager/releases/download/<tag>/<asset> -o /usr/local/bin/ldm
sudo chmod +x /usr/local/bin/ldm
Windows¶
Invoke-WebRequest -Uri "https://github.com/peterrichards-lr/liferay-docker-manager/releases/download/<tag>/ldm-windows.exe" -OutFile "$HOME\bin\ldm.exe"
4. Manual Beta Installation¶
To install a specific beta or pre-release version manually, replace <tag> in the URLs above with the specific version string (e.g., v2.4.26-beta.1).
Stable releases are always available via the /releases/latest/download/ path, while pre-releases must be accessed via their specific tag path: /releases/download/<tag>/.
5. GitHub API Rate Limiting (HTTP 403 / "Failed to check for updates")¶
If you are running LDM behind a corporate proxy, VPN, or a shared public IP address, you might occasionally see the following error when checking for updates or upgrading:
This occurs when the shared IP address hits the GitHub unauthenticated REST API limit (60 requests/hour).
The Solution: LDM automatically falls back to an HTML redirect check on https://github.com/peterrichards-lr/liferay-docker-manager/releases/latest (which is not rate-limited). If the fallback also fails, verify your network connectivity or try again later.
๐ ๏ธ Troubleshooting: Sudo & Root Issues¶
LDM strictly prohibits being run with sudo or as the root user (except for internal, just-in-time elevation).
LDM runs as your standard user and only invokes sudo internally for specific system-level operations:
ldm fix-hosts: Requests elevation to append entries to/etc/hosts.ldm upgrade: Requests elevation to replace the binary in system paths like/usr/local/bin. Uses acp+rmpattern to handle cross-device links during replacement. On Windows, it seamlessly requests administrative privileges via UAC prompts when replacing the binary.
Standalone LDM binaries use a cache directory in your home folder (~/.shiv). Running as root causes this cache to become owned by root, which prevents the tool from functioning correctly when run as a standard user later.
The Fix:
- Never use the sudo prefix: Run
ldm <command>directly as a standard user. - Exit Root Shells: If you are logged in as root, type
exitto return to your standard user before running LDM. - Fix Cache Ownership: If you have already run with sudo and are now seeing "Permission Denied" errors, wipe the cache:
- Fix Docker Permissions: If you were using
sudobecause of Docker errors, add your user to thedockergroup instead:
Note: You must log out and back in for this to take effect.
3. Shell Autocompletion¶
LDM supports full TAB completion for all commands and project names. This significantly improves productivity by allowing you to quickly cycle through projects when running stop, logs, or run.
Step 1: Install argcomplete (Source Installs Only)¶
If you are using the Standalone Binary, argcomplete is already bundled. If you are using a Python Source installation (pip install -e .), ensure the library is installed:
Step 2: Enable Completion for your Shell¶
Run the following command to see the specific instruction for your active shell:
For Zsh (macOS Default)¶
Add this to your ~/.zshrc:
For Bash¶
Add this to your ~/.bashrc:
For Fish¶
Add this to your ~/.config/fish/config.fish:
For PowerShell (Windows)¶
Standard argcomplete requires a community module to bridge with PowerShell.
- Install the
PowerShell-Argcompletemodule:
- Register the completion for
ldmin your PowerShell Profile ($PROFILE):
Add this line to the file and save:
Step 3: Restart your Terminal¶
After adding the line to your profile, restart your terminal or source the file (e.g., source ~/.zshrc) for the changes to take effect.
๐ณ Colima (Advanced macOS Setup)¶
Colima is a lightweight, open-source alternative to Docker Desktop. While highly performant on Apple Silicon, it is much stricter regarding file sharing and permissions.
0. Installation¶
Homebrew: brew install colima
MacPorts: sudo port install colima
1. Recommended Start Command (Apple Silicon)¶
For the best compatibility with Liferay and SSCE build processes, we recommend using the macOS Virtualization Framework (vz) with VirtioFS.
# Optimized for M1/M2/M3 (16GB+ RAM)
colima start --cpu 4 --memory 8 --vm-type=vz --mount-type=virtiofs --mount /Users/$(whoami):w --mount /Volumes:w
2. Supported Providers (Legacy Intel Mac / macOS 12)¶
If you are running on an older Intel Mac (macOS 12 and below), Colima is explicitly unsupported for LDM due to filesystem limitations (sshfs breaks write permissions, 9p breaks Elasticsearch file locking).
For older macOS versions, you must use a provider that supports gRPC FUSE or osxfs:
- Docker Desktop (Recommended)
- OrbStack (Lightweight alternative)
3. The "Ghost Mount" Issue¶
If LDM reports FATAL: VOLUME MOUNTING IS BROKEN, it means Colima's VM can see the folder but cannot see the files inside it.
The Fix: Ensure your home directory is explicitly mounted with write permissions (:w). If your project is on an external volume, add it to the mount list using the command above.
3. Permissions¶
Unlike Docker Desktop, Colima does not "mask" file owners. LDM automatically handles this by running a Permission Fixer before every stack startup to ensure the liferay user (UID 1000) has access to your host files. Note: LDM is smart enough to skip the .git directory to preserve your repository metadata permissions.
4. Automatic Start (macOS Service)¶
For a seamless experience, you can set up Colima to start automatically in the background when you log in.
Step 1: Create the Startup Script¶
Save this script as /usr/local/bin/colima-start-fg and make it executable (chmod +x). It is architecture-aware and will automatically select the best VM and mount settings for your Mac.
#!/bin/bash
# 1. Path includes Homebrew (M1/M2) and MacPorts
export PATH="/opt/homebrew/bin:/opt/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
# 2. Robust Home Directory Logic
if [ -z "$HOME" ]; then
export HOME="$(eval echo ~$USER)"
fi
function shutdown() {
colima stop
exit 0
}
trap shutdown SIGTERM
trap shutdown SIGINT
# 3. Detect Architecture and Set Optimized Parameters
ARCH=$(uname -m)
if [[ "$ARCH" == "arm64" ]]; then
# Apple Silicon (M1/M2/M3)
# Optimized for vz/virtiofs
START_CMD="colima start --cpu 4 --memory 8 --vm-type=vz --mount-type=virtiofs --mount $HOME:w --mount /Volumes:w"
else
# Intel Mac
# Optimized for sshfs (virtiofs requires macOS 14+ on Intel)
START_CMD="colima start --cpu 2 --memory 6 --mount-type sshfs --mount $HOME:w"
fi
# 4. The Start/Monitor Loop
while true; do
colima status &>/dev/null
if [[ $? -eq 0 ]]; then
break;
fi
# Execute the detected start command
$START_CMD
sleep 5
done
# 5. Keep alive for launchd
tail -f /dev/null &
wait $!
Step 2: Create the launchd Service¶
Create a file named ~/Library/LaunchAgents/com.github.abiosoft.colima.plist with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.github.abiosoft.colima</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/colima-start-fg</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/colima.log</string>
<key>StandardErrorPath</key>
<string>/tmp/colima.err</string>
</dict>
</plist>
Step 3: Load the Service¶
๐ช Windows & ๐ง Linux Auto-Start¶
Colima is primarily a macOS tool. If you are on Windows or Linux, auto-start is handled differently:
- Windows (Docker Desktop): Open Settings and check "Start Docker Desktop when you log in".
- Linux (Native/WSL2): Ensure the docker service is enabled via systemd:
๐ DNS & Subdomain Configuration¶
Server-Side Client Extensions (SSCE) in LDM use subdomains (e.g., https://my-ext.forge.demo) for routing. Because these are local domains, your operating system needs to be told to route them to your machine.
1. Manual Mapping (The Standard Way)¶
You must add each domain and subdomain to your system's hosts file.
- macOS / Linux: Edit
/etc/hostsusing sudo:
Add a line like this:
- Windows: Edit
C:\Windows\System32\drivers\etc\hostsas an Administrator.
Tip
LDM will proactively check your DNS configuration during ldm run or ldm doctor and provide the exact line you need to copy-paste if any subdomains are missing.
Caution
Windows & .local domains: Windows 10/11 reserve the .local TLD for Multicast DNS (mDNS). If you use a .local domain, Windows may prioritize mDNS discovery and ignore your hosts file entries entirely, leading to resolution failures even if the entries are correct.
Recommendation: We strongly recommend using .test, .internal, or .demo instead of .local when working on Windows or WSL.
๐ง Docker Permissions (WSL & Linux)¶
If you see a "Permission Denied" error or LDM keeps asking for sudo, your user likely doesn't have permission to access the Docker socket. Do not run LDM with sudo. Instead, add your user to the docker group:
- Add the group:
- Apply the changes:
- WSL Users: Completely restart your WSL terminal.
-
Native Linux Users: Log out and log back in.
-
Verify: Run
docker ps. If it works withoutsudo, LDM will also work.
๐ Fixing SSL Trust Issues (mkcert)¶
If your browser (Chrome, Edge, etc.) shows "Your connection is not private" or a red warning even though LDM is running with SSL, follow these steps to fix the trust relationship:
1. Initialize the Root CA (Mandatory)¶
The most common cause is that the mkcert Root CA has not been added to your system's trust store. Run this in your terminal:
- macOS: You may be prompted for your password or Touch ID to modify the System Keychain.
- WSL2: You must run this inside your WSL terminal to allow
curland Liferay modules to verify internal HTTPS traffic. - Windows: You will see a security prompt asking to install the "mkcert development CA." Click Yes.
2. Fully Restart your Browser¶
Chrome and other Chromium-based browsers often cache certificate trust.
- Simply refreshing the page is often not enough.
- Action: Completely Quit (Cmd+Q on Mac) the browser and restart the application.
3. Verify with ldm doctor¶
Run ldm doctor to verify that your system sees the Root CA as trusted and that all required tools (telnet, nc, lcp, docker compose) are correctly installed and reachable:
Look for: mkcert โ
Installed (Root CA Trusted) and ensure other tools show as โ
Installed.
๐ Running Commands¶
Project Scope¶
Most LDM commands (like run, stop, logs) require a project context.
- Implicit: If you are inside a project folder, LDM will detect it automatically.
- Explicit: You can target a project from anywhere using
ldm run <project_name>or a direct pathldm run ./my-project. - Workspace Support: LDM automatically searches for projects in:
- The current directory.
~/ldm(default)./Volumes/SanDisk/ldm(for external storage users).- Any directory specified in the
LDM_WORKSPACEenvironment variable.
Pro-Tip: Add export LDM_WORKSPACE="/path/to/your/projects" to your .bashrc or .zshrc to make your projects accessible from anywhere.
Version Verification¶
LDM binaries use "Magic Byte" detection to accurately report their checksum in ldm doctor. This ensures that even if you rename the file, LDM can still verify that you are running a valid, hardened production build.
Last Updated: 2026-10-14 | Last Reviewed: 2026-10-14