Skip to main content

Automating deployments

Now that you've got game server containers running on your Kubernetes cluster, you'll want to automate the build and deployment of your game server containers from your build server. To do this, we're going to use two tools to simplify the build and deployment process:

  • Unreal Engine Scripts. These PowerShell scripts make it easy to build, test and deploy Unreal Engine games.
  • skaffold. This tool builds Docker containers and deploys Kubernetes resources to a cluster.

Preparing for automation

Before continuing with automation, you'll need to perform the following steps:

  • Ensure that your Unreal Engine project is in a subdirectory of your source control repository. That is, if your source control repository is at a path <root>, then your Unreal Engine project file should be at a location like <root>\MyProject\MyProject.uproject.
  • Move the Dockerfile you created in Preparing your game server into your project folder, and update the paths inside the Dockerfile to use Saved/StagedBuilds/LinuxServer as the source location of the server. This is the subdirectory that the Unreal Engine scripts will build the Linux server into.

Setting up Unreal Engine Scripts

To make it easy to build the Unreal Engine server binaries, we'll use a collection of scripts that we've developed at Redpoint Games called the "Unreal Engine Scripts".

Cloning the Unreal Engine Scripts

If you're using Git as your source control provider, you can add the Unreal Engine scripts to your source code repository with the following command:

git submodule add https://src.redpoint.games/redpointgames/unreal-engine-scripts BuildScripts

Otherwise, clone the Unreal Engine Scripts somewhere on your machine, and then copy the contents of the cloned folder into a new folder called BuildScripts inside your source control repository.

Creating BuildConfig.json

Next, create a file called BuildConfig.json in the root of your source control repository, and give it the following content, replacing MyProject where appropriate. You should also replace DebugGame with Shipping when you want to ship into production, but DebugGame can be useful for debugging while you're trying to get everything working.

{
"Distributions": [
{
"Name": "MyProject",
"FolderName": "MyProject",
"ProjectName": "MyProject",
"Build": {
"Editor": {
"Target": "MyProjectEditor"
},
"Game": {
"Targets": [
"MyProject"
],
"Platforms": [
"Win64"
],
"Configurations": [
"DebugGame"
]
},
"Server": {
"Targets": [
"MyProjectServer"
],
"Platforms": [
"Linux"
],
"Configurations": [
"DebugGame"
]
}
},
"Deployment": [
{
"Name": "Agones Server",
"Type": "Custom",
"Manual": false,
"Package": {
"Type": "Server",
"Target": "MyProjectServer",
"Platform": "Linux",
"Configuration": "DebugGame"
},
"Custom": {
"ScriptPath": "BuildScriptsExtra/DeployAgonesServer.ps1"
}
}
]
}
]
}

Creating DeployAgonesServer.ps1

Next, create a file called DeployAgonesServer.ps1 underneath a new folder called BuildScriptsExtra in the root of your repository, with the following content:

param(
[Parameter(Mandatory=$true)][string] $EnginePath,
[Parameter(Mandatory=$true)][string] $StageDirectory,
[Parameter(Mandatory=$true)][string] $PackageDirectory,
[Parameter(Mandatory=$true)][string] $PackageType,
[Parameter(Mandatory=$true)][string] $PackageTarget,
[Parameter(Mandatory=$true)][string] $PackagePlatform,
[Parameter(Mandatory=$true)][string] $PackageConfiguration
)

# The parameters passed into this script contain the paths and information about
# the packaged game server. At the moment we've just hard-coded the relative paths
# into the Dockerfile, but if you wanted to re-use this script for different builds
# you could generate the Dockerfile based on the parameters and then run Skaffold.

# Add --kube-context= to pick a specific Kubernetes cluster to deploy to.
skaffold run -f "skaffold.yaml"
exit $LastExitCode

Review your project repository

After adding the Unreal Engine Scripts and required files, your source code repository should have the following structure:

- BuildScripts/
- Build.ps1 (from the Unreal Engine Scripts repository)
- ... (from the Unreal Engine Scripts repository)
- BuildScriptsExtra/
- DeployAgonesServer.ps1
- MyProject/
- MyProject.uproject
- ... (other Unreal Engine project files and folders like Content)
- BuildConfig.json

Testing the build

At the command prompt, inside the folder of your source code repository, you should now be able to run the following command:

powershell .\BuildScripts\Build.ps1 -Engine C:\Path\To\UnrealEngine -Distribution MyProject

This won't deploy the server or build the Dockerfile. We need to set up Skaffold in the next section, and then we can test actual deployment by adding -ThenDeploy to the command above.

caution

You must run the command above, since we'll be manually testing skaffold after setting it up, and we need the Linux game server binaries already built.

Setting up Skaffold

Skaffold is used to build and deploy the packaged game server to your Kubernetes cluster.

Creating skaffold.yaml

In the root of your repository, create a file called skaffold.yaml and give it the following contents. You'll need to replace the image URL with your GitLab registry URL:

apiVersion: skaffold/v2beta25
kind: Config
build:
artifacts:
- image: registry.gitlab.com/mygroup/myproject/game-server
context: MyProject
docker:
dockerfile: Dockerfile
local:
push: true
useBuildkit: true
deploy:
kubectl:
manifests:
- game-server.yaml

Then, create a file called game-server.yaml and give it the following contents. Again, replace the image URL as appropriate:

apiVersion: "agones.dev/v1"
kind: Fleet
metadata:
name: eos-dedicated-server
spec:
replicas: 2
template:
spec:
ports:
- name: game
containerPort: 7777
template:
spec:
imagePullSecrets:
- name: gitlab
containers:
- name: eos-dedicated-server
image: registry.gitlab.com/mygroup/myproject/game-server
resources:
requests:
memory: "1Gi"
cpu: "1500m"
limits:
memory: "1Gi"
cpu: "1500m"
---
apiVersion: "autoscaling.agones.dev/v1"
kind: FleetAutoscaler
metadata:
name: eos-dedicated-server-autoscaler
spec:
fleetName: eos-dedicated-server
policy:
type: Buffer
buffer:
bufferSize: 2
minReplicas: 2
maxReplicas: 20

Testing skaffold

You can now test the skaffold deployment by running:

skaffold run

It should package up the previously built binaries, push the packaged game server to the registry and then start the Agones fleets in the Kubernetes cluster.

Updating your build server configuration

If you're using GitLab, refer to Building and testing on GitLab for additional instructions. Otherwise, update your current build server configuration to run the following command:

powershell .\BuildScripts\Build.ps1 -Engine C:\Path\To\UnrealEngine -Distribution MyProject -ThenDeploy

Further steps

This document is intended to be a starting point for automating your deployment. You can improve on this deployment pipeline in a few ways:

  • Currently when this pipeline deploys, it'll replace any idle game servers with the new version. Since you're likely not releasing the game client at the exact same time this deployment runs, you'll want to run multiple fleets (with different game version) in parallel. A suggestion is to create a Helm chart for side-by-side fleet deployments, and to update your Skaffold configuration to use the chart.
  • This pipeline deploys to a single Kubernetes cluster that your build server is configured to access. If you need to deploy to multiple Kubernetes clusters, you'll probably need to run the skaffold build and skaffold deploy commands separately, running skaffold deploy --kube-context=... for each Kubernetes cluster you have configured.