The following instructions only detail how to set up a Ubuntu VM on GCP. Compared to other potential options, a VM offers a stateful compute solution with a lower cost. Cloud run function are not good for stateful continuous networking, K8 is more expensive and offers no continuous free offering. Based on analysis at the time, a micro VM appears to be the best solution for HK Server hosting.
Caution
The suggested instances (lowest compute), is part of the free tier of google cloud at time of writing. Always confirm and see pricing details for more information. Setting a billing alert at 10.00 is a great way to protect yourself.
Note
The commands here are linux centric. Personally I am using WSL2 on windows, adjust accordingly for other OS.
-
Set up a google cloud project to use and enable GCP on your google account.
-
Go to the GCP console and select compute engine, you may need to enable the API.
-
Add ssh key to GCP for logging in, must do this before starting the VM
- Generate a new ssh key with the user name being your google user name. E.g.
ssh-keygen -t rsa -b 4096 -C <google username>
- When asked where to save this file, select somewhere in your
.ssh
folder. E.g.~/.ssh/gcp
- Get the local machine public key with
cat ~/.ssh/gcp.pub
- First registry your public ssh key with Google Cloud Project, under
compute engine > settings > metadata
which will have ssh keys tab - Add the text as SSH key and press Save
- Make sure that your firewall rules allow ssh. The GCP dashboard go VPC Network > Firewall.
default-allow-ssh
at the bottom should be present. Note this will allow anyone with a valid ssh key to log in, to restrict this see this video.
- Generate a new ssh key with the user name being your google user name. E.g.
There are two methods for creating a VM on GCP provided. The first is using manually in the web UI, the second is using terraform. Terraform is the suggested method if you are looking for reproducability.
-
Head to Google Cloud Engine and select
Create Instance
-
Hollowknight multiplayer is a pretty cheap server. So we will use a micro instance on E2 for the cheapest cost:
- VM Basics:
- Instance Name:
hollowknight-server
- Region:
us-central1
(where ever you want) - Zone:
any
- VM Provisioning:
Standard
- No time limit
- Instance Name:
- Machine Config:
- General Purpose > E2
- Preset: e2-micro (0.25 vCPU and 1GB Memory)
- OS and Storage
- Operatorating System: Ubuntu 22.04 x86
- Storage Size 10Gb
- Networking
- Allow HTTP and HTTPS traffic
- Ephemeral IP is fine, we'll connect to whatever via the domain
- Select
standard
network teir. Either select an existing or reserve a static IP likehollowknight-server
- Under Network tags add
hk-server
- Advanced
- Add startup script with the contents of
terraform/install_docker.sh
- Add startup script with the contents of
If it is planned to connect a domain to this IP it may be beneficial to reserve a static IP that can be used between VMs. DNS records take a while to update so having a fixed IP for GoDaddy to point to is useful. However, be aware that Google charges more for IPs that are static but not in use.
- VM Basics:
-
After launching, the instance should be visible under the VM Instances.
-
Next create a firewall exceptions for both HKMP and HKMW. Assuming that the default ports are being used, forward
2222
and3333
on the VM's IP:- Navigate to
VPC network > Firewall
- Click
Create Firewall Rule
, name ithollowknight-server
with descriptionHollow Knight multiplayer server port
. - Set priority to anything, since this is low priority set this to
2000
(lower = higher priority). - For network direction select
Ingress
- Under
Targets
selectSpecified target tags
and enter taghk-server
. This needs to match the tag added to the VM's network tags. If you forgot about this, edit the VM's details in the compute engine. - For the source filter select
IPv4
and then set the ranges to0.0.0.0/0
which will allow all IP ranges (be careful, we have no LB). - In protocols / ports, select
UDP
and add port2222
(multiplayer) - In protocols / ports, select
TCP
and add port3333
(itemsync) - Click create and you should see this rule appear in the firewall list
Note that you can watch the network activity of the VM using the observability window.
- Navigate to
Terraform is infra by code. It is by far the best way to get a reproducable VM up and running as easy as possible. Additionally, it ensures that everything is torn down correctly once you're done playing. Installing terraform is easy on all platforms.
Terraform will need to interact with GCP APIs, so we will need to have a valid account for it to use. For authentication, we will use our personal account since we are running terraform on our local machine. Reference, you only need to do this once.
-
Install the GCP CLI, test it is installed with
gcloud --help
-
Authenticate with
gcloud init
-
To allow terraform to log in, we will need to acquire new user credientials using
gcloud auth application-default login
. Note where the credential JSON file gets saved (e.g.~/.config/gcloud/application_default_credentials.json
). This JSON will look something like:{ "account": "", "client_id": "xxx.apps.googleusercontent.com", "client_secret": "...", "quota_project_id": "your-project-name", "refresh_token": "1//...", "type": "authorized_user", "universe_domain": "googleapis.com" }
- Navigate to the terraform folder and initize terraform state with
terraform init
- Validate the terraform configs with:
terraform plan \ -var credential_file=<path to credential json>
- Apply terraform config using:
terraform apply \ -var credential_file=<path to credential json> \ -var project=<gcp project name> \ -var username=<google username>
- If terraform completes successfully, the machines public IP will be printed
Note
Customize the properties of VM inside the variables.tf or via CLI commands.
Note
While the VM may be started, the start up script (which installs docker) will take a minute or two to complete.
Upon start up, the server should show up in the VM Instances.
- Get the external IP of the sever from the VM dashboard
- Connect to the running VM using
ssh -i ~/.ssh/gcp <username>@<external ip-address>
- Once logged in use
id -Gn
to see what you are added to the docker user group- If you so not see "docker" run
sudo usermod -aG docker $USER
- Relog into the VM
- If you so not see "docker" run
- Check docker is installed fine with
docker ps
, which should show no containers running- If docker is not installed, the start up script failed. Try running the commands in
terraform/install_docker.sh
manually - Can view start up script issues in
/var/log/syslog
if you want to debug. The start up could still be running.
- If docker is not installed, the start up script failed. Try running the commands in
Refer to the respective server Readme for what you want to run under the docker folder.
To clean up the VM, simply delete the instance on the Google Cloud Engine page.
terraform destroy