{"id":21726951,"url":"https://github.com/wttech/aemc","last_synced_at":"2026-03-10T06:32:52.764Z","repository":{"id":64846009,"uuid":"575886592","full_name":"wttech/aemc","owner":"wttech","description":"AEM Compose (Core \u0026 CLI)","archived":false,"fork":false,"pushed_at":"2026-02-09T15:18:20.000Z","size":76508,"stargazers_count":53,"open_issues_count":52,"forks_count":9,"subscribers_count":6,"default_branch":"main","last_synced_at":"2026-02-09T19:09:39.050Z","etag":null,"topics":["adobe","adobe-experience-manager","aem","aemaacs","ansible","automation","configuration-management","devops","docker"],"latest_commit_sha":null,"homepage":"https://wttech.blog/blog/2023/get-your-aem-together-with-aem-compose/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wttech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-12-08T14:19:58.000Z","updated_at":"2026-02-09T15:18:26.000Z","dependencies_parsed_at":"2024-01-16T09:47:18.631Z","dependency_job_id":"955ea441-e8b3-47ce-b694-5af3cfe30a52","html_url":"https://github.com/wttech/aemc","commit_stats":{"total_commits":1009,"total_committers":14,"mean_commits":72.07142857142857,"dds":"0.21902874132804762","last_synced_commit":"39570dbfc4093acabb11f6bc342d0b14975519fd"},"previous_names":[],"tags_count":210,"template":false,"template_full_name":null,"purl":"pkg:github/wttech/aemc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wttech%2Faemc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wttech%2Faemc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wttech%2Faemc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wttech%2Faemc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wttech","download_url":"https://codeload.github.com/wttech/aemc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wttech%2Faemc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30326891,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T05:25:20.737Z","status":"ssl_error","status_checked_at":"2026-03-10T05:25:17.430Z","response_time":106,"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":["adobe","adobe-experience-manager","aem","aemaacs","ansible","automation","configuration-management","devops","docker"],"created_at":"2024-11-26T03:42:19.277Z","updated_at":"2026-03-10T06:32:52.736Z","avatar_url":"https://github.com/wttech.png","language":"Go","readme":"![AEM Compose Logo](https://github.com/wttech/aemc-ansible/raw/main/docs/logo-with-text.png)\n[![WTT Logo](https://github.com/wttech/aemc-ansible/raw/main/docs/wtt-logo.png)](https://www.wundermanthompson.com/service/technology)\n\n[![GitHub All Releases](https://img.shields.io/github/downloads/wttech/aemc/total)](https://github.com/wttech/aemc/releases)\n[![Last Release Version](https://img.shields.io/github/v/release/wttech/aemc?color=lightblue\u0026label=Last%20Release)](https://github.com/wttech/aemc/releases)\n![Go Version](https://img.shields.io/github/go-mod/go-version/wttech/aemc)\n[![Apache License, Version 2.0, January 2004](https://github.com/wttech/aemc-ansible/raw/main/docs/apache-license-badge.svg)](http://www.apache.org/licenses/)\n\n**AEM Compose**\n\nAEMC is a versatile tool for managing Adobe Experience Manager (AEM) instances. \nWith a comprehensive set of commands, it simplifies tasks such as working CRX packages, OSGi configurations, JCR repository nodes, and more. \nIts seamless integration with Terraform, Pulumi, and Ansible enhances automation capabilities.\n\n- Reusable core designed to handle advanced dev-ops operations needed to manage AEM instances\n- Various distributions based on core for context-specific use cases:\n  - [*CLI*](#cli---overview) - for developer workstations, shell scripting\n    - [AEM Project Quickstart](https://github.com/wttech/aemc#cli---aem-project-quickstart) - add development environment automation to the existing AEM projects\n    - [Docker Example](examples/docker) - for experiments only\n  - [*Terraform AEM Provider*](https://github.com/wttech/terraform-provider-aem) - set up with ease higher environments (VMs and AEM instances) in the cloud (AWS, Azure, GCP, etc.)\n  - [*Pulumi AEM Provider*](https://github.com/wttech/pulumi-aem-native) - working the same as Terraform AEM Provider but with Pulumi\n  - [*Ansible Collection/Modules*](#ansible-collection) - for managing higher AEM environments\n    - [Packer Example](https://github.com/wttech/aemc-ansible/tree/main/examples/packer) - starting point for baking AWS EC2 image using Ansible\n    - [Local Example](https://github.com/wttech/aemc-ansible/tree/main/examples/local) - development \u0026 testing sandbox for AEM Compose project\n- Fast \u0026 lightweight\n- Usable on all operating systems and architectures without pre-installing any dependencies\n\n# References\n\n* Blog Posts\n  * [Get your AEM together with AEM Compose!](https://wttech.blog/blog/2023/get-your-aem-together-with-aem-compose/) by [Krystian Panek](mailto:krystian.panek@vml.com)\n  * [Turning IDE into an AEM development powerhouse](https://wttech.blog/blog/2024/turning-ide-into-an-aem-development-powerhouse/) by [Krystian Panek](mailto:krystian.panek@vml.com) and [Dominik Przybył](mailto:dominik.przybyl@vml.com)\n* Talk at AdaptTo 2024 Conference - [First-ever IaC Providers for AEM](https://adapt.to/2024/schedule/lightning-talks/first-ever-iaac-providers-for-aem) by [Krystian Panek](mailto:krystian.panek@vml.com)\n* Talk at AdaptTo 2023 Conference - [Get Your AEM Together: AEM Compose, the Ultimate DevEx Tool](https://adapt.to/2023/schedule/get-your-aem-together-aem-compose-the-ultimate-devex-tool) by [Tomasz Sobczyk](mailto:tomasz.sobczyk@vml.com) \u0026 [Krystian Panek](mailto:krystian.panek@vml.com)\n\n[![AdaptTo 2023 Video](docs/adapto-to-video.png)](https://www.youtube.com/watch?v=EH4ubsxNpbs)\n\n# Table of Contents\n\n* [Distributions](#distributions)\n  * [CLI - Overview](#cli---overview)\n  * [CLI - Screenshots](#cli---screenshots)\n  * [CLI - AEM Project Quickstart](#cli---aem-project-quickstart)\n  * [IaaC Providers](#iaac-providers)\n  * [Ansible Collection](#ansible-collection)\n  * [Go Scripting](#go-scripting)\n* [Dependencies](#dependencies)\n* [Configuration](#configuration)\n  * [Generating default configuration](#generating-default-configuration)\n  * [Configuration precedence](#configuration-precedence)\n  * [Context-specific customization](#context-specific-customization)\n    * [Improving performance](#improving-performance)\n    * [Increasing verbosity](#increasing-verbosity)\n    * [Installing content packages](#installing-content-packages)\n    * [Installing packages with troubleshooting](#installing-packages-with-troubleshooting)\n* [Examples](#examples)\n  * [Replication agents](#replication-agents)\n  * [SSL by Default](#ssl-by-default)\n  * [Global Trust Store](#global-trust-store)\n* [Troubleshooting](#troubleshooting)\n* [Contributing](#contributing)\n* [Authors](#authors)\n* [License](#license)\n\n# Distributions\n\n## CLI - Overview\n\nProvides complete set of commands to comfortably work with CRX packages, OSGi configurations, repository nodes and more.\n\nKey assumptions:\n\n- Idempotent and fast\n- Rich configuration options\n- Self-describing, both machine \u0026 human-readable \n- Multiple input \u0026 output formats (text/yaml/json)\n\nMain features:\n\n- easy \u0026 declarative setup of:\n  - JDK (isolated, version tied to project)\n  - AEM instances (run modes, JVM \u0026 start opts, env \u0026 secret vars, Sling props, custom admin password)\n  - OSGi (configurations, bundles, components)\n  - Crypto Support, Trust Store, SSL by Default\n  - replication agents \n  - any repository nodes\n- deploying AEM packages with:\n  - efficiently upload with optimized memory usage (constant and independent of package size)\n  - automatic workflow toggling - avoiding DAM asset renditions regeneration\n  - advanced snapshot handling - avoiding redeploying the same package by checksum verification\n  - customizable instance health checking\n- building AEM packages with:\n  - source code change detection - avoiding rebuilding application when it is not needed (handled by [Taskfile](https://taskfile.dev/usage/#prevent-unnecessary-work))\n- making AEM instance backups (with restoring)\n  - advanced archive format to speed up performance and storage efficiency ([ZSTD](https://github.com/facebook/zstd) used by default)\n  - instance state aware - stopping, archiving then starting again AEM instances automatically (if needed)\n- content synchronization between running instance and local file system\n\nWorth knowing:\n\n- On Windows use it with [Git Bash](https://gitforwindows.org/) ([CMD](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cmd) and [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/overview) are not supported nor tested)\n\n## CLI - Screenshots\n\nHelp command:\n\n\u003cimg src=\"docs/cli-help-home.png\" alt=\"CLI Help Home\" width=\"600\"/\u003e\n\nInstance commands:\n\n\u003cimg src=\"docs/cli-help-instance.png\" alt=\"CLI Help Instance\" width=\"320\"/\u003e\n\nPackage commands:\n\n\u003cimg src=\"docs/cli-help-pkg.png\" alt=\"CLI Help Package\" width=\"320\"/\u003e\n\nSetup task:\n\n- AEM instances are provisioned only when the configuration is changed\n- AEM dispatcher set up using container engine, redeployed only when there are configuration changes as well\n- Health checks executed to confirm the stability of the environment as a whole\n\n\u003cimg src=\"docs/cli-demo-short.gif\" alt=\"CLI Demo\"/\u003e\n\n## CLI - AEM Project Quickstart\n\nSupported project types:\n\n- with structure based on [Adobe AEM Project Archetype](https://github.com/adobe/aem-project-archetype#usage), compatibility:\n\n  | AEM Compose | AEM Project Archetype  |\n  |-------------|------------------------|\n  | \u003e= 1.2.0    | 41, 42, 43, 47, 48, 51 |\n\n- with any type of structure, however afterwards only a little customizations in *Taskfile.yml* need to be done to reflect configuration related to built AEM application artifact path and AEM dispatcher files location,\n- empty folder; the project kind will be needed to be specified explicitly during scaffolding.\n\n---\n\nRun command below to install the AEM Compose tool in your project:\n\n```shell\ncurl https://raw.githubusercontent.com/wttech/aemc/main/project-install.sh | sh\n```\n\nAfter successful installation, remember to always use the tool via wrapper script in the following way:\n\n```shell\nsh aemw [command]\n```\n\nNext scaffold the AEM Compose files in the project:\n\n```shell\nsh aemw project scaffold\n```\n\nProject scaffolding:\n\n- sets up ready-to-use tasks powered by [Task tool](https://taskfile.dev/), which aggregate one or many AEM Compose CLI commands into useful procedures.\n- provides configuration for provisioning AEM instances (installing service pack, setting replication agents, etc.).\n- provides configuration for running AEM Dispatcher on [Podman](https://podman-desktop.io/) (by default) or [Docker](https://www.docker.com/products/docker-desktop/) (remember to install one of these tools before running the setup task).\n\nTo list all available tasks, run:\n\n```shell\nsh taskw --list\n```\n\nUsually, the first steps to take are:\n\n```shell\nsh taskw init\nsh taskw setup\n```\n\n## IaaC Providers\n\nThe tool is designed to be used in Infrastructure as a Code (IaaC) solutions such as [Terraform](https://www.terraform.io/) or [Pulumi](https://www.pulumi.com/).\n\nSee separate projects based on AEM Compose:\n\n- Terraform Provider: \u003chttps://github.com/wttech/terraform-provider-aem\u003e\n- Pulumi Provider: \u003chttps://github.com/wttech/pulumi-aem\u003e\n\n## Ansible Collection\n\nThe tool is designed to be used in Ansible playbooks and roles.\n\nSee a separate project based on AEM Compose: \u003chttps://github.com/wttech/aemc-ansible\u003e\n\n## Go Scripting\n\nConsider implementing any application on top of AEM Compose API like using snippet below:\n\nFile: *aem.go*\n\n```go\npackage main\n\nimport \"fmt\"\nimport \"os\"\nimport aemc \"github.com/wttech/aemc/pkg\"\n\nfunc main() {\n    aem := aemc.DefaultAEM()\n    instance, _ := aem.InstanceManager().NewByIDAndURL(\"remote_author\", \"http://admin:admin@192.168.1.2:4502\")\n    changed, err := instance.PackageManager().DeployWithChanged(\"/tmp/my-package.zip\")\n    if err != nil {\n        fmt.Printf(\"cannot deploy package: %s\\n\", err)\n        os.Exit(1)\n    }\n    if changed {\n      if err := aem.InstanceManager().AwaitStartedOne(*instance); err != nil {\n\t\t  fmt.Printf(\"instance not stable after deploying package: %s\\n\", err)\n\t\t  os.Exit(1)\n      }\n    }\n    fmt.Println(\"package deployed properly\")\n    os.Exit(0)\n}\n```\n\nThen to run application use command:\n\n```shell\ngo run aem.go\n```\n\n# Dependencies\n\nThis tool is written in Go. Go applications are very often self-sufficient which means that they are not relying on platform-specific libraries/dependencies. \nThe only requirement is to use proper tool binary distribution for each operating system and architecture.\nCheck out [releases page](https://github.com/wttech/aemc/releases) to review available binary distributions.\n\n# Configuration\n\n## Defaults\n\nThe tool tries to make configuration as much explicit as it could be to allow customization in an easy way.\n\nBelow are listed all available configuration options ([source](pkg/project/instance/aem/default/etc/aem.yml)):\n\n```shell\n# AEM instances to work with\ninstance:\n\n  # Full details of local or remote instances\n  config:\n    local_author:\n      active: [[.Env.AEM_AUTHOR_ACTIVE | default true ]]\n      http_url: [[.Env.AEM_AUTHOR_HTTP_URL | default \"http://127.0.0.1:4502\" ]]\n      user: [[.Env.AEM_AUTHOR_USER | default \"admin\" ]]\n      password: [[.Env.AEM_AUTHOR_PASSWORD | default \"admin\" ]]\n      run_modes: [ local ]\n      jvm_opts:\n        - -server\n        - -Djava.awt.headless=true\n        - -Djava.io.tmpdir=[[canonicalPath .Path \"aem/home/tmp\"]]\n        - -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=[[.Env.AEM_AUTHOR_DEBUG_ADDR | default \"0.0.0.0:14502\" ]]\n        - -Duser.language=en\n        - -Duser.country=US\n        - -Duser.timezone=UTC\n      start_opts: []\n      secret_vars:\n        - ACME_SECRET=value\n      env_vars:\n        - ACME_VAR=value\n      sling_props: []\n    local_publish:\n      active: [[.Env.AEM_PUBLISH_ACTIVE | default true ]]\n      http_url: [[.Env.AEM_PUBLISH_HTTP_URL | default \"http://127.0.0.1:4503\" ]]\n      user: [[.Env.AEM_PUBLISH_USER | default \"admin\" ]]\n      password: [[.Env.AEM_PUBLISH_PASSWORD | default \"admin\" ]]\n      run_modes: [ local ]\n      jvm_opts:\n        - -server\n        - -Djava.awt.headless=true\n        - -Djava.io.tmpdir=[[canonicalPath .Path \"aem/home/tmp\"]]\n        - -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=[[.Env.AEM_PUBLISH_DEBUG_ADDR | default \"0.0.0.0:14503\" ]]\n        - -Duser.language=en\n        - -Duser.country=US\n        - -Duser.timezone=UTC\n      start_opts: []\n      secret_vars:\n        - ACME_SECRET=value\n      env_vars:\n        - ACME_VAR=value\n      sling_props: []\n\n  # Tuning performance \u0026 reliability\n  # 'auto'     - for more than 1 local instances - 'serial', otherwise 'parallel'\n  # 'parallel' - for working with remote instances\n  # 'serial'   - for working with local instances\n  processing_mode: auto\n\n  # HTTP client settings\n  http:\n    timeout: 10m\n    debug: false\n    disable_warn: true\n\n  # State checking\n  check:\n    # Time to wait before first state checking (to avoid false-positives)\n    warmup: 1s\n    # Time to wait for next state checking\n    interval: 6s\n    # Number of successful check attempts that indicates end of checking\n    done_threshold: 4\n    # Max time to wait for the instance to be healthy after executing the start script or e.g deploying a package\n    await_started:\n      timeout: 30m\n    # Max time to wait for the instance to be stopped after executing the stop script\n    await_stopped:\n      timeout: 10m\n    # Max time in which socket connection to instance should be established\n    reachable:\n      timeout: 3s\n    # Bundle state tracking\n    bundle_stable:\n      symbolic_names_ignored: []\n    # OSGi events tracking\n    event_stable:\n      # Topics indicating that instance is not stable\n      topics_unstable:\n        - \"org/osgi/framework/ServiceEvent/*\"\n        - \"org/osgi/framework/FrameworkEvent/*\"\n        - \"org/osgi/framework/BundleEvent/*\"\n      # Ignored service names to handle known issues\n      details_ignored:\n        - \"*.*MBean\"\n        - \"org.osgi.service.component.runtime.ServiceComponentRuntime\"\n        - \"java.util.ResourceBundle\"\n      received_max_age: 5s\n    # OSGi components state tracking\n    component_stable:\n      skip: false\n      pids:\n        include: ['com.day.crx.packaging.*', 'org.apache.sling.installer.*']\n        exclude: ['org.apache.sling.installer.hc.*', 'org.apache.sling.installer.core.impl.console.*']\n        match:\n          \"disabled\": []\n          \"no config\": []\n          \"unsatisfied (reference)\": []\n          \"satisfied\": []\n    # Sling Installer tracking\n    installer:\n      # JMX state checking\n      state: true\n      # Pause Installation nodes checking\n      pause: true\n\n  # Managed locally (set up automatically)\n  local:\n    # Wait only for those instances whose state has been changed internally (unaware of external changes)\n    await_strict: true\n\n    # Current runtime dir (Sling launchpad, JCR repository)\n    unpack_dir: \"aem/home/var/instance\"\n    # Archived runtime dir (AEM backup files '*.aemb.zst')\n    backup_dir: \"aem/home/var/backup\"\n\n  # Status discovery (timezone, AEM version, etc)\n  status:\n    timeout: 500ms\n\n  # JCR Repository\n  repo:\n    property_change_ignored:\n      # AEM assigns them automatically\n      - \"jcr:created\"\n      - \"cq:lastModified\"\n      # AEM encrypts it right after changing by replication agent setup command\n      - \"transportPassword\"\n\n  # CRX Package Manager\n  package:\n    # Force re-uploading/installing of snapshot AEM packages (just built / unreleased)\n    snapshot_patterns: [ \"**/*-SNAPSHOT.zip\" ]\n    # Use checksums to avoid re-deployments when snapshot AEM packages are unchanged\n    snapshot_deploy_skipping: true\n    # Disable following workflow launchers for a package deployment time only\n    toggled_workflows: [/libs/settings/workflow/launcher/config/asset_processing_on_sdk_*,/libs/settings/workflow/launcher/config/update_asset_*,/libs/settings/workflow/launcher/config/dam_*]\n    # Also sub-packages\n    install_recursive: true\n    # Use slower HTML endpoint for deployments but with better troubleshooting\n    install_html:\n      enabled: false\n      # Print HTML directly to console instead of writing to file\n      console: false\n      # Fail on case 'installed with errors'\n      strict: true\n    # Number of changes after which the commit to the repository is performed\n    install_save_threshold: 1024\n    # Allows to relax dependency handling if needed\n    install_dependency_handling: required\n    # Controls how 'rep:policy' nodes are handled during import\n    install_ac_handling: ''\n\n  # OSGi Framework\n  osgi:\n    bundle:\n      install:\n        start: true\n        start_level: 20\n        refresh_packages: true\n\n  # Crypto Support\n  crypto:\n    key_bundle_symbolic_name: com.adobe.granite.crypto.file\n\n  # Workflow Manager\n  workflow:\n    launcher:\n      lib_root: /libs/settings/workflow/launcher\n      config_root: /conf/global/settings/workflow/launcher\n      toggle_retry:\n        timeout: 10m\n        delay: 10s\n\njava:\n  # Require following versions before e.g running AEM instances\n  version_constraints: [\"\u003e= 1.8, \u003c 1.9\", \"\u003e= 11, \u003c 12\", \"\u003e= 17, \u003c 18\", \"\u003e= 21, \u003c 22\"]\n\n  # Pre-installed local JDK dir\n  # a) keep it empty to download open source Java automatically for current OS and architecture\n  # b) set it to absolute path or to env var '[[.Env.JAVA_HOME]]' to indicate where closed source Java like Oracle is installed\n  home_dir: \"\"\n\n  # Auto-installed JDK options\n  download:\n    # Source URL with template vars support\n    url: \"https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.25%2B9/OpenJDK11U-jdk_[[.Arch]]_[[.Os]]_hotspot_11.0.25_9.[[.ArchiveExt]]\"\n    # Map source URL template vars to be compatible with Adoptium Java\n    replacements:\n      # Var 'Os' (GOOS)\n      \"darwin\": \"mac\"\n      # Var 'Arch' (GOARCH)\n      \"x86_64\": \"x64\"\n      \"amd64\": \"x64\"\n      \"386\": \"x86-32\"\n      # enforce non-ARM Java as some AEM features are not working on ARM (e.g Scene7)\n      \"arm64\": \"x64\"\n      \"aarch64\": \"x64\"\n\nbase:\n  # Location of temporary files (downloaded AEM packages, etc)\n  tmp_dir: aem/home/tmp\n  # Location of supportive tools (downloaded Java, OakRun, unpacked AEM SDK)\n  tool_dir: aem/home/opt\n\nlog:\n  level: info\n  timestamp_format: \"2006-01-02 15:04:05\"\n  full_timestamp: true\n\ninput:\n  format: yml\n  file: STDIN\n\noutput:\n  format: text\n  log:\n    # File path of logs written especially when output format is different than 'text'\n    file: aem/home/var/log/aem.log\n    # Controls where outputs and logs should be written to when format is 'text' (console|file|both)\n    mode: console\n\nvendor:\n  # AEM instance source files\n  quickstart:\n    # AEM SDK ZIP or JAR\n    dist_file: 'aem/home/lib/{aem-sdk,cq-quickstart}-*.{zip,jar}'\n    # AEM License properties file\n    license_file: \"aem/home/lib/license.properties\"\n\n  # JDK used to: run AEM instances, build OSGi bundles, assemble AEM packages\n  java:\n    # Require following versions before e.g running AEM instances\n    version_constraints: [\"\u003e= 1.8, \u003c 1.9\", \"\u003e= 11, \u003c 12\", \"\u003e= 17, \u003c 18\", \"\u003e= 21, \u003c 22\"]\n\n    # Pre-installed local JDK dir\n    # a) keep it empty to download open source Java automatically for current OS and architecture\n    # b) set it to absolute path or to env var '[[.Env.JAVA_HOME]]' to indicate where closed source Java like Oracle is installed\n    home_dir: \"\"\n\n    # Auto-installed JDK options\n    download:\n      # Source URL with template vars support\n      url: \"https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.25%2B9/OpenJDK11U-jdk_[[.Arch]]_[[.Os]]_hotspot_11.0.25_9.[[.ArchiveExt]]\"\n      # Map source URL template vars to be compatible with Adoptium Java\n      replacements:\n        # Var 'Os' (GOOS)\n        \"darwin\": \"mac\"\n        # Var 'Arch' (GOARCH)\n        \"x86_64\": \"x64\"\n        \"amd64\": \"x64\"\n        \"386\": \"x86-32\"\n        # enforce non-ARM Java as some AEM features are not working on ARM (e.g Scene7)\n        \"arm64\": \"x64\"\n        \"aarch64\": \"x64\"\n\n  # Oak Run tool options (offline instance management)\n  oak_run:\n    download_url: \"https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/1.72.0/oak-run-1.72.0.jar\"\n    store_path: \"crx-quickstart/repository/segmentstore\"\n\n# Source files\nquickstart:\n  # AEM SDK ZIP or JAR\n  dist_file: \"aem/home/lib/{aem-sdk,cq-quickstart}-*.{zip,jar}\"\n  # AEM License properties file\n  license_file: \"aem/home/lib/license.properties\"\n\n# Content clean options\ncontent:\n  clean:\n    # File patterns to be deleted\n    files_deleted:\n      - patterns:\n          - \"**/.vlt\"\n          - \"**/.vlt*.tmp\"\n          - \"**/install/*.jar\"\n    # File patterns to be flattened\n    files_flattened:\n      - \"**/_cq_design_dialog/.content.xml\"\n      - \"**/_cq_dialog/.content.xml\"\n      - \"**/_cq_htmlTag/.content.xml\"\n      - \"**/_cq_template/.content.xml\"\n    # Property patterns to be skipped, removed from cleaned file\n    properties_skipped:\n      - patterns: \"jcr:uuid\"\n        excluded_paths: [ \"**/home/users/*\", \"**/home/groups/*\" ]\n      - patterns: \"cq:lastModified*\"\n        excluded_paths: [ \"**/content/experience-fragments/*\" ]\n      - patterns: [ \"dam:sha1\", \"dam:size\" ]\n        included_paths: [ \"**/content/dam/*.svg/*\" ]\n      - patterns:\n          - \"jcr:lastModified*\"\n          - \"jcr:created*\"\n          - \"jcr:isCheckedOut\"\n          - \"cq:lastReplicat*\"\n          - \"cq:lastRolledout*\"\n          - \"dam:extracted\"\n          - \"dam:assetState\"\n          - \"dc:modified\"\n          - \"*_x0040_*\"\n          - \"cq:name\"\n          - \"cq:parentPath\"\n          - \"dam:copiedAt\"\n          - \"dam:parentAssetID\"\n          - \"dam:relativePath\"\n    # Mixin type patterns to be skipped, removed from cleaned file\n    mixin_types_skipped:\n      - patterns:\n          - \"cq:ReplicationStatus\"\n          - \"mix:versionable\"\n    # Unused namespaces to be skipped, removed from cleaned file\n    namespaces_skipped: true\n```\n\nNote that environment variables may be injected in any part of config file. \nEnvironment variables could be defined in one or many [dotenv files](https://github.com/wttech/aemc/blob/main/pkg/common/osx/osx.go#L32).\n\n## Overriding default configuration\n\nBy default, the VCS-tracked file is loaded (*aem/default/etc*).\nHowever, occasionally developers might want to override the default config file and load a VCS-ignored file instead (*aem/home/etc/aem.yml*).\n\nTo do so, run the command:\n\n```shell\nsh aemw config init\n```\n\n## Configuration precedence\n\nAll configuration options specified in file *aem.yml* could be overridden by environment variables.\nSimply add prefix `AEM_` then each level of nested YAML object join with `_` and lowercase the name of each object.\n\nFor example: `instance.local.quickstart.dist_file` could be overridden by environment variable `AEM_INSTANCE_LOCAL_QUICKSTART_DIST_FILE`\n\nAlso note that some configuration options may be ultimately overridden by CLI flags, like `--output-format`.\n\n## Context-specific customization\n\nBy default, fail-safe options are in use. However, consider using the configuration options listed below to achieve a more desired tool experience. \n\n### Improving performance\n\n  ```shell\n  export AEM_INSTANCE_PROCESSING_MODE=parallel\n  ```\n\n  This setting will significantly reduce command execution time. Although be aware that when deploying heavy AEM packages like Service Packs on the same machine in parallel, a heavy load could be observed, which could lead to unpredicted AEM CMS and AEM Compose tool behavior.\n\n### Increasing verbosity\n\n  ```shell\n  export AEM_OUTPUT_VALUE=ALL\n  ```\n\n  Setting this environment variable will instruct the tool to request from the AEM instance descriptive information about the recently executed command subject.\n  For example, if a recently executed command was `sh aemw package deploy my-package.zip -A` the AEM Compose tool after doing the actual package deployment will request from CRX Package Manager the exact information about just deployed package.\n  This feature is beneficial for clarity and debugging purposes.\n\n### Installing content packages\n\nTo install larger AEM packages that may include content pages, assets, and more, you can adjust the HTTP timeout setting. \nBy default, the timeout is set to `10m`, but you have the option to increase it (e.g., to `3h`) or disable it completely (by using `0`).\n\nTo set the timeout for a single AEMC command, use the following syntax:\n\n```shell\nAEM_INSTANCE_HTTP_TIMEOUT=0 sh aemw package deploy --file my-package.zip\n```\n\nIt's important to be aware that AEMaaCS also has its own timeout for requests made to the Package Manager UI. For detailed information, please refer to the [documentation](https://experienceleague.adobe.com/docs/experience-manager-cloud-service/content/implementing/developer-tools/package-manager.html?lang=en#aemaacs-packages).\n\nTo skip the instance health check after running a command that would normally trigger it, `AEM_INSTANCE_CHECK_SKIP` environment variable can be used. This can save a lot of time when deploying a lot of packages sequentially.\n\nTo skip the instance health check for a single AEMC command, use the following syntax:\n\n```shell\nAEM_INSTANCE_CHECK_SKIP=true sh aemw package deploy --file my-package.zip\n```\n\n### Installing packages with troubleshooting\n\nStarting from version 1.4.0 (see [#177](https://github.com/wttech/aemc/pull/177)), AEMC now supports AEM package installations using an HTML report serving endpoint, similar to CRX Package Manager's. While this method may result in slightly extended installation times, it provides a comprehensive HTML report detailing the package installation process.\n\nThis new feature offers two distinct modes for leveraging its benefits:\n\n1. Saving HTML report to file:\n\n   ```shell\n   AEM_INSTANCE_PACKAGE_INSTALL_HTML_ENABLED=true sh aemw package deploy --file my-package.zip\n   ```\n\n2. Direct console output of HTML report:\n\n   ```shell\n   AEM_INSTANCE_PACKAGE_INSTALL_HTML_ENABLED=true AEM_INSTANCE_PACKAGE_INSTALL_HTML_CONSOLE=true sh aemw package deploy --file my-package.zip\n   ```\n\n# Examples\n\n## Replication agents\n\n1. Configuring publish agent on AEM author:\n\n    ```shell\n    PROPS=\"\n    enabled: true\n    transportUri: http://localhost:4503/bin/receive?sling:authRequestLogin=1\n    transportUser: admin\n    transportPassword: admin\n    userId: admin\n    \"\n    echo \"$PROPS\" | sh aemw repl agent setup -A --location \"author\" --name \"publish\"\n    ```\n\n2. Configuring flush agent on AEM publish:\n\n    ```shell\n    PROPS=\"\n    enabled: true\n    transportUri: http://localhost/dispatcher/invalidate.cache\n    protocolHTTPHeaders:\n    - 'CQ-Action: {action}'\n    - 'CQ-Handle: {path}'\n    - 'CQ-Path: {path}'\n    - 'Host: flush'\n    \"\n    echo \"$PROPS\" | sh aemw repl agent setup -P --location \"publish\" --name \"flush\"\n    ```\n   If needed, update `localhost` to the value on which AEM dispatcher is available, e.g.`localhost:8080`.\n\n## SSL by Default\n\nAEM Compose supports *SSL by Default* feature of AEM.\n\nThis feature requires:\n- certificate file in PEM format\n- private key file in DER or PEM format\n- password for keystore (has to be the same for each invocation of the tool)\n- password for truststore (can be different for each invocation of the tool)\n- hostname for HTTPS connector (used by AEM to check if the setup was successful; has to be reachable by AEM)\n- port for HTTPS connector\n\nTo set up *SSL by Default*, run:\n\n```shell\nsh aemw ssl setup \\\n   --instance-author\n   --keystore-password password \\\n   --truststore-password password1 \\\n   --certificate-file localhost.crt \\\n   --private-key-file localhostprivate.key \\\n   --https-hostname localhost \\\n   --https-port 8443\n\nsh aemw ssl setup \\\n   --instance-publish\n   --keystore-password password \\\n   --truststore-password password1 \\\n   --certificate-file localhost.crt \\\n   --private-key-file localhostprivate.key \\\n   --https-hostname localhost \\\n   --https-port 9443\n```\n\nAbove example uses the self-signed certificate created as per the AEM docs.\n\nSee the reference documentation: [AEM 6.5 \u003e Administering Guide \u003e SSL by Default](https://experienceleague.adobe.com/docs/experience-manager-65/administering/security/ssl-by-default.html?lang=en)\n\nFor local environment remember to set different port numbers for author and publish instances.\n\n## Global Trust Store\n\nAEM Compose supports managing the trust store of AEM instances.\n\nThis feature supports:\n\n- creation of the general trust store if it does not exist\n    ```shell\n    sh aemw gts create --password PASSWORD_HERE -A\n    ```\n\n- getting the general trust store status\n    ```shell\n    sh aemw gts status -A\n    ```\n\n- adding a certificate to the general trust store\n    ```shell\n    sh aemw gts certificate add --path \u003cpath\u003e -A\n    ```\n  \nThis command will add a certificate to the general trust store only if not exists in trust store and will return the alias of the certificate.\nCommand `certificate add` supports certificates in PEM and DER formats.\n\n- reading a certificate from the general trust store (by alias)\n    ```shell\n    sh aemw gts certificate read --alias \u003calias\u003e -A\n    ```\n\n- removing a certificate from the general trust store (by alias)\n    ```shell\n    sh aemw gts certificate remove --alias \u003calias\u003e -A\n    ```\n\n\n# Troubleshooting\n\n## Migration from Gradle plugins\n\nIf you're migrating from [Gradle AEM Plugin](https://github.com/wttech/gradle-aem-plugin) you may run into issue with setting up dispatcher.\nIn case of error when running task dispatcher:start or dispatcher:setup:\n\n```\n2024-01-22 16:37:23 dispatcher  | 2024/01/22 15:37:23 Dispatcher configuration validation failed:\n2024-01-22 16:37:23 dispatcher  | 2024/01/22 15:37:23   /mnt/dev/src/conf.d/variables/default.vars: lstat /etc/httpd.extra: no such file or directory\n2024-01-22 16:37:23 dispatcher  |\n2024-01-22 16:37:23 dispatcher  | ERROR Mon Jan 22 15:37:23 UTC 2024 Configuration invalid, please fix and retry,\n2024-01-22 16:37:23 dispatcher  |               Line numbers reported are correct for your configuration files.\n```\n\nCheck if there is a broken symlink/file in `dispatcher/src/variables/default.vars`. If the file exists, delete it and\nrun the task again.\n\n## Exception while unpacking dispatcher on Linux\n\nIf you're setting up your instance for the first time on a Linux OS (i.e. Ubuntu with Gnome Shell), you may stumble upon the following error:\n\n```\nINFO[2025-02-27 13:17:09] preparing new SDK 'aem/home/lib/aem-sdk-2025.2.19687.20250225T164325Z-250100.zip'\nINFO[2025-02-27 13:17:09] unpacking SDK ZIP 'aem/home/lib/aem-sdk-2025.2.19687.20250225T164325Z-250100.zip' to dir 'aem/home/opt/sdk'\nINFO[2025-02-27 13:17:09] unpacked SDK ZIP 'aem/home/lib/aem-sdk-2025.2.19687.20250225T164325Z-250100.zip' to dir 'aem/home/opt/sdk'\nINFO[2025-02-27 13:17:09] unpacking SDK dispatcher tools using script 'aem/home/opt/sdk/aem-sdk-dispatcher-tools-2.0.235-unix.sh' to dir 'aem/home/opt/sdk/dispatcher'\n# Failed to parse arguments: Unknown option -title\nERRO[2025-02-27 13:17:10] cannot run SDK dispatcher tools unpacking script 'aem/home/opt/sdk/aem-sdk-dispatcher-tools-2.0.235-unix.sh': exit status 1\ngetting started\n  AEM Compose project is not yet ready to use!\n\n  Be sure to provide AEM files (SDK ZIP or Quickstart JAR + License + Service Packs) to directory 'aem/home/lib'.\ntask: Failed to run task \"init\": exit status 1\n```\n\nImportant line is `Unknown option -title`.\n\nTo fix this, **make sure that `xterm` is installed and available on your system**, and re-run the task.\n\n# Contributing\n\nIssues reported or pull requests created will be very appreciated.\n\n1. Fork plugin source code using a dedicated GitHub button.\n2. See [development guide](DEVELOPMENT.md)\n3. Do code changes on a feature branch created from *main* branch.\n4. Create a pull request with a base of *main* branch.\n\n# Authors\n\n- Creator, owner, and maintainer: [Krystian Panek](mailto:krystian.panek@vml.com)\n- Consultancy: [Tomasz Sobczyk](mailto:tomasz.sobczyk@vml.com), [Maciej Majchrzak](mailto:maciej.majchrzak@vml.com)\n- Contributors: [\u0026lt;see all\u0026gt;](https://github.com/wttech/aemc/graphs/contributors)\n\n# License\n\n**AEM Compose** is licensed under the [Apache License, Version 2.0 (the \"License\")](https://www.apache.org/licenses/LICENSE-2.0.txt)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwttech%2Faemc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwttech%2Faemc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwttech%2Faemc/lists"}