Running a single Docker Container in Azure cost-effectively

Running a single Docker Container in Azure cost-effectively

At home, I have a few essential services I need to keep running at all times. When I write crucial, I mean that they are services I rely on, and I would like those services to run when I need them the most. One of those is my password manager, called Bitwarden. I run it locally on my Synology NAS in a Docker container (read here for details on this setup). I connect to this service via all of my devices, and if it doesn’t work, I might be locked out of one or more of my other services.

While I’m pleased with how Docker (the service that runs container-based images) performs on my Synology DS1821+ NAS device, I’ve been thinking of a way to host these containers in Azure.

So, I set out to compare the different options. It turns out that the cost is a crucial factor here.

My container

Currently running the container is a slightly evolved version of the original Bitwarden password manager solution. It’s now called Vaultwarden, but it works and acts the same. It only needs 30-40 MB of RAM and less than 1% of my NAS CPU performance. In a word, it’s lightweight.

The options for running Docker containers in Azure

Azure has native support for Docker-based containers. There are also additional options, such as running a container within a virtual machine. Ideally, I’d like to avoid this approach and look for something more cloud-native. By cloud-native, I refer to Oracle’s clean definition, found here:

[..] cloud native refers to the concept of building and running applications to take advantage of the distributed computing offered by the cloud delivery model. Cloud native apps are designed and built to exploit the scale, elasticity, resiliency, and flexibility the cloud provides.” (Oracle)

Essentially, it’s about leveraging the power and flexibility of the (public) cloud to run my simple containers.

Kubernetes

The most obvious solution? Azure Kubernetes Service, or just AKS for short. The name implies that it allows you to provision and run a Kubernetes cluster in the cloud. It’s a complex beast, though, as you must think about access, security, monitoring, clusters, nodes, VNETs, ingress, development tooling, integration, container registries, etc. Then there is stuff like Dapr and Helm that might not be needed, but they are prominently there on the first page of the documentation. Running a single container image is overkill with AKS.

Putting aside the technical work required now, how much would I pay for AKS running my simple password management container? Let’s check this from the Azure Pricing Calculator.

I’ll host my container on Linux (Ubuntu), and the tier would be Basic. The virtual machines would be the cheapest AKS supports, the A0 (1 vCPU Core, 0.75 GB of RAM), and the cluster running for 730 hours per month.

Total cost for the AKS setup? 14.41 €/$16.14 (excluding bandwidth costs). I think the cluster would be sluggish with the slowest and cheapest VM, but at least it seems affordable.

[ Update: Dec 22: @matonen pointed out on Twitter that using the B1 VM SKU is slightly cheaper than the A0 I initially used. With the B1, the base cost of the VM is $8.76 ]

The other option to run containers in a Kubernetes cluster is the relatively new option called Container Apps. Instead of spinning up the cluster myself, someone else – Microsoft in this case – will run it and let me introduce my container images to be onboarded in a cluster. This is a more lightweight approach, yet it still allows me to get the ability to utilize many of the Kubernetes capabilities.

[ Another update Dec 25: After some twittering, I tested provisioning a fresh AKS cluster in Azure. The lowest VM compute option is either B4ms or A4_v2. Thus, the limitation seems to be that the VM needs at least 4 GB of RAM. Therefore, the A0 and B1 VM SKU cannot be utilized. This puts the lowest AKS pricing at around 112 €/month with the A4_v2. ]

Estimating the price for Container Apps is a bit trickier. You need to specify the number of requests (in millions) toward your app. Based on this and the execution time per request, the billable active usage (in seconds) is factored in. As my app would run throughout the month, I first tried estimating 2,600,000 seconds. This produced a running cost of 97.4 €/$109 per month. This implies that Container Apps are started when they receive a request. But I’d like my solution to run at all times – a quick lookup for a password shouldn’t take more than a second, and I fear that I’d have to wait for the container to spin up for too long each time I use my solution.

There’s an additional option to configure Container App to idle. The idle usage price is, and pay attention here, 0.0000036 € per second. The first 180,000 seconds are free. Assuming I’d first idle the whole month, I’d pay 0.0000036 € x 2,420,000 seconds = 8.7 € per month for the idle fee. Idle memory usage is almost the same billable rate, 0.0000036 € per second, and the first 360,000 GiB-seconds are free. This adds about 8 €, making the total about 16.7 €.

Perhaps I’d make 50 requests daily or about 1500 requests monthly. This falls under the default billable rate so the total cost would be about 16.7 € for a single container running at all times.

So, in comparison. AKS would cost about 14.4 €, while Container Apps would be slightly more, about 16.7 €.

They are surprisingly affordable before considering the work required to set up the solution.

What about running a single container?

Putting AKS and Container Apps aside, the other options for running containers in Azure include Azure Container Instances (ACI) and Azure Web App for Containers.

ACI is something I like. The pricing structure is also much easier to understand. You spin up a container and pay for the CPU and memory usage while it runs. The intention I get with ACI is usually to spin up a container when you need to trigger a task or a job. Then, the container is shut down once the job is completed. For my use case, the container should run at all times. So, let’s check the numbers!

Running a container with 1 GB of RAM and one vCPU Core for 2.6 million seconds adds up to 33.36€/$37.35. This is more than double what I pay for running the same solution in AKS or Container Apps.

The other option, Azure Web App for Containers, consists of running the Azure App Service with a Service Plan, and that’s mostly it. The best option is the B1 instance (with one vCPU Core and 1.75 GB of RAM) for about 48.9 €/$55 per month. Also, I’d be hesitant to run a relatively essential and sensitive service such as a password manager on a web server myself (while admittedly, the solution I use does expose an API, but it isn’t the same as running a web server directly).

In summary

I’m surprised how cheap the enterprise-grade solutions are. At the same time, I’m a bit hesitant to start up an AKS instance just for a single container. I fear the amount of work required to maintain, monitor, and secure the environment is quite a bit. Container Apps seems like a winner here, as it’s much cheaper than ACI and more secure (on the surface, at least) than the Web App for Containers.

I continue running my container on top of my Synology NAS, but now that I know the options, I’ll need to look at Container Apps more closely.