Skip to main content
RajulPr
Level 2
September 28, 2026
New

Building a Production-Like AEM Local Development Environment with Docker

  • September 28, 2026
  • 0 replies
  • 9 views

A comprehensive guide to isolated Dev and QA environments with AEM Author, Publish, Dispatcher, Nginx, persistent storage, and WKND validation

 

Local AEM development often begins with a single Author instance. That is sufficient for early coding, but it does not validate the complete delivery path. A mature local setup should make it easy to test Publish behavior, Dispatcher filters and caching, environment-specific configuration, content activation, reverse-proxy routing, and repeatable environment lifecycle management.

 

PURPOSE 

This guide presents a reproducible, Docker-based approach to local development and QA validation. It mirrors production engineering practices but does not replace AEM as a Cloud Service environments, Cloud Manager, or Adobe-supported production deployment models.

 

What you will build

  • Two isolated environments: Development and QA
  • AEM Author and Publish services in each environment
  • Apache HTTP Server with Dispatcher in front of Publish
  • Optional Nginx reverse proxy for friendly local domains
  • Persistent volumes for repositories and logs
  • Environment-specific run modes and configuration
  • WKND-based end-to-end validation
  • Operational commands, troubleshooting guidance, and security guardrails

Who this guide is for

AEM developers, technical leads, architects, DevOps engineers, and team members responsible for onboarding or standardizing local development environments.

Guide map

01

Why Docker for AEM

02

Reference architecture

03

Prerequisites and capacity planning

04

Repository and configuration model

05

Docker Compose foundation

06

Dispatcher and Nginx

07

WKND validation workflow

08

Daily operations

09

Troubleshooting playbook

10

Security, limitations, and next steps

 

01   Why Docker for AEM development?

Docker does not remove the complexity of AEM. It makes that complexity explicit, versionable, and repeatable. The value comes from codifying service relationships, configuration, ports, networks, storage, and startup behavior so that the wider team can reproduce the same environment.

Consistency

Developers use the same service topology and configuration model, reducing machine-specific differences.

Isolation

Dev and QA repositories, caches, logs, and networks remain separate.

Repeatability

Compose commands provide a predictable lifecycle for start, stop, rebuild, and reset.

Portability

The environment definition can be version-controlled alongside project documentation.

Earlier validation

Developers can test the Browser → Proxy → Dispatcher → Publish route before promoting changes.

 

KEY IDEA 

Do not optimize for the maximum number of containers on day one. Begin with one Author, one Publish, and the official local Dispatcher runtime. Add a second isolated environment after the first path is stable.

 

02   Reference architecture

The reference topology uses two independent Compose projects. Each project has its own network, named volumes, ports, service names, and environment file.

AEM Author

AEM Publish

Dispatcher

Nginx

Content & admin

Delivery runtime

Cache & filter

Local front door

DEVELOPMENT   •   HOST PORTS 4502 / 4503 / 8080 / 80

AEM Author

AEM Publish

Dispatcher

Nginx

Content & admin

Delivery runtime

Cache & filter

Local front door

QA   •   HOST PORTS 4512 / 4513 / 8081 / 81

Request path

Browser   →   Nginx   →   Apache Dispatcher   →   AEM Publish

 

Author remains available for authoring, package management, administration, and activation. Publish receives activated content and serves delivery requests through Dispatcher.

Port plan

Service

Development

QA

AEM Author

4502

4512

AEM Publish

4503

4513

Dispatcher

8080

8081

Nginx

80

81

Author debugger

30303

30313

Publish debugger

30304

30314

 

03   Prerequisites and capacity planning

Required software and artifacts

  1. A supported Java installation matched to the AEM SDK version used by the project.
  2. The AEM as a Cloud Service SDK, including the local Quickstart JAR and compatible Dispatcher Tools.
  3. Docker Desktop or Docker Engine with the Docker Compose plugin.
  4. A Git client and sufficient permissions to update the local hosts file.
  5. A compatible WKND release, if reference content is required for validation.

 

 

LICENSE AND DISTRIBUTION 

Do not commit AEM Quickstart JARs, licensed SDK assets, credentials, private keys, or proprietary content packages to source control or publish them in public container registries.

 

Suggested workstation baseline

Resource

Starting point

Recommended for two environments

CPU

4 cores

6–8 cores when running both environments

Memory

8 GB available

16 GB or more preferred

Storage

SSD with free capacity

60 GB or more for images, volumes, and logs

Treat these figures as planning guidance rather than fixed product requirements. Measure actual utilization for your SDK, project codebase, package set, and host operating system.

04   Repository and configuration model

Recommended repository structure

aem-local/

├── compose.yaml

├── compose.dev.yaml

├── compose.qa.yaml

├── .env.dev

├── .env.qa

├── aem/

│   ├── author/

│   └── publish/

├── dispatcher/

│   └── src/

├── nginx/

│   └── conf.d/

├── packages/

└── scripts/

 

Environment-specific settings

COMPOSE_PROJECT_NAME=aem-dev

AUTHOR_PORT=4502

PUBLISH_PORT=4503

DISPATCHER_PORT=8080

NGINX_PORT=80

AUTHOR_RUNMODES=author,dev

PUBLISH_RUNMODES=publish,dev

DOMAIN_NAME=local-dev.aemaacs.com

 

Store non-sensitive differences in environment files. Keep secrets in untracked local files or an approved secret-management mechanism.

Run-mode configuration

config.author.dev

config.publish.dev

config.author.qa

config.publish.qa

 

 

DESIGN RULE 

Use run modes only for configuration that genuinely differs by tier or environment. Avoid duplicating configuration when the same value should be shared.

 

05   Docker Compose foundation

The following excerpt illustrates service relationships and storage. Adapt image-building details, users, permissions, health checks, and startup commands to your organization’s approved local-development pattern.

services:

  author:

    build: ./aem/author

    ports:

      - "${AUTHOR_PORT}:4502"

    volumes:

      - author-data:/opt/aem/crx-quickstart/repository

      - author-logs:/opt/aem/crx-quickstart/logs

    networks: [aem-network]

 

  publish:

    build: ./aem/publish

    ports:

      - "${PUBLISH_PORT}:4503"

    volumes:

      - publish-data:/opt/aem/crx-quickstart/repository

      - publish-logs:/opt/aem/crx-quickstart/logs

    networks: [aem-network]

 

  dispatcher:

    build: ./dispatcher

    depends_on: [publish]

    ports:

      - "${DISPATCHER_PORT}:8080"

    networks: [aem-network]

 

  nginx:

    image: nginx:stable

    depends_on: [dispatcher]

    ports:

      - "${NGINX_PORT}:80"

    networks: [aem-network]

 

volumes:

  author-data:

  author-logs:

  publish-data:

  publish-logs:

 

networks:

  aem-network:

 

Persistence strategy

  • Use named volumes for repository data and logs.
  • Keep Dev and QA volume names independent.
  • Use bind mounts primarily for source-controlled configuration or package input.
  • Document the reset behavior clearly because deleting volumes destroys local repository data.

06   Dispatcher and Nginx

Use compatible Dispatcher Tools

Build the local Dispatcher from the tools delivered with the AEM SDK and validate configuration using the SDK utilities. This helps align the local Dispatcher configuration with supported cloud deployment patterns.

Filter strategy

Adopt a deny-by-default model and allow only the methods and URL patterns required by the application. The following is conceptual only and must not be copied as a complete production security policy:

/0001 { /type "allow" /method "GET" /url "/content/*" }

/0002 { /type "allow" /method "GET" /url "/etc.clientlibs/*" }

/9999 { /type "deny"  /url "*" }

 

 

SECURITY CHECK 

Review administrative, diagnostic, repository, authoring, internal, and custom API endpoints. A broad allow rule can unintentionally expose sensitive functionality.

 

Caching considerations

  • Authentication and authorization
  • Personalized or cookie-dependent responses
  • Query-parameter handling
  • Cache invalidation and stat-file behavior
  • Vanity URLs, redirects, error pages, and client libraries
  • GraphQL and other API responses

Nginx reverse proxy

server {

    listen 80;

    server_name local-dev.aemaacs.com;

 

    location / {

        proxy_pass http://dispatcher:8080;

        proxy_set_header Host $host;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

    }

}

 

Add the domain names to the local hosts file:

127.0.0.1 local-dev.aemaacs.com

127.0.0.1 local-qa.aemaacs.com

 

07   WKND validation workflow

WKND provides reference content and application behavior that can be used to validate the complete local delivery chain. Choose a release compatible with the project’s AEM SDK and Java version.

  1. Deploy the compatible WKND package to Author.
  2. Confirm the site renders on Author.
  3. Configure and test local activation or replication to Publish.
  4. Publish the required site content and dependencies.
  5. Verify the page directly on Publish.
  6. Verify the same page through Dispatcher.
  7. Verify the page through the Nginx domain.
  8. Repeat an eligible request and inspect whether Dispatcher serves it from cache.

 

 

SUCCESS CRITERIA 

Complete the test only when content is visible through the full path and expected security and caching behavior can be demonstrated.

 

08   Daily operations

Start Development

docker compose --env-file .env.dev -f compose.yaml -f compose.dev.yaml up -d

 

Start QA

docker compose --env-file .env.qa -f compose.yaml -f compose.qa.yaml up -d

 

Inspect status and logs

docker compose ps

docker compose logs -f

docker compose logs -f author

docker stats

 

Stop or reset

# Preserve named volumes

docker compose down

 

# Destructive reset: remove named volumes

docker compose down --volumes

 

09   Troubleshooting playbook

Symptom

What to inspect

AEM does not become ready

Check Java/SDK compatibility, memory, disk, permissions, repository health, and container logs.

Host port is in use

Identify the owning process or change the host-side port in the environment file.

Dispatcher fails to start

Run the validator supplied with the matching Dispatcher Tools package and inspect Apache logs.

Content is not cached

Review filters, cache rules, response headers, cookies, query handling, permissions, and invalidation.

Local domain does not resolve

Check the hosts file, proxy port mapping, Nginx configuration, and forwarded Host header.

Dev communicates with QA

Inspect network membership and ensure services are attached only to the intended project network.

 

Useful port checks

# macOS / Linux

lsof -i :4502

 

# Windows PowerShell / Command Prompt

netstat -ano | findstr :4502

 

10   Security, limitations, and next steps

Security checklist

  • Keep SDK artifacts, credentials, and keys out of Git.
  • Do not publish images containing licensed AEM binaries to public registries.
  • Bind local-only services to loopback where appropriate.
  • Use explicit Dispatcher allowlists and test denied paths.
  • Use read-only mounts for configuration inputs when possible.
  • Maintain base images and scan them according to organizational policy.
  • Back up important named volumes before destructive reset operations.

Understand the boundary

A local SDK environment supports rapid development and validation, but it does not reproduce every service, operational control, deployment behavior, or managed capability available in AEM as a Cloud Service. Use Cloud Manager and appropriate Adobe environments for cloud deployment validation.

Recommended enhancements

  • Health checks and readiness gates
  • Local HTTPS and certificate handling
  • Automated Dispatcher validation in CI
  • Smoke tests for Author, Publish, Dispatcher, and proxy routes
  • Centralized logs or lightweight local observability
  • Backup and restore scripts for named volumes
  • Documented image-version and SDK-version compatibility matrix

Conclusion

A successful Docker-based AEM environment is more than a containerized Quickstart JAR. It is a reproducible engineering platform that codifies the complete local request path, separates environment data, validates Dispatcher behavior early, and gives every developer a consistent operating model.

Start small, validate the full path, and expand deliberately. Once the first Author, Publish, and Dispatcher stack is reliable, add QA isolation, custom domains, automated checks, and observability. The result is a practical foundation for development, troubleshooting, demonstrations, training, and team onboarding.

 

COMMUNITY QUESTION 

How is your team standardizing local AEM environments? Share your approach to Author, Publish, Dispatcher, containers, and environment isolation.

 

References

Local Development Environment for AEM as a Cloud Service

Adobe Experience League  •  https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/local-development-environment-set-up/overview 

Set up local AEM SDK

Adobe Experience League  •  https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/local-development-environment-set-up/aem-runtime 

Set up local Dispatcher Tools

Adobe Experience League  •  https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/local-development-environment-set-up/dispatcher-tools 

Dispatcher in the Cloud

Adobe Experience League  •  https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/content-delivery/disp-overview 

AEM as a Cloud Service SDK

Adobe Experience League  •  https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/aem-as-a-cloud-service-sdk 

Adobe WKND releases

GitHub  •  https://github.com/adobe/aem-guides-wknd/releases