Skip to content

Commit

Permalink
Build Docker image for Game Server in Cloud Build (#114)
Browse files Browse the repository at this point in the history
IT'S ALIVE (and surprisingly easy to do!)

This has:

* Dockerfile for the Unreal Engine Dedicated game server, built with the
  Unreal development container.
* Documentation updates on how access the Unreal development containers.
* Create the secret for the GitHub personal access token via Terraform.
* Cloud Build script to create the image.

Closes #29
  • Loading branch information
markmandel authored Mar 7, 2023
1 parent bd35d19 commit 3991e44
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 5 deletions.
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ cd global-multiplayer-demo
export GAME_DEMO_HOME=$(pwd)
```

### Access to Unreal Engine Container Images

To build the Dedicated Game Server you will need access to the Unreal Engine GitHub organisation.

To do so, follow: [Accessing Unreal Engine source code on GitHub](https://www.unrealengine.com/en-US/ue-on-github).

Once done, to pull down the [Unreal Development Containers](https://unrealcontainers.com/), you will also need to
create [a personal access token (classic)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-personal-access-token-classic)
with at least `read:packages` scope.

Leave the page open with this token, as we'll need it shortly.

## Provision

### Optional: GCS Backend
Expand All @@ -78,6 +90,7 @@ You will need to now edit `terraform.tfvars`

* Update <PROJECT_ID> with the ID of your Google Cloud Project,
* Updated <CLIENT_ID> and <CLIENT_SECRET> with the Client ID and Client secret created in the above step.
* Updated <GITHUB_PAT> with the GitHub personal access token you created the above steps.

You can edit other variables in this file, but we recommend leaving the default values for your first run before
experimenting.
Expand Down Expand Up @@ -112,7 +125,7 @@ This should give you back an IP, such as `35.202.107.204`.
Since OAuth needs a domain to authenticate against, we'll use [sslip.io](https://sslip.io) for development purposes.

### Deploy Platform Components
Replace the` _RELEASE_NAME` substitution with a unique build name. Cloudbuild will deploy
Replace the` _RELEASE_NAME` substitution with a unique build name. Cloud Build will deploy

- Anthos Service Mesh (ASM) to all clusters using the fleet feature API
- Agones using Cloud Deploy
Expand All @@ -123,14 +136,17 @@ cd $GAME_DEMO_HOME/platform/
gcloud builds submit --config=cloudbuild.yaml --substitutions=_RELEASE_NAME=rel-1
```

Navigate to the [agones-deploy-pipeline](https://console.cloud.google.com/deploy/delivery-pipelines/us-central1/agones-deploy-pipeline) delivery pipeline to review the rollout status. Cloudbuild will create a Cloud Deploy release which automatically deploys Agones the first game server cluster. Agones can be deployed to subsequent clusters by clicking on the `promote` button within the Pipeline visualization or by running the following gcloud command:
Navigate to the [agones-deploy-pipeline](https://console.cloud.google.
com/deploy/delivery-pipelines/us-central1/agones-deploy-pipeline) delivery pipeline to review the rollout status.
Cloud Build will create a Cloud Deploy release which automatically deploys Agones the first game server cluster. Agones can be deployed to subsequent clusters by clicking on the `promote` button within the Pipeline visualization or by running the following gcloud command:

```shell
# Replace RELEASE_NAME with the unique build name
gcloud deploy releases promote --release=RELEASE_NAME --delivery-pipeline=agones-deploy-pipeline --region=us-central1`
```

Continue the promotion until Agones has been deployed to all clusters. You can monitor the status of the deployment through the Cloud Logging URL returned by the `gcloud builds` command as well as the Kubernetes Engine/Worloads panel in the GCP Console.
Continue the promotion until Agones has been deployed to all clusters. You can monitor the status of the deployment
through the Cloud Logging URL returned by the `gcloud builds` command as well as the Kubernetes Engine/Workloads panel in the GCP Console.

Open Match rollout status can be viewed by navigating to the [global-game-open-match](https://console.cloud.google.com/deploy/delivery-pipelines/us-central1/global-game-open-match) delivery pipeline. Since open match is deployed onto a single services GKE cluster, deployments are automatically rolled out with no need for manual promotion.

Expand All @@ -150,6 +166,20 @@ This will:
* Store those image in [Artifact Registry](https://cloud.google.com/artifact-registry)
* Deploy them via Cloud Build to a Autopilot cluster.

## Dedicated Game Server

To build the Unreal dedicated game server image, run the following command:

```shell
cd $GAME_DEMO_HOME/game
gcloud builds submit --config=cloudbuild.yaml
```

This will:

* Build the image for the dedicated game server.
* Store those image in [Artifact Registry](https://cloud.google.com/artifact-registry).

## Game Client

To build the Game Client for your host machine, you will need:
Expand Down
26 changes: 26 additions & 0 deletions game/.gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2023 Google LLC All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

.vs
*.blend1
*.fbx
Binaries
Build
DerivedDataCache
Droidshooter.sln
Intermediate
Packaged
Saved
*.code-workspace
/Makefile
15 changes: 15 additions & 0 deletions game/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# Copyright 2023 Google LLC All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

!.gcloudignore
.vs
*.blend1
*.fbx
Expand Down
34 changes: 34 additions & 0 deletions game/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# Build a container for the Unreal Engine dedicated game server
#

FROM ghcr.io/epicgames/unreal-engine:dev-slim-5.1.0 as builder
ARG SERVER_CONFIG=Development

COPY --chown=ue4:ue4 . /tmp/project

RUN /home/ue4/UnrealEngine/Engine/Build/BatchFiles/RunUAT.sh BuildCookRun \
-Server -NoClient -ServerConfig=${SERVER_CONFIG} \
-Project=/tmp/project/Droidshooter.uproject \
-UTF8Output -NoDebugInfo -AllMaps -NoP4 -Build -Cook -Stage -Pak -Package -Archive \
-ArchiveDirectory=/tmp/project/Packaged \
-Platform=Linux

FROM gcr.io/distroless/cc-debian11:nonroot
COPY --from=builder --chown=nonroot:nonroot /tmp/project/Packaged/LinuxServer /home/nonroot/project
EXPOSE 7777/udp
ENTRYPOINT ["/home/nonroot/project/Droidshooter/Binaries/Linux/DroidshooterServer", "Droidshooter"]
33 changes: 32 additions & 1 deletion game/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
# Droidshooter

World scale demo for Google and Google Cloud for Games
This is the Unreal Engine 5.1.0 project for the DroidShooter game!

## Local Builds

## Dedicated Game Server Docker Image

```shell
docker build . -t droidshooter-server
```

To run, you will need a copy of Agones [local SDK](https://agones.dev/site/docs/guides/client-sdks/local/) toolkit.

In one shell, start the local testing SDK server:

```shell
./sdk-server.linux.amd64 --local
```

Then in another shell:

```shell
docker run --rm --network=host droidshooter-server:latest
```

(In non *nix OS's where Docker is not native, you may need to do a slightly different network configuration to get the
same experience)

You now have a dedicated game server running on 127.0.0.1:7777

## Client building

See the top level [README.md](../README.md#game-client) game client section for full launch instructions.
39 changes: 39 additions & 0 deletions game/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2023 Google LLC All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
steps:
- name: gcr.io/cloud-builders/docker
id: github-login
script: |
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
secretEnv:
- CR_PAT
- name: gcr.io/cloud-builders/docker
id: build-image
args: ["build", ".", "-t", "${_UNREAL_SERVER_IMAGE}"]
artifacts:
images:
- ${_REGISTRY}/droidshooter-server
substitutions:
_UNREAL_SERVER_IMAGE: ${_REGISTRY}/droidshooter-server:${BUILD_ID}
_REGISTRY: us-docker.pkg.dev/${PROJECT_ID}/global-game-images
availableSecrets:
secretManager:
- versionName: projects/${PROJECT_ID}/secrets/github-packages/versions/latest
env: CR_PAT
options:
dynamic_substitutions: true
machineType: E2_HIGHCPU_32
logging: CLOUD_LOGGING_ONLY
41 changes: 41 additions & 0 deletions infrastructure/game-server.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2023 Google LLC All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

resource "google_secret_manager_secret" "secret_github_packages" {
secret_id = "github-packages"

labels = {
"environment" = var.resource_env_label
}

replication {
automatic = true
}
}

resource "google_secret_manager_secret_version" "pat_1" {
secret = google_secret_manager_secret.secret_github_packages.id
enabled = true

secret_data = var.github_pat
}

resource "google_secret_manager_secret_iam_binding" "cloud_build_binding" {
project = var.project
secret_id = google_secret_manager_secret.secret_github_packages.id
role = "roles/secretmanager.secretAccessor"
members = [
"serviceAccount:cloudbuild-cicd@${var.project}.iam.gserviceaccount.com",
]
}
5 changes: 4 additions & 1 deletion infrastructure/terraform.tfvars.sample
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,7 @@ app_service_account_config = {
}

# Agones GKE Service Account Name
k8s_service_account_id = "k8s-service-account"
k8s_service_account_id = "k8s-service-account"

# Github Personal Access Token
github_pat = "<GITHUB_PAT>"
6 changes: 6 additions & 0 deletions infrastructure/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,9 @@ variable "services_directory" {
description = "Services Directory for output to Cloud Deploy related files"
}

### Dedicated Game Server Variables

variable "github_pat" {
type = string
description = "A GitHub personal access token (classic) with at least read:packages scope"
}

0 comments on commit 3991e44

Please sign in to comment.