Table of Contents
If you’ve ever hosted web applications on Microsoft Azure, you probably know that every VM comes with a so-called ephemeral disk (usually mounted at /mnt
). It’s fast, SSD/NVMe-backed storage with insane IOPS and low latency... but with a catch: its contents are temporary. As soon as the VM is deallocated or migrated to another host, everything on that disk is gone.
That might sound scary, but in practice it’s perfect for all those workloads that are, by nature, temporary: caches, session files, temp directories, build artifacts, and so on. If you configure your web stack to use that disk, you get a performance boost at no extra cost. That’s exactly the idea behind azure-tempdisk-bootstrap.
/mnt
.
What does this project do?
I wrote azure-tempdisk-bootstrap as a small bootstrap script + systemd unit that automatically sets up the right directories under /mnt
each time the VM boots. It makes sure that Nginx, PHP, ASP.NET Core, and WordPress always have the proper temp/cache directories ready to use. Here’s what it creates:
/mnt/nginx/fastcgi/
– Nginx FastCGI cache/mnt/nginx/proxy/
– Nginx reverse-proxy cache/mnt/nginx/temp/
– Nginx temp files/mnt/php/sessions/
– PHP session files/mnt/php/uploads/
– PHP upload temp dir/mnt/dotnet/temp/
– .NET temporary path/mnt/wordpress/
– WordPress export/cache files
The script handles ownerships and permissions, and it ensures that the directories are recreated after each reboot (because remember, the Azure ephemeral disk gets wiped). No more manual work, no more “file not found” errors.
Why does it matter?
Because you want your caches and temp files on the fastest disk available. By default, they usually sit on your managed OS/data disk, which is slower and more expensive. Moving them to the ephemeral disk means:
- Faster page loads for cached requests
- Less pressure on your main disk (and fewer IOPS throttling issues)
- Better overall performance with zero cost
Of course, this disk isn’t persistent – so don’t store databases or critical logs there. But for temp stuff, it’s basically free performance.
How to get it
The project is available on GitHub, where you can download the latest release as a .zip
and drop the files into place.
There’s also a full installation guide in the repo, but here’s the short version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 1) Install the script sudo install -m 0755 scripts/azure-tempdisk-bootstrap.sh \ /usr/local/sbin/azure-tempdisk-bootstrap.sh # 2) Install the systemd unit sudo install -m 0644 systemd/azure-tempdisk-bootstrap.service \ /etc/systemd/system/azure-tempdisk-bootstrap.service # 3) Reload systemd, enable, and start sudo systemctl daemon-reload sudo systemctl enable azure-tempdisk-bootstrap.service sudo systemctl start azure-tempdisk-bootstrap.service # 4) Verify it works ls -ld /mnt/nginx/* /mnt/php/* /mnt/dotnet/temp /mnt/wordpress |
That’s it – from now on, each time your VM reboots, the right directories will be recreated and ready to use.
Nginx configuration: manual vs. semi-automatic
There are two ways to configure Nginx to use the temp disk:
Manual configuration (for complex setups)
If you run multiple sites with different caching needs, you’ll want to edit your server { }
configs directly and point each site’s proxy_cache_path
and fastcgi_cache_path
to the proper directories. That gives you full flexibility to tune each cache zone.
Semi-automatic configuration (simpler setups)
If you just want to get started quickly, the repo includes a conf/nginx/azure-tempdisk-cache.conf
file you can drop into /etc/nginx/conf.d/
. It sets up sensible defaults for proxy and FastCGI caches on /mnt
. Perfect if you’re hosting a few sites with similar needs.
PHP and .NET
For PHP, all you need to do is set the following in your php.ini
(works for PHP-FPM and any other SAPI):
1 2 3 4 |
session.save_path = "/mnt/php/sessions" upload_tmp_dir = "/mnt/php/uploads" |
For .NET apps, just point the TMPDIR
environment variable to /mnt/dotnet/temp
in your systemd unit. That’s it.
FAQ: Why a systemd service instead of a simple startup script?
One of the most common questions is: why did we choose to provide a dedicated systemd
service instead of just adding the bootstrap script to rc.local
, cron @reboot
, or similar mechanisms?
The answer comes down to reliability and timing:
- Mount timing
On Azure, the ephemeral disk (/mnt
) is mounted by the Azure Linux Agent (waagent
) or cloud-init after the basic system initialization.
If the bootstrap script runs too early,/mnt
may still be empty (or just a plain directory), and the whole setup would silently fail. - Explicit dependency management
Withsystemd
we can declareRequiresMountsFor=/mnt
andAfter=local-fs.target
, ensuring that the service only runs once the ephemeral disk is properly mounted and available. - Idempotence & safety
The service runs inoneshot
mode and exits after creating directories and permissions.systemd
guarantees that it is executed exactly once per boot and in the correct order. - Integration with other services
By declaringBefore=nginx.service
(or other services), we ensure that Nginx, PHP-FPM, or .NET apps never start without their required temp/cache directories being present. - Maintainability
Usingsystemd
keeps everything in the same place as other system services, making it easy to check logs withjournalctl
, enable/disable the bootstrap, or update the script.
In short: a plain script at boot time is fragile because it might run before /mnt
is ready. A dedicated systemd
unit makes the setup predictable, reliable, and fully integrated into the Linux service lifecycle.
Wrapping up
I built azure-tempdisk-bootstrap because I wanted a simple, reliable way to automatically leverage Azure’s ephemeral disk for my web workloads. It turned out to be so useful that I decided to open-source it. If you’re running Nginx, PHP, WordPress, or .NET on Azure, I think you’ll find it handy too.