Skip to main content


Setting Up A Local AEM Dispatcher With Docker

Istock 636932704 (3)

Reverse proxy and caching are two of the many features provided by the AEM dispatcher module. It is the prism through which your web users will view content on the AEM publisher. Developers will say the development and operations (DevOps) team handles it. DevOps rely on developers to provide instructions on how to configure it. Hardly anyone sets it up in their local environment. Instead, they depend on remote systems to test and debug. This can sometimes turn into a game of whack-a-mole until things work. 

In this post, I will review how to set up a local dispatcher using docker to proxy to your local AEM publish instance. We will be able to update config files, trace logs, and debug. When we send the configuration to DevOps, it will be with an “it worked on my computer” stamp of approval. 

Install Docker 

We leverage Docker to avoid the difficulties that come with installing Apache on your platform (Windows or macOS). We are also getting an environment that is pretty close to what AMS would be using. Installing Docker on your platform should be fairly straight forward. Once installed, you can verify with the following commands

Docker Version

Create an Archetype Project 

You may have your own Apache configuration. Before you throw those in, let’s build a baseline using the archetype project. Note that the aemVersion is set to 6.5.0 which is NOT the same if you were using AEM as a cloud service. This means that they will work on AMS dispatchers, not AEM as a Cloud Service.

mvn -B archetype:generate \
 -D archetypeGroupId=com.adobe.aem \
 -D archetypeArtifactId=aem-project-archetype \
 -D archetypeVersion=24 \
 -D appTitle="My Site" \
 -D appId="mysite" \
 -D groupId="com.mysite" \
 -D aemVersion="6.5.0"

Building an Image 

To build an image, we are going to leverage an existing CentOS image. We will install Apache and the dispatcher module. This is pretty much the same setup on AMS. The only difference is that they use the Enterprise RedHat Linux which CentOS is the free version of. First, create the following Dockerfile within the mysite project folder: 

FROM centos:7.8.2003

RUN yum -y update && \
    yum -y install httpd && \
    yum clean all && \
    mv $(curl --insecure --silent ${MODULE_URL} | \
    tar xzvf - --wildcards "*.so" | head -1) /etc/httpd/modules/ && \
    chown root:root /etc/httpd/modules/


RUN mkdir -p /mnt/var/www/author && \
    mkdir -p /mnt/var/www/html && \
    mkdir -p /mnt/var/www/default && \
    chown -R apache:apache /mnt/var/www

WORKDIR /etc/httpd
CMD [ "apachectl", "-DFOREGROUND" ]

Now, we build the image with the following command within the mysite project folder: 

docker build \
    -t mysite/dispatcher:latest \
    --build-arg MODULE_URL= \

Creating a Container 

Next, you will need to create a container using the image by leveraging Docker Compose. Create a file called docker-compose.yml within the mysite folder. 

version: "3.8"


    image: mysite/dispatcher:latest
        - 80:80
      DISP_ID: dispatcher1docker
      AUTHOR_DEFAULT_HOSTNAME: author.mycompany.local
      AUTHOR_IP: host.docker.internal
      AUTHOR_PORT: 4502
      AUTHOR_DOCROOT: /mnt/var/www/author
      PUBLISH_DEFAULT_HOSTNAME: mysite.mycompany.local
      PUBLISH_IP: host.docker.internal
      PUBLISH_PORT: 4503
      PUBLISH_DOCROOT: /mnt/var/www/html
      CRX_FILTER: deny
      - ./dispatcher/src/conf:/etc/httpd/conf:ro
      - ./dispatcher/src/conf.d:/etc/httpd/conf.d:ro
      - ./dispatcher/src/conf.dispatcher.d:/etc/httpd/conf.dispatcher.d:ro
      - ./dispatcher/src/conf.modules.d:/etc/httpd/conf.modules.d:ro
      - ./httpd-docroot:/mnt/var/www/html

What we are setting up here is a service called dispatcher. The environment variables represent the minimal set used by the archetype Apache configs. The volumes section maps each config folder to its place within the container. The last volume maps the HTML folder where the dispatcher is caching pages to our host’s directory. This is how they will persist should the container restart. It also allows us to navigate the cached data within our host’s file system. 

The archetype configs will create 2 vhosts. They are author.mycompany.local and mysite.mycompany.local. To access these locally, you should make sure to update your hosts file (i.e. /etc/hosts in macOS) so that they resolve to 

Testing MySite Through the Default Dispatcher 

Start your publisher and deploy mysite by using the command we all know and love: 

mvn clean install -P autoInstallPackagePublish -P adobe-public

Start the dispatcher 

docker-compose up -d

And verify the following things 

Things to Try Out 

There are many dispatcher related topics we could touch upon that would not fit into this tutorial. Here are a few ideas you can try out now that you have a working dispatcher. 

  • Test the dispatcher flush 
  • Remove the /content/mysite root by updating the rewrite rules 
  • Create a new vhost for a new site 
  • Access the author through the dispatcher 
  • Set up Sling Server Side Includes 
  • Tail the logs generated by Apache 
  • Explore the modules under /etc/httpd/modules 

I hope you found this blog post useful. For any additional questions, please comment below and be sure to check out our other Adobe blogs. 

Thoughts on “Setting Up A Local AEM Dispatcher With Docker”

  1. This cannot be used on Windows machine as YUM would not be available. Is there any other set of commands for windows.

  2. Juan Ayala Post author

    Those YUM commands run inside the container, not the Windows host.

  3. Arvind Pandey

    Hi Juan,

    I tried to follow this article as its archetype structure is very close to our project code base.

    After I performed all steps successfully.


    When I try to access local:8082, It gives “You don’t have permission to access / on this server.”.(I changed port from 80 to 8082 in docker-compose.yml).

  4. Gonzalo Calandria

    How do you setup the dispatcher flush agent? I’ve tried several ways and I keep getting 403 forbidden.

  5. Juan Ayala Post author

    Arvind Pandey: That’s right. Apache within the container is on 80. It is exposed on the host on 80. Hence in the docker-compose.yml it is 80:80. On some hosts, 80 may be locked down. Hence you would change to 8082:80 and any request coming into the host on localhost:8082 should get forwarded to Apache 80. But just because it is doesn’t mean Apache will accept it. The VirtualHost configuration may not be set up correctly. So just keep an eye on your logs to see what if anything is causing the request not to reach your VirtualHost.

  6. Juan Ayala Post author

    Gonzalo Calandria: The sample shown is set up so that the hosts forward port 80 to Apache within the container on the same port hence the 80:80 port configuration in docker-compose.yml. It is possible that your OS or Antivirus is blocking 80 on the host so you may need to adjust that to an alternate port i.e. 8080:80, meaning localhost:8080 will be forwarded to Apache 80. When troubleshooting keep an eye on the Apache logs.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Juan Ayala

Juan Ayala is a Lead Developer in the Adobe practice at Perficient, Inc., focused on the Adobe Experience platform and the things revolving around it.

More from this Author

Follow Us