Skip to content

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 doctor expects 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):

Enable-WindowsOptionalFeature -Online -FeatureName TelnetClient

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)

choco install mkcert openssl
mkcert -install

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:

# 5. Initialize Local Trust Store (Requires Administrator)
mkcert -install

๐ŸŽ 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)

...

sudo apt update && sudo apt install mkcert libnss3-tools openssl
mkcert -install

๐Ÿณ 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:

ldm init-common

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:

Docker CPUs                         โœ…  12 Cores
Docker Memory                       โœ…  7.6 GB

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:

[wsl2]
memory=11GB

Then apply it:

wsl --shutdown
# restart Docker Desktop, then:
ldm doctor --detailed

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:

# Force a repair of the current version
ldm upgrade --repair

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 and ldm (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:

=== LDM Self-Upgrade ===
โŒ  Failed to check for updates.

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 a cp + rm pattern 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:

  1. Never use the sudo prefix: Run ldm <command> directly as a standard user.
  2. Exit Root Shells: If you are logged in as root, type exit to return to your standard user before running LDM.
  3. Fix Cache Ownership: If you have already run with sudo and are now seeing "Permission Denied" errors, wipe the cache:
sudo rm -rf ~/.shiv
  1. Fix Docker Permissions: If you were using sudo because of Docker errors, add your user to the docker group instead:
sudo usermod -aG docker $USER

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:

pip install argcomplete

Step 2: Enable Completion for your Shell

Run the following command to see the specific instruction for your active shell:

ldm completion

For Zsh (macOS Default)

Add this to your ~/.zshrc:

eval "$(ldm completion zsh)"

For Bash

Add this to your ~/.bashrc:

eval "$(ldm completion bash)"

For Fish

Add this to your ~/.config/fish/config.fish:

ldm completion fish | source

For PowerShell (Windows)

Standard argcomplete requires a community module to bridge with PowerShell.

  1. Install the PowerShell-Argcomplete module:
Install-Module -Name PowerShell-Argcomplete -Scope CurrentUser
  1. Register the completion for ldm in your PowerShell Profile ($PROFILE):
# Open your profile in notepad
notepad $PROFILE

Add this line to the file and save:

Register-Argcomplete ldm

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

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:

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

launchctl load ~/Library/LaunchAgents/com.github.abiosoft.colima.plist

๐ŸชŸ 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:
sudo systemctl enable --now docker

๐ŸŒ 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/hosts using sudo:
sudo nano /etc/hosts

Add a line like this:

127.0.0.1 forge.demo ecopulse-microservice.forge.demo ecopulse-theme.forge.demo
  • Windows: Edit C:\Windows\System32\drivers\etc\hosts as 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:

  1. Add the group:
sudo usermod -aG docker $USER
  1. Apply the changes:
  2. WSL Users: Completely restart your WSL terminal.
  3. Native Linux Users: Log out and log back in.

  4. Verify: Run docker ps. If it works without sudo, 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:

mkcert -install
  • 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 curl and 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:

ldm doctor

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.

  1. Implicit: If you are inside a project folder, LDM will detect it automatically.
  2. Explicit: You can target a project from anywhere using ldm run <project_name> or a direct path ldm run ./my-project.
  3. Workspace Support: LDM automatically searches for projects in:
  4. The current directory.
  5. ~/ldm (default).
  6. /Volumes/SanDisk/ldm (for external storage users).
  7. Any directory specified in the LDM_WORKSPACE environment 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