Using Dockerized Apache as a Reverse Proxy for Java

I recently was working on a project in an effort to replace a legacy development environment. Our dev environment had simply grown to require a multitude of items including ElasticSearch, DynamoDB, Apache, and MySQL. For Apache and MySQL the old environment was using a XAMPP stack which I’ve commonly used in other development environments in the past. The other components were previously installed using homebrew and required at least half a day for a dev to get their environment ready to run the application. Docker with Docker Compose seemed liked an easy enough solution for this as there are supported containers for each of the services listed above that make this easy to setup with minimal effort. Creating scripts within repos to load development data would also greatly decrease the setup time for a developer to be setup and productive on a project.

One of the biggest sticking points though was the Apache reverse proxy to Tomcat. During application development the Java application is run from within IntelliJ so that the code can be live edited and there are other services and reasons outside the scope of this blog for needing to use Apache to proxy calls on 80 and 443 back to the application on 8080. The challenge is you can map localhost 80 and localhost 443 to the container no problem, but getting back from the Apache container to Java proved to be somewhat of a challenge as the localhost or 127.0.0.1 referred to the container itself not the host.

Please note the solution below may not be optimal for everyone, relies on the users being on MacOS and using the interface en0 (this should be whatever your default network connection is).

To get around this my teammate and I discovered that you can map back using your host machine’s private IPv4 address however this is problematic as it would require modifying the container and it can change from time to time. After some experimenting we found that the simplest way to to get this to work was to add the following environemnt variable to your docker-compose.yml
environment:
- MYIP=${MYIP}

Next you will need to make sure your Apache container’s vhost file has a ProxyPass directive that includes this environment variable, this may look something like this:
ProxyPass / http://${MYIP}:8080/
ProxyPassReverse / http://${MYIP}:8080/

Next you will need to create a build script that sets the value to something. Then you’ll need a startup script that starts the docker-compose with a valid IP address.
The build script looks something like this:
MYIP=x docker-compose build --no-cache

The startup script looks something like this:
MYIP=$(ifconfig | grep -C5 en0 | grep inet | grep -v inet6 | awk ‘{print $2}’) docker-compose up -d ${1}

Squeezing More Life From Older Apple Hardware

Last year with the release of OSx Mojave support for many older models was dropped. While I do have a newer Macbook Pro I also have an old 2011 that’s still going strong thanks to its upgradability. As a DevOps professional that’s always on call I take a laptop with me nearly everywhere I go. This means dinner, concerts, band practice, bars, out of town trips etc. Some of these places I am concerned about theft and do not feel like risking having a $3000+ laptop stolen. So for some time now I’ve been using the trusty old 2011 Macbook Pro as my on call go everywhere machine. The only bummer is that Mojave is not supported on this hardware and that’s a shame as it is still plenty powerful.

Why would you want to use old hardware you ask? Put simply because I can and it fits the use case of what I’m doing. In fact I’m typing this blog right now on the old 2011 Macbook Pro. One of the biggest downfalls of the recent Apple hardware trends after 2012 is the lack of replaceable parts and the disposability of high dollar machines. For example if you don’t opt for a RAM upgrade at the time of purchasing a new Mac portable you’re stuck with that RAM permanently. Sure you can choose the RAM upgrade when you purchase but the cost of that RAM upgrade is many times more than what it would cost to do it yourself when those parts were user replaceable. The biggest problem here comes down waste, and less usable years out of an otherwise usable machine.

To further prove my point I upgraded the old 2011 MacBook Pro with a SATA SSD and 8gb of RAM. Comparing this to the function key late 2016 MacBook Pro the GeekBench CPU benchmarks were astoundingly not as earth shatteringly different as one might expect. Both machines feature and Intel i5 dual core processor with 8gb of RAM. Here are the results:

2011 13” MacBook Pro (i5 8gb)
– Single core: 2948 
-Multi core 5673

2016 13” MacBook Pro (i5 8gb)
– Single core: 3888 
– Multi core: 7721

So how to get Mojave on this old unsupported MacBook Pro… Well fortunately DosDude1 has created a patcher tool that essentially helps you to create a bootable MacOS USB stick along with a patching utility you run at the end of the install process that adds in kexts and other patches to extend functionality to older devices. The tool can be downloaded from his site here: http://dosdude1.com/mojave/#downloads

To complete the process you will need at least 10gb of space on a flash drive, to install the utility and follow the directions here: http://dosdude1.com/mojave/#instructions

I’ve been running Mojave on this machine without any issues for the past 2 months and all has been well. The only gotcha is to make sure you check his site before installing minor release updates as some newer MacOS patches require an updated version of the tool to be installed. If you forget to this and find your machine unbootable all hope is not lost, simply create a new bootable flash drive from another Mac and proceed to install the OS again. This will not overwrite your files or home directory unless you erase the partition using disk utility.

Extending Partition Without Rebooting (EBS Amazon Linux)

This guide assumes that you are using a Linux OS in AWS EC2 and are not using LVM. In the example below we will walk through the steps of growing an EBS volume.

First we need to go to the “Volumes” page of EC2 and right click the volume we wish to expand and click modify. Increase the size to the desired amount and press modify. Once the storage amount changes in the EBS volume screen we are ready to proceed.

SSH into the machine we extended the drive for and run the following command to identify the drive. This may vary on systems with multiple disks, however for most single volume EC2 machines this will be /dev/xvda1

sudo lsblk

NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT

xvda    202:0    0  40G  0 disk

└─xvda1 202:1    0  40G  0 part /

Next once you’ve identified the disk (in my case above it’s /dev/xvda1, you’ll want to run the following commands:

To grow the partition run(make note of the space between the device and partition number): sudo growpart /dev/xvda 1

Finally to grow our partition to be used by the OS:
sudo resize2fs /dev/xvda1

Note: if you are running an XFS file system you may need to run xfs_growfs instead of resize2fs