Dockerize your Mulesoft API's
This article will describe how we Dockerize our Mulesoft 3.9 Enterprise edition and deploy it in AWS.
Join the DZone community and get the full member experience.Join For Free
Containerizing Your Mule MicroService Applications
In his 24 May 2018 blog post, Aaron Landgraf shares a broad brush of capabilities in the Mule Titan release. Full story here.
Landgraf describes the new Anypoint Runtime Fabric for creating, deploying and managing Mule containers in the Cloud, see excerpt below.
"Anypoint Runtime Fabric is a container service that makes it easy to manage multi-cloud deployments of Mule runtimes and to deploy multiple runtime versions on the same Runtime Fabric. By leveraging Docker and Kubernetes, Anypoint Runtime Fabric drastically simplifies the deployment and management of Mule runtimes on Microsoft Azure, Amazon Web Services (AWS), virtual machines (VMs), and physical servers. Isolate apps, scale horizontally, and redeploy with zero downtime."
Our project shares many similar goals articulated above but is limited to achieving them with a more austere set of tools. This article will describe how we Dockerize our Mulesoft 3.9 Enterprise edition and deploy in AWS.
Our target Architecture will consist of deploying Mule applications from AnypointStudio into Docker containers running inside an AWS AMI image.
In the steps below, you'll configure an AWS EC2 instance and configure the environment for Docker. With Docker installed, you'll create images for Mule and MMC, run the containers, associate the Mule runtime with the MMC, and deploy a simple Hello Mule application.
Docker containers are ephemeral by nature, which means that any changes to container state will be lost when a container is stopped. This isn't desirable, and a quick remedy will be to use Docker volumes to persist and change what we need between container starts. The information which will be stateful is specified by the VOLUMEtag in the Docker files below.
We assume you're familiar with Mule and have some familiarity setting up EC2 instances in AWS. If you're not confident with AWS or would like a little refresher please review the following articles.
Some refreshers before getting started:
Some AWS services will incur charges, be sure to stop and/or terminate any services you aren't using. Additionally, consider setting up billing alerts to warn you of charges exceeding a threshold that may cause you concern.
We begin by copying the distribution files for MMC and Mule runtime to our EC2 instance. It will probably be easiest to use wget from the EC2 instance to download them directly. Other options include scp from your development environment or copy from an S3 bucket. Use the approach you feel most comfortable with.
In my EC2-User home folder I use the following hierarchy for my Dockerfile source:
Folder Structure for Builds
ls src/docker/mule MMC-3.8.0 MuleEE-3.9.0 ls src/docker/mule/MMC-3.8.0 Dockerfile mmc-3.8.x-web.tar.gz start.sh ls src/docker/mule/MuleEE-3.9.0 Dockerfile mule-enterprise-standalone-3.9.0 mule-ee-distribution-standalone-3.9.0.tar.gz
Note that the tar file has been expanded, and we have a folder for mule-enterprise-standalone-3.9.0.
The reason for this is that I install our custom EE license, make any changes to configuration files unique to our environments, and repackage the tar file for creation of the Mule Docker image.
Apply Local Changes to Mule Configuration Files
tar xzf mule-ee-distribution-standalone-3.9.0.tar.gz export MULE_HOME=~/src/docker/mule/MuleEE-3.9.0/mule-enterprise-standalone-3.9.0 cd $MULE_HOME # apply mule license bin/mule -installLicense _path_to_your_license.lic # re-create tar tar czf mule-ee-distribution-standalone-3.9.0.tar.gz mule-enterprise-standalone-3.9.0
The Docker volumes expect to preserve stateful information under /opt, so the folder
structure and permissions will need to be set up. My permissions are wide open, and you
may prefer to create an EC2 Mule user and group to apply stricter access control. If
you do, I'm confident you'll do so successfully on your own.
Folder Structure for Docker Volumes
sudo mkdir /opt/mmc sudo mkdir /opt/mmc/logs sudo mkdir /opt/mmc/mmc-data sudo chmod -R 777 /opt/mmc sudo mkdir /opt/mule-enterprise-standalone-3.9.0 sudo mkdir /opt/mule-enterprise-standalone-3.9.0/apps sudo mkdir /opt/mule-enterprise-standalone-3.9.0/conf sudo mkdir /opt/mule-enterprise-standalone-3.9.0/domains sudo mkdir /opt/mule-enterprise-standalone-3.9.0/logs sudo chmod -R 777 /opt/mule-enterprise-standalone-3.9.0 sudo ln -s /opt/mule-enterprise-standalone-3.9.0 /opt/mule ls -l /opt drwxrwxrwx. 4 root root 34 Feb 2 15:43 mmc drwxrwxrwx. 6 mule mule 57 May 24 15:05 mule-enterprise-standalone-3.9.0
My open AWS Mule ports look like this:
Open Ports in AWS Mule SG
Custom TCP Rule
Mule MMC Agent
Custom TCP Rule
Mule API for HTTP
Dockerizing the Mule Management Console (MMC)
Dockerfile for MMC
FROM java:openjdk-8-jdk MAINTAINER Your Name <email@example.com> USER root WORKDIR /opt RUN useradd --user-group --shell /bin/false mule && chown mule /opt COPY ./mmc-3.8.x-web.tar.gz /opt COPY ./start.sh /opt # Using the most recent MMC 3.8.x version RUNtar xzf mmc-3.8.x-web.tar.gz \ && ln -s mmc-3.8.x-web mmc \ && chmod 755 mmc-3.8.x-web \ && chmod 755 start.sh \ && rm mmc-3.8.x-web.tar.gz # Mule environment vars ENV MMC_HOME /opt/mmc # Volume mount points VOLUME ["/opt/mmc/apache-tomcat-7.0.52/logs", "/opt/mmc/apache-tomcat-7.0.52/conf", "/opt/mmc/apache-tomcat-7.0.52/bin", "/opt/mmc/apache-tomcat-7.0.52/mmc-data"] # Mule work directory # WORKDIR /opt USER mule # start tomcat && tail -f /var/lib/tomcat7/logs/catalina.out CMD [ "./start.sh" ] # Expose default MMC port EXPOSE 8585
When the MMC Docker container starts, it will run the Tomcat server and tail the
log contents to stdout.
Create the start.sh script below in your MMC folder. It will be added to the Docker image and will keep the container running after it's started in the step below.
start.sh File in MMC Folder
#!/bin/sh # If the apache-tomcat location is different for you, be sre to change cd /opt/mmc/apache-tomcat-7.0.52 bin/startup.sh && tail -f logs/catalina.out
The initial build may take a while to complete as it needs to pull down the image layers from the Docker hub and create an image.
Build Your MMC Docker Container
# Change maxmule at end of next line to your Docker image name and optionally tag docker build -t maxmule/mmc .
When the build successfully completes we can start the MMC container instance and use the browser to connect to it.
Run Your MMC Docker Container
# Change maxmule at end of next line to your Docker image name docker run -itd --name mmc -p 8585:8585 -v /opt/mmc/mmc-data:/opt/mmc/apache-tomcat-7.0.52/mmc-data -v /opt/mmc/logs:/opt/mmc/apache-tomcat-7.0.52/logs maxmule/mmc
It may take a while for the MMC to start up, so you can use the Docker logs command to see when startup has completed. The Ctrl-C command will terminate the earlier logs command.
Ensure MMC is Running
docker ps docker logs -f mmc ^C
Dockerizing the Mule Runtime
Dockerfile for Mule
FROM java:openjdk-8-jdk # 3.9.0 ee branch MAINTAINER Your Name <firstname.lastname@example.org> USER root WORKDIR /opt RUN useradd --user-group --shell /bin/false mule && chown mule /opt COPY ./mule-ee-distribution-standalone-3.9.0.tar.gz /opt COPY ./start.sh /opt RUN tar xzf mule-ee-distribution-standalone-3.9.0.tar.gz \ && ln -s mule-enterprise-standalone-3.9.0 mule \ && chmod 755 mule-enterprise-standalone-3.9.0 \ && chown -R mule:mule mule-enterprise-standalone-3.9.0 start.sh \ && chmod 755 start.sh \ && rm mule-ee-distribution-standalone-3.9.0.tar.gz # Mule environment vars ENV MULE_HOME /opt/mule ENV PATH $MULE_HOME/bin:$PATH # Volume mount points for persisten storage, create others for domains and conf if necessary VOLUME ["/opt/mule/logs", "/opt/mule/apps"] USER mule ENTRYPOINT ["mule"] CMD ["console"] # Expose port 7777 if you plan to use MMC EXPOSE 7777 # Expose additional ports as needed for your API use #EXPOSE 8081 EXPOSE 8082 #EXPOSE 8083
Similar to how we built and started the MMC above, we'll follow the same steps with our Mule container.
Mule will be using port 8082 for working with our API deployment and port 7777 for
communicating with the MMC.
Build Your Mule Docker Container
# Change maxmule at end of next line to your Docker image name and optionally tag docker build -t maxmule/mule39ee .
The build step is the same as we did earlier for the MMC.
Build Your Mule Docker Container
# Change maxmule at end of next line to your Docker image name docker run -itd --name mule -p 8082:8082 -v /opt/mule/apps:/opt/mule/apps -v /opt/mule/logs:/opt/mule/logs maxmule/mule39ee
When build has successfully completed, we run our Mule runtime instance and verify that it has properly started.
Ensure Mule is Running
docker ps docker logs -f mule ^C
Deploying a Model
Create a simple HTTP flow in AnypointStudio, which listens on Port 8082, a port that you expose in your Docker file and the EC2 instance security group. Run the flow in AnypointStudio first to ensure it will work when deployed to your Docker container.
This concludes our brief examples with Dockerizing the Mule.
I hope you enjoyed reading this article as much as I have enjoyed writing it, and I'm looking forward to your feedback!
Opinions expressed by DZone contributors are their own.