Custom Game Server Scaling Reference Architecture

Learn how to containerize your game server with Docker, and build a reliable, automated deployment process for servers using Azure Resource Manager templates, Azure Functions and DevOps practices.

Refer to Orchestrating and scaling Icebird's game server with Docker and Azure to read all the details. There is both source code and a deployment template available on GitHub.

Architecture diagram

Basic game server hosting using encapsulation

Reference implementation details

Each virtual machine includes a Docker container that runs a game session. As soon as the virtual machine starts, it instantiates the Docker container and opens the required network port(s) through a custom script extension (Linux, Windows). Every container has it's own public dedicated IP address.

Additionally, there is a get server Azure Function, that runs on an App Service plan, which allows for additional scaling options as described in the App Service environment document. Any App Service must have an Azure Storage account and, the Azure Function service will provision it. In this storage account, an Azure Table Storage table is used to store the information about the pool of servers, including the unique identifier of the server, its IP address, port, and status. The get server Azure Function uses this information to return connection details to the client, as well as to mark a server as not available when it is being used.

To help scale the server pool, a timer-triggered auto-scale Azure Function is used. Every minute or so, it looks how many servers are available and adds additional servers if they are required. If there are too many servers in the pool that are unused, it will deprovision them. You can set up how many servers you want to have warm in the pool.

Once a game server starts, it needs to talk to a third send details Azure Function to announce its existence, so the pertinent connection information can be updated in Azure Table Storage.

After a game session is finished, the game server pings a fourth game session over Azure Function that updates the state of the Azure Table Storage for that specific server.

Ultimately the goal is to free up the virtual machines as fast as possible, so this architecture is focusing on having a single game session per virtual machine only.

Keep an eye on the Azure limits page to know how many concurrent users you would be able to run based on the Azure Storage limitations. If you need to scale up, consider replacing Azure Table storage with Azure Cosmos DB and its table API.

Deployment template

Click the following button to deploy the project to your Azure subscription:

Deploy to Azure

This operation will trigger a template deployment of the template.json ARM template file to your Azure subscription, which will create the necessary Azure resources. This may induce charges in your Azure account.

Have a look at the general guidelines documentation that includes an article summarizing the naming rules and restrictions for Azure services.


If you're interested in how the ARM template works, review the Azure Resource Manager template documentation from each of the different services leveraged in this reference architecture:


To run the Azure Functions locally, update the local.settings.json file with these same app settings.


If you don't have an Azure subscription, create a free account to get started with 12 months of free services. You're not charged for services included for free with Azure free account, unless you exceed the limits of these services. Learn how to check usage through the Azure Portal or through the usage file.

You are responsible for the cost of the Azure services used while running these reference architectures. The total amount will vary based on usage. See the pricing webpages for each of the services that were used in the reference architecture:

You can also use the Azure pricing calculator to configure and estimate the costs for the Azure services that you are planning to use.