{"id":48635772,"url":"https://github.com/peterrichards-lr/liferay-docker-manager","last_synced_at":"2026-05-27T12:01:23.750Z","repository":{"id":346878381,"uuid":"1190871806","full_name":"peterrichards-lr/liferay-docker-manager","owner":"peterrichards-lr","description":"A professional command-line orchestrator for quickly standing up Liferay Portal and DXP environments using Docker Compose.","archived":false,"fork":false,"pushed_at":"2026-05-08T11:10:50.000Z","size":106164,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-08T11:39:21.020Z","etag":null,"topics":["automation","cli","docker","docker-compose","dxp","ldm","liferay","liferay-docker-manager","orchestrator","python","sales-engineering"],"latest_commit_sha":null,"homepage":"https://liferay.dev/b/liferay-docker-automation-python-scripts","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peterrichards-lr.png","metadata":{"files":{"readme":"docs/README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY.md","support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-24T17:44:28.000Z","updated_at":"2026-05-08T11:10:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"a37e6164-7fdb-41f4-a43c-7a53894a64a6","html_url":"https://github.com/peterrichards-lr/liferay-docker-manager","commit_stats":null,"previous_names":["peterrichards-lr/liferay-docker-manager"],"tags_count":323,"template":false,"template_full_name":null,"purl":"pkg:github/peterrichards-lr/liferay-docker-manager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterrichards-lr%2Fliferay-docker-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterrichards-lr%2Fliferay-docker-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterrichards-lr%2Fliferay-docker-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterrichards-lr%2Fliferay-docker-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peterrichards-lr","download_url":"https://codeload.github.com/peterrichards-lr/liferay-docker-manager/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterrichards-lr%2Fliferay-docker-manager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32991982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"ssl_error","status_checked_at":"2026-05-13T13:14:51.610Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","cli","docker","docker-compose","dxp","ldm","liferay","liferay-docker-manager","orchestrator","python","sales-engineering"],"created_at":"2026-04-09T10:21:34.438Z","updated_at":"2026-05-13T17:01:18.467Z","avatar_url":"https://github.com/peterrichards-lr.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Liferay Docker Manager (ldm)\n\nA professional command-line orchestrator for quickly standing up Liferay Portal and DXP environments using Docker Compose.\n\n\u003e [!NOTE]\n\u003e **Project History:** This tool was originally born as part of the [liferay-docker-scripts](https://github.com/peterrichards-lr/liferay-docker-scripts) repository. It has since evolved into a standalone application to provide better modularity and multi-instance stability.\n\n---\n\n## Why use LDM?\n\n`ldm` is designed to be both fast for power users and helpful for newcomers. It follows a consistent usage pattern:\n\n1. **Sensible Defaults**: Whenever a standard Liferay convention exists, `ldm` uses it automatically (e.g., port `8080`, managed DB name `lportal`).\n2. **Smart Context**: If you run a command from inside a project folder, `ldm` automatically detects the project context.\n3. **Interactive Fallback**: If a required piece of information (like a project name or a Liferay tag) is missing from your command and cannot be detected, `ldm` will **prompt you interactively** or show you a list of choices.\n4. **Graceful Abort**: You can type `q` at any interactive prompt to safely cancel the operation.\n\n---\n\n## 🛡️ Compatibility (Verified Environments)\n\nThe badges below represent our verified support for various Docker providers. Environments marked as **Hardened** have received specific logic refinements to handle complex file-sharing and permission scenarios.\n\n\u003c!-- COMPATIBILITY_START --\u003e\n| Architecture | Host OS | Docker Provider | Hardening | Verified |\n| :--- | :--- | :--- | :--- | :--- |\n| **Apple Silicon** | macOS 11+ | **OrbStack** | ![OrbStack](https://img.shields.io/badge/OrbStack-Hardened-00B0FF?style=flat-square\u0026logo=apple) | ✅ |\n| **Apple Silicon** | macOS 11+ | **Docker Desktop** | ![DockerDesktop](https://img.shields.io/badge/Docker_Desktop-Hardened-00C853?style=flat-square\u0026logo=apple) | ✅ |\n| **Apple Silicon** | macOS 11+ | **Colima** | ![Colima](https://img.shields.io/badge/Colima-Hardened-FFAB00?style=flat-square\u0026logo=apple) | ✅ |\n| **Apple Intel** | macOS 11+ | **Colima** | ![Colima](https://img.shields.io/badge/Colima-Hardened-FFAB00?style=flat-square\u0026logo=apple) | ✅ |\n| **Windows PC** | Windows 11 | **Native WSL2** | ![WSL2](https://img.shields.io/badge/WSL2-Hardened-blue?style=flat-square\u0026logo=windows) | ✅ |\n| **Windows PC** | Windows 11 | **Docker Desktop** | ![DockerDesktop](https://img.shields.io/badge/Docker_Desktop-Hardened-00C853?style=flat-square\u0026logo=windows) | ✅ |\n| **Linux Workstation** | Fedora 43 | **Native Docker** | ![Fedora](https://img.shields.io/badge/Fedora-Hardened-success?style=flat-square\u0026logo=linux) | ✅ |\n| **Linux Node** | Ubuntu 22.04 | **Docker Engine** | ![Linux](https://img.shields.io/badge/Linux-Native-success?style=flat-square\u0026logo=linux) | ✅ |\n\n## Global Infrastructure\n\n| Component | Verified Versions | Notes |\n| :--- | :--- | :--- |\n| **Traefik** | `v3.6.1+` | Automatic API version negotiation enabled. |\n| **Elasticsearch** | `8.17.0`, `7.17.24` | Dual support with version-aware project sync. |\n\u003c!-- COMPATIBILITY_END --\u003e\n\n---\n\n## Key Features\n\n- **Multi-Instance Session Isolation**: Run multiple demos side-by-side on the same machine without session cross-talk. `ldm` automatically manages unique session cookie names and virtual hostnames.\n- **Orchestrated Search Snapshots**: Save and restore the exact state of a demonstration, including the database, files, and **Elasticsearch 8.x index state**.\n- **Service-Specific Lifecycle**: Manage individual components within a project surgically. Restart or view logs for a single extension without affecting the rest of the stack.\n- **Client Extension Lifecycle**: Automatically detects and builds Server-Side Client Extensions (SSCE). Subdomains are automatically generated, and traffic is routed based on `LCP.json`.\n- **Zero-Config SSL**: Automated HTTPS using `mkcert` and a global Traefik proxy. Works on Docker Desktop, **Colima**, and **WSL2**.\n- **Proactive License Verification**: Automatically detects Liferay XML licenses in `common/`, `deploy/`, or `osgi/modules/` folders. Warns you before boot if a DXP license is missing or expired.\n- **Fail-Fast Design**: Proactive environment checking. LDM verifies Docker reachability, volume mounts, resource allocations (CPU/RAM), and **Compose functionality** before execution, providing clean, actionable error messages instead of tracebacks.\n- **Architecture-Aware**: The tool detects your OS automatically to fetch the correct optimized binary during self-updates.\n\n---\n\n## Documentation\n\n- [Installation Guide](installation.md)\n- [Architecture Overview](LDM_ARCHITECTURE.md)\n- [Test \u0026 Validation Strategy](TESTING.md)\n- [Security Posture \u0026 Disclosures](SECURITY.md)\n- [Future Roadmap](roadmap.md)\n\n---\n\n## Scripting \u0026 Automation\n\nLDM is designed to be pipeline-friendly. The `ldm doctor` command returns a non-zero exit code if critical environment issues are detected.\n\n### Health Check Pipe\n\nEnsure your environment is healthy before attempting to start a project:\n\n```bash\nldm doctor --skip-project \u0026\u0026 ldm run my-project\n```\n\n### Automation Patterns\n\nCheck if services are running before executing operations:\n\n```bash\n# Start infrastructure only if it's not already running\nldm ps || ldm infra-setup --search\n```\n\n### CI/CD Integration\n\nYou can use LDM in automated scripts to verify infrastructure:\n\n```bash\nif ldm doctor --skip-project; then\n  echo \"Environment is healthy, proceeding...\"\nelse\n  echo \"Critical environment failure!\"\n  exit 1\nfi\n```\n\n---\n\n## Installation (Quick Start)\n\nThe standalone binary is the recommended way to use LDM.\n\n```bash\n# For macOS (Apple Silicon)\nsudo curl -L https://github.com/peterrichards-lr/liferay-docker-manager/releases/latest/download/ldm-macos-arm64 -o /usr/local/bin/ldm\n\n# For macOS (Apple Intel)\nsudo curl -L https://github.com/peterrichards-lr/liferay-docker-manager/releases/latest/download/ldm-macos-x86_64 -o /usr/local/bin/ldm\n\n# For Linux / WSL2\nsudo curl -L https://github.com/peterrichards-lr/liferay-docker-manager/releases/latest/download/ldm-linux -o /usr/local/bin/ldm\n\n# Make it executable\nsudo chmod +x /usr/local/bin/ldm\n```\n\nFor detailed instructions and Windows setup, see the **[Full Installation Guide](installation.md)**.\n\n---\n\n## Quick Start\n\n\u003e [!IMPORTANT]\n\u003e **Binary vs Script**: If you have installed the **Standalone Binary**, use `ldm` in your commands. If you are using the **Manual Installation**, use `./ldm` (on Linux/macOS) or `ldm.bat` (on Windows) from the root of this repository.\n\n```bash\n# 1. THE CONFIDENCE BOOSTER: Run Liferay with pre-configured samples\nldm run my-sample-project --samples\n\n# 2. THE DEVELOPER FLOW: Initialize from a workspace and start monitoring\nldm init-from /path/to/workspace my-project\n\n# 3. THE ARCHIVE FLOW: Import a static snapshot of a workspace\nldm import /path/to/workspace my-static-project\n\n# 4. THE RECOVERY FLOW: Re-create a deleted project from a snapshot folder\nldm run my-recovered-project --snapshot ~/Desktop/old-baseline-snapshot\n\n# Monitor an existing project (manually)\nldm monitor /path/to/workspace\n```\n\n---\n\n## Command Reference\n\n### `list` (alias: `ls`)\n\nDisplay a tabulated overview of all initialized LDM sandbox environments.\n\n```bash\nldm list\nldm ls\n```\n\n### `run` (alias: `up`)\n\nInitialize and start a project stack.\n\n```bash\n# Run with a specific tag and virtual hostname\nldm run --tag 2024.q4.0 --host-name demo.local\n\n# Using the alias\nldm up demo\n\n# Initialize with \"Confidence Booster\" samples\nldm run demo --samples\n\n# Interactive run (will prompt for version and project name)\nldm run\n```\n\n#### SSL Defaults (New Projects)\n\nLDM uses smarter defaults for SSL based on your hostname. When a custom `--host-name` is used, SSL is enabled by default to support modern Liferay features like Client Extensions.\n\n| Command | Host Name | SSL Default | Access URL |\n| :--- | :--- | :--- | :--- |\n| `ldm run` | `localhost` | `False` | `http://localhost:8080` |\n| `ldm run --host-name my.local` | `my.local` | `True` | `https://my.local` |\n| `ldm run --no-ssl` | `localhost` | `False` | `http://localhost:8080` |\n| `ldm run --host-name my.local --no-ssl` | `my.local` | `False` | `http://my.local:8080` |\n\n### `init-from` (Live Link)\n\nInitialize a project from a source workspace and establish a **persistent link**. This command records the workspace path in the project metadata and automatically starts the `monitor` process to sync your code changes in real-time.\n\n```bash\nldm init-from ~/repos/my-workspace my-project\n```\n\n### `import` (Static Snapshot)\n\nScaffold a new project by taking a **one-time static import** of an existing workspace. This project is detached from the source; changes to the source workspace will not be synced. Follows the same internal deployment sequence as `init-from`.\n\n```bash\nldm import ~/repos/my-workspace my-static-project\n```\n\n### `monitor`\n\nRestarts the background watch process for a project linked to a Liferay workspace. This command can **only be used for projects created with `init-from`**. It automatically syncs built artifacts (`.jar`, `.war`, `.zip`) whenever they are updated in the workspace.\n\n```bash\nldm monitor [project_name] --delay 2.0\n```\n\n### `logs`\n\nView real-time logs. Supports filtering by project and specific service.\n\n```bash\nldm logs [project] [service]\n\n# Examples:\nldm logs                  # All logs for current project\nldm logs demo             # All logs for 'demo' project\nldm logs demo liferay     # Only Liferay logs for 'demo'\nldm logs demo my-extension # Only logs for a specific client extension\n```\n\n### `stop`, `restart`, `down` (alias: `rm`)\n\nManage the lifecycle of a project or a specific service.\n\n```bash\nldm stop [project] [service]      # Stop containers gracefully\nldm restart [project] [service]   # Stop and then start\nldm down [project] [service]      # Remove containers (and optionally -v volumes)\nldm rm [project]                  # Alias for 'down'\n\n# Examples:\nldm restart               # Full stack restart (graceful stop + run)\nldm restart demo liferay  # Surgical restart of just the Liferay container\nldm down --volumes        # Tear down stack and clear all database/data state\nldm rm demo -v            # Remove 'demo' and its volumes\n```\n\n### `deploy`\n\nHot-deploy built artifacts or rebuild extension images.\n\n```bash\nldm deploy [project] [service] --rebuild\n\n# Examples:\nldm deploy                # Sync all artifacts and refresh stack\nldm deploy demo my-ext --rebuild  # Rebuild and restart one extension\n```\n\n### `scale`\n\nScale services within a project for multi-node simulation and clustering tests.\n\n```bash\nldm scale [project] service=count\n\n# Examples:\nldm scale demo liferay=2  # Scale Liferay to 2 nodes (enables clustering)\nldm scale demo my-ext=3   # Scale a client extension to 3 nodes\n```\n\n### `snapshot` \u0026 `restore`\n\nBackup and recover project states, including files, DB, and search indices.\n\n**Examples:**\n\n```bash\n# Create a named snapshot\nldm snapshot demo --name \"post-setup-gold-standard\"\n\n# List snapshots for a project\nldm restore demo --list    # Non-interactive list of all snapshots\nldm restore demo --index 1 # Restore to index 1\n```\n\n### `shell` \u0026 `gogo`\n\nJump into a container shell for deep inspection or connect to the OSGi Gogo console for runtime management.\n\n**Interactive Shell Examples:**\n\n```bash\n# Enter bash in the Liferay container\nldm shell demo\n\n# Common Shell Tasks (inside container):\n# 1. View live Tomcat logs\ncd tomcat/logs \u0026\u0026 tail -f catalina.out\n\n# 2. Check injected environment variables\nenv | grep LIFERAY\n\n# 3. Verify mounted OSGi configurations\nls osgi/configs\n```\n\n**Gogo Shell Examples:**\n\n```bash\n# Connect to the Gogo shell (requires --gogo-port during run)\nldm gogo demo\n\n# Common Gogo Commands:\n# 1. List all active bundles\nlb\n\n# 2. Check for unresolved dependencies\ndiag\n\n# 3. List declarative services (SCR)\nscr:list\n```\n\n### `env`\n\nManage persistent environment variables in project metadata.\n\n```bash\nldm env [project] KEY=VALUE\nldm env [project] --remove KEY\nldm env                   # Interactive manager (view and edit all)\n```\n\n### `cloud-fetch` (Fetch Cloud State)\n\nSynchronize an **existing local project** with data, logs, and configuration from Liferay Cloud (LCP). This is used for local debugging and state hydration, not for importing source code.\n\n\u003e [!NOTE]\n\u003e **Prerequisite:** You must have the [LCP CLI](https://customer.liferay.com/documentation/cloud/latest/en/reference/command-line-tool.html) installed and authenticated (`lcp login`).\n\n```bash\n# 1. Discover available cloud environments\nldm cloud-fetch --list-envs\n\n# 2. Stream remote logs from UAT to your local terminal\nldm cloud-fetch [project] uat liferay --logs\n\n# 3. Pull the latest Cloud backups (DB/Data) into your local project snapshots\nldm cloud-fetch [project] uat --download\n\n# 4. Sync Cloud environment variables to your local project metadata\nldm cloud-fetch [project] uat --sync-env\n```\n\n### `log-level`\n\nManage Liferay internal logging levels (Log4j2) without restarts.\n\n```bash\n# List current custom levels\nldm log-level --list\n\n# Set a specific category to DEBUG\nldm log-level [project] --bundle portal --category com.liferay.portal --level DEBUG\n\n# Interactive configuration\nldm log-level\n```\n\n### `doctor`\n\nVerify host environment health, Docker resources (CPUs/Memory), and project dependencies.\n\n```bash\nldm doctor          # Health check for current/selected project\nldm doctor --all    # Batch validate every project in your workspace\n```\n\n### `status` (alias: `ps`)\n\nLightweight summary of all active global services and running projects.\n\n```bash\nldm status\nldm ps\n```\n\n### `browser` (alias: `open`)\n\nLaunch the project URL in your system browser. If no project is specified, LDM will present a list of currently running projects to select from.\n\n```bash\nldm browser [project]\nldm open [project]\n```\n\n### `upgrade`\n\nAutomatically download and install the latest version of LDM for your architecture. Includes integrity verification.\n\n```bash\nldm upgrade             # Standard upgrade to latest\nldm upgrade --repair    # Re-download current version to fix integrity issues\n```\n\n### `renew-ssl`\n\nRefresh project-specific SSL certificates immediately.\n\n```bash\nldm renew-ssl           # Interactive selector\nldm renew-ssl demo      # Renew for 'demo' specifically\nldm renew-ssl --all     # Renew certificates for every project\n```\n\n### `init-common`\n\nInitialize or recreate the baseline global configuration (`common/` folder) from internal resources.\n\n```bash\nldm init-common\n```\n\n### `infra-setup`, `infra-down`, `infra-restart`\n\nIndependently manage global infrastructure services (Traefik proxy, Search sidecar, Bridge).\n\n```bash\nldm infra-setup            # Start global services manually\nldm infra-setup --search   # Also initialize the Global Search container\nldm infra-down             # Stop and remove global services\nldm infra-restart          # Reset all global services in one go\n```\n\n\u003e [!TIP]\n\u003e **Sidecar Fallback**: If the Global Search (ES8) container is not running, `ldm` will automatically default to Liferay's internal **Sidecar** search. It also cleans up global ES configurations in your project to ensure the Sidecar initializes correctly.\n\n### `migrate-search`\n\nMigrates a project from using the internal Sidecar search to the shared **Global Search container**.\n\n```bash\nldm migrate-search [project]\n```\n\n**What it does:**\n\n1. Verifies the project is stopped.\n2. Ensures the Global Search container is running (offers to start it).\n3. Deletes internal indices (`data/elasticsearch7` or `data/elasticsearch8`).\n4. Re-syncs Global ES configurations from `common/`.\n5. Offers to restart the project immediately.\n\n### `reset`\n\nSurgically clear project data folders. This command requires the project to be stopped.\n\n```bash\nldm reset [project] [target]\n```\n\n**Available Targets:**\n\n- **`state`** (Default): Clears the `osgi/state` folder.\n- **`search`**: Clears internal Sidecar indices.\n- **`db`**: Clears the Hypersonic database (if used).\n- **`global-search`**: Deletes the project's indices from the shared Global Search container.\n- **`all`**: Performs all of the above.\n\n**Examples:**\n\n```bash\nldm reset demo state          # Clear OSGi state for 'demo'\nldm reset demo search,db      # Clear local search and DB\nldm reset demo all            # Total project data wipe\n```\n\n### `prune`\n\nIdentify and remove orphaned resources. This command scans your Docker environment for containers and global search snapshots that no longer have a matching project folder on your disk.\n\n```bash\nldm prune\n```\n\n**What it cleans:**\n\n- **Orphaned Containers**: Any container with the `com.liferay.ldm.managed` label whose project folder was manually deleted.\n- **Orphaned Search Snapshots**: Leftover Elasticsearch 8.x snapshots in the global vault from deleted projects.\n- **Temporary Files**: Residual `.*.tmp` files left behind by interrupted sync or build operations.\n\n### `clear-cache`\n\nClears the local Docker Hub tag cache. LDM caches Liferay tags for 24 hours to improve performance; use this command to force a fresh fetch from the registry.\n\n```bash\nldm clear-cache\n```\n\n### `config`\n\nView or set global LDM configuration settings (stored in `~/.ldmrc`).\n\n```bash\nldm config                  # View all global settings\nldm config key value        # Set a global preference\nldm config key --remove     # Remove a preference\n```\n\n---\n\n## Configuration Files\n\n- **`logging.json`**: Managed via `log-level` command.\n- **`common/`**: Files here (configs, XML licenses, LPKG files) are synced to all project stacks.\n- **`services/`**: Place standalone `Dockerfile` directories here for orchestration.\n\n---\n\n## Prerequisites\n\n- **Docker Engine**: Docker Desktop, Colima, or native WSL2.\n- **Docker Compose**: **v2 (Plugin)** is mandatory. Legacy v1 standalone is not supported.\n- **Resources**: Recommended **4 CPUs and 8GB RAM** allocated to Docker.\n  - *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.\n- **Python**: 3.10+ (if not using binary)\n- **mkcert**: (Optional) For automated local SSL.\n\n### Increasing Resources in Colima\n\nIf `ldm doctor` reports insufficient resources in Colima, you can increase them with these commands:\n\n```bash\ncolima stop\ncolima start --cpu 4 --memory 8\n```\n\n---\n\n## Interactive Mode Tips\n\n- **Smart Project Detection**: `ldm` prioritizes project detection in this order:\n    1. Positional argument (e.g., `ldm run my-project`).\n    2. CLI flag (e.g., `ldm run -p my-project`).\n    3. The current working directory (if it's an LDM project).\n    4. An interactive list of all discovered projects.\n- **Quick Quit**: You can type `q` at any interactive prompt to safely abort the current command.\n- **Bypass Prompts**: Use the `-y` or `--non-interactive` flag to skip all confirmations and use default values. This is ideal for scripts and CI/CD pipelines.\n- **Tag Discovery**: When running `ldm run` without a version tag, the tool will offer to fetch the latest available tags from Docker Hub based on your release type preference (LTS, QR, etc.).\n\n---\n\n## 🛠️ Development \u0026 Building\n\nIf you want to contribute to LDM or test your changes locally, follow these steps.\n\n### 1. Run from Source (Live Development)\n\nThe easiest way to develop is to install LDM in \"editable\" mode. This allows your changes to the `ldm_core` package to take effect immediately.\n\n```bash\n# Clone the repo\ngit clone https://github.com/peterrichards-lr/liferay-docker-manager.git\ncd liferay-docker-manager\n\n# Install in editable mode\npip install -e .\n\n# Run the entry point\npython3 liferay_docker.py --help\n```\n\n### 2. Building Standalone Binaries\n\nYou can build a single-file executable to test how the tool behaves as a binary.\n\n#### **Option A: Shiv (Official CI Method)**\n\nUsed for macOS and Linux. Fast and lightweight, but requires `python3` to be present on the host.\n\n```bash\n# Build only\n./scripts/package-shiv.sh\n\n# Build and install to /usr/local/bin/ldm (requires sudo)\n./scripts/package-shiv.sh --install\n```\n\n#### **Option B: PyInstaller (True Standalone)**\n\nBundles the Python interpreter inside the file. Works even on machines without Python installed.\n\n```bash\n# Build only\n./scripts/package-pyinstaller.sh\n\n# Build and install to /usr/local/bin/ldm (requires sudo)\n./scripts/package-pyinstaller.sh --install\n```\n\nThe resulting binary will be found in the `dist/` folder (for PyInstaller) or the root (for Shiv).\n\n## License\n\nMIT © Peter Richards\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterrichards-lr%2Fliferay-docker-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeterrichards-lr%2Fliferay-docker-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterrichards-lr%2Fliferay-docker-manager/lists"}