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
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 ARG MODULE_URL 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/mod_dispatcher.so && \ chown root:root /etc/httpd/modules/mod_dispatcher.so EXPOSE 80 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=https://download.macromedia.com/dispatcher/download/dispatcher-apache2.4-linux-x86_64-4.3.3.tar.gz \ .
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" services: dispatcher: image: mysite/dispatcher:latest ports: - 80:80 environment: 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 volumes: - ./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 127.0.0.1.
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
- You can access mysite directly on the publisher: http://localhost:4503/content/mysite/us/en.html
- You can access mysite through the dispatcher: http://mysite.mycompany.local/content/mysite/us/en.html
- You are seeing things getting cached in the mapped folder, in our case httpd-docroot
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.
This cannot be used on Windows machine as YUM would not be available. Is there any other set of commands for windows.
Those YUM commands run inside the container, not the Windows host.
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.
PROBLEM STATEMENT:
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).
How do you setup the dispatcher flush agent? I’ve tried several ways and I keep getting 403 forbidden.
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.
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.