☠📝 Java Web Apps on Azure — The hunt for up-to-date documentation
My struggle to move our Java backend to Azure App Service reinforces that no documentation is better than outdated or “noisy” documentation.
Azure’s teams have built a super awesome platform, but their documentation is severely lacking. If you get it to run, you’ll feel like you accomplished a huge feat, but this will be tainted by your resentment at having been left to figure it out on your own. That was my experience anyway. And it’s why I’m writing this article.
Unhappy with our cloud provider, I persuaded my boss to try Microsoft Azure. No sooner did we commit to making the switch than I found myself in a maze of ancient docs guided by screenshots that look nothing like what’s shown in the Azure Portal.
Switching to MS Azure was a pain. If you go down this path, be prepared to face a slew of challenges (Side note: “How to think like a programmer” does a great job teaching you to break big problems down).
Our current backend is a Java archive (JAR)-packed with Maven serving a REST API using Spring. Our data is stored in a Maria or MySQL database.
To summarise, the JAR file needs to —
- Read from the environment variables
- Connect to a MySQL database that’s also on Azure
- Log somewhere you can tail it (easier said than done!)
- Run on App Service Linux and not a VM
- Not be modified too much from your current code base.
Most importantly, don’t count on reliable documentation from Microsoft. You won’t find it (at least at the time of writing this article). Your current best bet — besides this article — is learning from fellow developers.
For committed readers, the full story
Armed to the teeth with protein shakes, I moved from a communal co-working space to a private (and silent!) office to give Azure my undivided attention. Here’s what I learned behind that closed door:
To get my backend to run, I learned a lot from “Build a Java and MySQL App on VMs and Containers in Azure” — a wonderful tutorial written by Brian Benz.
Here is a brief summary of the path to a running JAR file:
- You need a resource group for everything — something Azure is very clear about, and the portal makes it easy to create one.
- For your backend, a database is necessary, so I created an “Azure Database for MySQL servers.”
- I followed Brian’s advice in creating a new Firewall Rule: 0.0.0.0 to 255.255.255.255. Logically, this should be narrowed down later.
- I’m not sure if the prompt, “Allow access to Azure Services” in the UI means MS support or other Azure features, but I checked it…
- For security reasons you should setup a database user for the backend to use. I did that as Brian described.
- You will also need an App Service Plan, which is kind of the “machine size” you choose and will be billed for. I took the B3 tier for my trials, but you might play around here.
- Now you need to configure your Web App by adding at least these two application settings:
JAVA_OPTS = “-Dserver.port=80”
WEBSITES_CONTAINER_START_TIME_LIMIT = 1800
You can decrease 1800 if you started your Web App at least once and know how long it takes (with some margin).
- Finally, you need to turn on Diagnostic logs yourself in the matching tab.
- Only after all of that I could start deploying and actually see what’s going on. I chose to upload via SFTP. Imitating the Java example of Azure Tutorials I uploaded my JAR to the wwwroot.
- How to get the SFTP credentials is mentioned in another documentation again. You need to download your “publishing profile”.
- I established the following procedure after every JAR upload to potentially get it to start (since the logs seem to be delayed and appear in batches, it’s very difficult to properly follow what is going on):
I. Upload JAR
II. Stop the Web App (I learned much later that my “Restart does not work” -expression was just the Web App taking long time to start and logs appearing in batches)
III. Start the Web App
IV. Hit the Web App URL (just to make sure, the rotating, loading spinner of the browser gives a calming feeling)
V. Tail the logs, stare at them for 5 minutes and hope to see the startup success message after that.
While conquering the Azure portal and assembling all pieces, I collected more than one point which is either difficult to find in the docs or nowhere to be found at all:
Do “Always On” Web Apps start automatically?
As far as I understand, a WebApp has to be triggered by calling its URL; but I also understand that a WebApp with the “Always on” flag should start by itself?
Efficient log access
Logs go to files you cannot efficiently access. There are three ways to access them: SFTP, the portals own log stream or the Azure CLI 2.0. While the latter two seem to be delayed and not prettified (readable), SFTP is a hustle because the files are in use while the Web App is running.
The secret start timer and health check port
By waiting for dozens of minutes in front of the log stream I learned that I need to increase the start time limit because our backend took too long to start (normally 26s, in Azure Web App around 320s).
Not having seen it anywhere in the docs (I’ve adopted it from a tutorial of MS in their pom.xml) I learned that Azure App Service needs the server.port set to 80. Otherwise (I found out later) the health check will fail and report an error.
“Handy” solution for application settings
While MS itself calls this feature “handy capability” this is where it felt like rummaging around in a black box with a stick. One can set application settings (environment variables) but the mythic Kudu Console (which has close to no docs at all and if there are, they are deprecated) lists them with weird prefixes — might be nice for developers but made me ask, “Do I need to rename them in code?” “Does spring detect them like this?” “How does that work?”…
Placing the JAR
How the file must be named when placed in the wwwroot is unclear, I imitated the tutorial and just named it app.jar. Must there be a web.config file? No one knows. Well, MS admitted, “There must be one,” but the docs are missing. They are working to get it in the docs now (weirdly enough, my deployment still works without it 🤔).
I’ve now worked at three different startups, and like every developer, I’ve always struggled with documenting too little versus too much. As one of my mentors aptly put it, “Classical documentation is outdated at creation.”
“As you know Azure and cloud services are very fast pace and things are changing by the day, we try our best to document however there are times the releases are faster than updating the documents.”
Answer of a polite Microsoft employee treating my incident about Azure App Service.
“Why, why do giants like MS still update documents? There must be solutions for bringing documentation code-near! I appreciate that these challenges are massive, but I cannot stress enough that only when I love your product will I tell others how awesome you are. I know I’m not alone.”
It’s actually a two-part challenge:
First: How do you adequately document a fast-living system?
And if you somehow master that …
Second: How do you keep the documentation relevant? (Seriously? 2015 documentation for Azure in late 2018?!)
“Next-generation documentation” isn’t only about writing different; it’s about maintaining different.
From complaints to solutions
The developer community doesn’t even need to go so far as writing up-to-date documentation. Flagging deprecated documentation would go a long way.
Like the popup on Medium, a small context menu could invite corrections to the documentation:
This console you mention does not exist anymore! Please update.
Combined with a system like CS:GO Overwatch, a tool like this could improve content quality in no time! Docs like the one above from 2015 would vanish in hours and greatly reduce “documentation noise”.
I made up this term at time of writing but it actually describes the concept pretty well — having wrong documentation feels even worse than having none at all
Switching to MS Azure doesn’t sound too difficult! That’s what I said, too. What’s complicated are not the steps per se; it’s stitching everything together. But I hope this account of my journey guides fellow developers and triggers a wake-up call for the app companies we count on.
(This is my first story for Medium, so I’m not quite sure I’ve respected all the rules or even wrote something people want to read… let me know.)