Skip to content
Go back

Local Testing for Godot Web Builds with Docker & Nginx

Published:  at  21:00

Godot Web Build Testing Banner

Hey Grinders!

One common hurdle when developing games with Godot Engine for the web platform (HTML5 export) is testing the build locally. Simply opening the index.html file directly in your browser using a file:// path often doesn’t work correctly, especially with Godot 4. This is because modern web browsers require specific security headers (Cross-Origin-Embedder-Policy and Cross-Origin-Opener-Policy) for features like SharedArrayBuffer to work, which Godot often relies on for performance (especially with threads).

Without these headers, you might encounter errors or find that your game doesn’t load at all. The solution is to serve the files using a proper web server. While there are many ways to do this, we’ve found using Docker Compose and a minimal Nginx configuration to be a clean, repeatable, and efficient method.

Here’s how you can set it up:

Prerequisites

  1. Docker & Docker Compose: Ensure you have both installed on your system. You can get them from the official Docker website.
  2. Godot Web Export: You need to have exported your Godot project for the Web platform.

The Setup

We’ll use two files: a docker-compose.yml file to define our Nginx service and a simple Nginx configuration file.

1. Directory Structure:

Organize your files like this:

your-project-root/ ├── export/ │ └── web/ <— Your Godot web build files go here (index.html, etc.) └── infra/ ├── docker-compose.yml └── nginx/ └── default.conf <— Our Nginx configuration

Important: Make sure your Godot web export target directory matches the path specified in the docker-compose.yml volume mount (in this example, ../export/web relative to the docker-compose.yml file). Adjust the path if your structure differs.

2. docker-compose.yml:

Create this file in your project root (or wherever makes sense for your workflow). Its content defines the Nginx service.

services:
  godot_webuild_server:
    image: nginx:latest
    container_name: godot_webuild_server
    ports:
      - "9090:80"
    restart: unless-stopped
    volumes:
      # NOTE: Change the `./../export/web` path to where ever your Godot Webbuild is exported to!
      - ./../export/web:/usr/share/nginx/html:ro
      - ./nginx:/etc/nginx/conf.d

3. Nginx Configuration (nginx/default.conf):

Create a file named default.conf (or any .conf name) inside the nginx folder. This file tells Nginx how to serve your game files and adds the necessary headers.

server {
    listen 80;
    server_name localhost;

    add_header Cross-Origin-Embedder-Policy 'require-corp';
    add_header Cross-Origin-Opener-Policy 'same-origin';

    location / {
        root /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ =404;

        types {
            application/wasm wasm;
            text/html html;
            application/javascript js;
            text/css css;
        }
    }
}

Running Your Web Build Locally

  1. Export your Godot project to the export/web directory (or whichever directory you specified in docker-compose.yml).
  2. Open your terminal and navigate to the directory containing your docker-compose.yml file.
  3. Run the server:
# The `-d` flag runs the container in detached mode (in the background).
docker compose up -d
  1. Open your web browser and go to: http://localhost:9090
  2. Your Godot web build should now load and run correctly!

Stopping the Server

When you’re done testing, navigate back to the directory with docker-compose.yml in your terminal and run:

docker compose down

This will stop and remove the container defined in the Compose file.


That’s it! With this simple Docker Compose and Nginx setup, you can easily spin up a local web server that correctly serves your Godot web exports with the necessary headers, making local testing much smoother. It keeps your main system clean and provides a consistent testing environment.

Happy developing!



Next Post
It's a Wrap! Our DCJam2025 Entry "Enter the Mansion" is Submitted!