Apple Silicon(M1) 3 Months Later

Well here we are 3 months into 2021 and 3 months into having M1 unleashed on the world. As noted in a previous post back in December most everything I run on a day to day basis works, however I’ve now had some time use it as my daily driver for several months and developers have begun to release more Apple Silicon builds, which means better performance and less dependance on Rosetta 2.

More M1 Native Software Builds

Generally speaking everything has run equally as fast or faster than it did on my old late 2016 Macbook Pro 15″. The one really big exception to this were JetBrains products. I’m a daily user of DataGrip, IntelliJ, and PyCharm. On December 30, 2020 JetBrains announced via their blog that they had Apple Silicon versions of the 2020.03 release of all their main products. Performance with these has been astronomically better on M1 and it now handily beats my Intel Mac hands down for IDE performance.

Docker Coming Along

Onto the biggest gotcha yet…Docker. While not having Docker support out the gate for M1 was a huge bummer and made many of us who use Docker in our jobs either as developers, engineers, or devops users, they were quick to get a preview build out the door that is available for use. The reasons for this are widely documented including here however the TL;DR version is that the are some differences between the M1 ARM silicon and x86 processors in terms of virtualization options and supported container architectures.

Enter the Docker Desktop for Apple Silicon Preview build. At the time of this writing the current preview build is 7. I was quickly disappointed when I ran the docker-compose for my local dev env and was immediately greeted by warnings and containers dying with this message

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

However manually running the containers in my environment with the following flag once and then stopping them made them play nice with Docker-Compose

--platform linux/amd64
#Example Running a container
docker run --platform linux/amd64 -it mysql:5.7

Performance with Docker using the compatibility flag has been fine. The only major problem that I’ve had is that disabling Use gRPC FUSE for file sharing in the experimental features requires a restart of Docker Desktop and it gets hung restarting until I reset all settings to default. All in all it’s usable enough for my purposes and the performance has been quite acceptable. This should continue to improve with time.

Audio and Video Production

Logic Pro X works like a charm of course (it better, it’s first party). All the plugins I use from ToonTrack, Neural DSP, EastWest, and Izotope all seem to work rather well, maybe with the exception of Ozone 9 occasionally causing crashes of Logic (only on startup, but I’ve managed to work around this by disabling the plugin before saving and closing the project and then toggling it back on once the project loads). iMovie has of course been fine, rendering times have dramatically improved for me over my MacBook Pro, and the heat is non-existent during rendering.

Best Battery Life….Ever….Seriously…

Part of the fun of #DevOpsLyfe when working with retail customers is being on call and high alert during the black Friday/cyber Monday holiday shopping traffic increases. I decided to keep an eye on monitoring dashboards on my M1 Air this year with Caffeine toggled on to prevent screen sleep…..13 hours later I still had a 34% batter remaining. Never have I been able to keep a dynamically updating monitoring page going for that long on battery. In fact the next day I did the same thing with my Intel MacBook Pro from work (it’s a 2018), and the battery lasted a whole 3.5 hours. The lack of heat produced by these machines, the efficiency of SoC ARM, and the low power draw has really made these the absolute best devices on the market for desktop computing power on the go.

What’s Next?

It remains to be seen what will come next in the Apple Silicon world. One thing is for sure though, it has changed the game and it is here to stay. I’m interested to see how this SoC architecture scales beyond 16GB of shared memory, and how a greater number of I/O ports is handled. One thing is for sure though, when the more powerful high end pro devices rock Apple Silicon it’s going to be truly impressive.

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}