Skip to main content

Deploying Locally

Deploying Redwood uses the provided Infrastructure-as-Code (IaC); the same workflow is used to deploy to a local development Kubernetes cluster as well as production ones.

If you installed all of the prerequisites properly, you're ready to test deploying the Redwood backend to your local Kubernetes cluster (which Rancher Desktop hosts within WSL). Altogether, this setup gives us a Linux environment that has Docker and Kubernetes, which is very similar to what deploying to a cloud provider would look like.

Redwood Configuration

While it's not strictly required to set up a configuration environment for development for just getting started, it will be convenient to have it when you inevitably want to change something.

  1. Create a new folder in config/node for the Kubernetes dev environment (e.g. redwood-demo-k8s [k8s is a common abbreviation for Kubernetes])

  2. Create a _config.json file in that folder (e.g. config/node/redwood-demo-kubernetes/_config.json) with the parentNames pointing to the environment folder you created earlier and the provided kubernetes environment.

    For example:

    {
    "parentNames": ["kubernetes", "redwood-demo"]
    }
    note

    You might have started to noticed the inheritance pattern we've been introducing for configuration. In our examples, we have the config env redwood-demo-kubernetes inherit from redwood-demo. Later, when we deploy to a cloud, you'll see that we'll introduce a config env redwood-demo-production that inherits from redwood-demo-kubernetes. This pattern isn't required, but it can prevent issues where a config variable was added for development but not for production.

    You can read more about configuration inheritance here.

Pulumi Configuration

Now that we have our project configuration environment, we need to create the associated Pulumi configuration.

  1. Under the RedwoodBackend directory, create the file packages/deployment/environments.json with the below contents; replace <key> with the appropriate values (without <>). Replace <config-environment> with the name of the folder you created above.

    {
    "development": {
    "stack": "<pulumi-org-name>/<project-name>/dev-<developer identifier>",
    "config": "<config-environment>"
    }
    }

    The stack during development shouldn't be shared with your teammates if they're also developing with the backend, which is why there's an additional ID of sorts added at the end. This can be your name, initials, or any way to differentiate you from the others on your team.

    For example:

    {
    "development": {
    "stack": "incanta/redwood-demo/dev-mike",
    "config": "redwood-demo-kubernetes"
    }
    }
  2. Under the RedwoodBackend directory, create the file packages/deployment/Pulumi.yaml with the below contents; replace <key> with the appropriate values (without <>)

    name: "<your-project-name>"
    runtime: "nodejs"
    description: "<anything you'd like to see on the Pulumi dashboard; eg. Backend for <project name>"

    For example:

    name: "redwood-demo"
    runtime: "nodejs"
    description: "Backend for the Redwood Demo"
info

The two files in the packages/deployment folder that we just added (environments.json and Pulumi.yaml) can be shared with your teammates. However, make sure the stack under development in the environments.json file is different for each of you. You would share the same stack for production uses, but your individual local deployments should be kept separate. However, you should share the same organization and project names.

Deploying

Deploying locally for basic configurations is fairly straight forward:

  1. Ensure Rancher Desktop is running

  2. Open a terminal to the RedwoodBackend directory

  3. Install the NodeJS dependencies by running the below command:

    yarn
    note

    yarn will automatically trigger a build, but you can recompile manually by running yarn build.

  4. If you're on the Full Version of Redwood, you need to package the sidecar package

    info

    Skip this step if you're using the Evaluation Version.

    yarn pkg:sidecar
  5. Copy the folder generated when you packaged the Linux Server to RedwoodBackend/dist; it will have the name LinuxServer

    Copying the LinuxServer folder to the dist folder

  6. Deploy the Redwood backend by running the below command:

    yarn up

    This command will do the following:

    1. Create the necessary Docker containers
    2. Deploy the necessary dependencies to the local Kubernetes cluster
    3. Deploy the Redwood containers to the local Kubernetes cluster
    note

    The Evaluation version comes with the microservice executables prepackaged so that step is skipped.

  7. You will be prompted if you want to create the stack you defined in environments.json; if the name of the stack looks right, press the Enter key:

    $ yarn up
    yarn run v1.22.19
    $ cd packages/deployment && yarn up
    $ node ./run.js up development
    The stack 'incanta/redwood-demo/dev-mike' does not exist.

    If you would like to create this stack now, please press <ENTER>, otherwise press ^C:
  8. Pulumi will start generating a preview of the deployment; no changes are made and you'll be prompted if the proposed changes should be applied. Press the Up arrow to select yes and press the Enter key:

    Created stack 'incanta/dev-mike'
    Previewing update (incanta/dev-mike)

    View in Browser (Ctrl+O): https://app.pulumi.com/incanta/redwood-demo/dev-mike/previews/2f235049-fc1c-49c7-9172-f20f374aed82

    Type Name Plan
    + pulumi:pulumi:Stack redwood-demo-dev-mike create
    + ├─ docker:index:Image yourcr.com/container/redwood-dev-image create
    + ├─ docker:index:Image yourcr.com/container/game-server-image create
    + ├─ pulumi:providers:kubernetes k8s-provider-local create
    + ├─ kubernetes:core/v1:ConfigMap game-server-config-map-local create
    + ├─ kubernetes:helm.sh/v3:Release redis create
    + ├─ kubernetes:helm.sh/v3:Release ingress create
    + ├─ kubernetes:helm.sh/v3:Release open-match create
    + ├─ kubernetes:helm.sh/v3:Release mongo create
    + ├─ kubernetes:helm.sh/v3:Release agones-local create
    + ├─ kubernetes:core/v1:ConfigMap director-frontend-config-map-local create
    + ├─ kubernetes:core/v1:ServiceAccount realm-backend-account-local create
    + ├─ kubernetes:core/v1:ConfigMap director-backend-config-map-local create
    + ├─ kubernetes:rbac.authorization.k8s.io/v1:Role gameservers-allocations-role-local create
    + ├─ kubernetes:core/v1:ConfigMap match-function-config-map-local create
    + ├─ kubernetes:networking.k8s.io/v1:Ingress director-ingress-local create
    + ├─ kubernetes:agones.dev/v1:Fleet agones-fleet-local create
    + ├─ kubernetes:apps/v1:StatefulSet director-frontend-local create
    + ├─ kubernetes:autoscaling.agones.dev/v1:FleetAutoscaler agones-fleet-autoscaler-local create
    + ├─ kubernetes:apps/v1:StatefulSet match-function-local create
    + ├─ kubernetes:rbac.authorization.k8s.io/v1:RoleBinding read-gameservers-write-allocation-local create
    + ├─ kubernetes:core/v1:Service director-frontend-debug-local create
    + ├─ kubernetes:core/v1:Service director-frontend-local create
    + ├─ kubernetes:core/v1:Service match-function-debug-local create
    + ├─ kubernetes:core/v1:Service match-function-local create
    + ├─ kubernetes:apps/v1:StatefulSet director-backend-local create
    + ├─ kubernetes:core/v1:Service realm-backend-local create
    + ├─ kubernetes:core/v1:Service director-backend-debug-local create
    + └─ kubernetes:core/v1:Service director-backend-local create
    Outputs:
    k8sId: "Local Deployment"

    Resources:
    + 29 to create

    Do you want to perform this update? [Use arrows to move, type to filter]
    yes
    > no
    details
    note

    You can skip Pulumi previews by passing the -y or --yes argument to yarn up/destroy commands, i.e.

    yarn up -y
  9. The deployment will be finished when the output stops changing and you see the final output similar to the below:

    Outputs:
    k8sId: "Local Deployment"

    Resources:
    + 32 created

    Duration: 2m8s

Testing

Testing with a local Kubernetes deployment is very similar to testing without Kubernetes. The Unreal client tries to connect to the Director Frontend at ws://localhost:3001, so all you need to do is forward the port from within Rancher Desktop.

Port Forwarding Tab

Port Forwarding for Director Frontend

Deploying to the Cloud

success

You now have a local Kubernetes cluster that hosts the same microservices that get deployed a production environment on the cloud. Most of your development and testing will be done locally, but it's important to test deploying to the cloud well before it's time to release your game.

Whenever you're ready to test deploying to the cloud, you can read more about it here.