Skip to content

Repository files navigation

OpenSimulator / OS Grid Docker Stack

This is yet another Docker build of OpenSimulator, with a focus on getting up and running as fast as possible for new users, but with some flexiblilty for the more experienced.

  1. Source mode: clone OpenSimulator from git and build inside Docker.
  2. Release mode: download official OpenSimulator binary release archive.
  3. OSGrid mode: download OSGrid-ready package and generate Regions.ini from minimum required values.

AI Experiments

It also contains experiments in AI by integrating opensim-console2mcp as part of the stack. This communicates with OpenSim using the RestConsole.

You just need something to talk to that MCP server.

Files

  • Dockerfile
  • docker-compose.yml (source mode default)
  • docker-compose.release.yml (official binary release override)
  • docker-compose.osgrid.yml (OSGrid override)
  • .env.example
  • docker/init-standalone.sh
  • docker/init-osgrid.sh
  • docker/entrypoint.sh

Prerequisites

  • Docker Engine
  • Docker Compose v2 (docker compose)

Quick Start

0) Initialize environment file

cp .env.example .env

Optional launcher scripts

The project includes helper scripts that run the correct compose command for each mode:

  • ./run-source.sh
  • ./run-release.sh
  • ./run-osgrid.sh

Each script will auto-create .env from .env.example if it does not exist.

Mode 1: Build from source cloned from git

This is the default compose stack (docker-compose.yml). It clones from:

  • git://opensimulator.org/git/opensim

You can override clone URL/ref via .env:

  • OPENSIM_GIT_URL
  • OPENSIM_GIT_REF

Run:

docker compose up --build

Or use:

./run-source.sh

This mode runs standalone OpenSimulator with MariaDB.

Mode 2: Build from official OpenSimulator binary release archive

This mode runs its own standalone + MariaDB stack, but the OpenSim binaries come from an official download archive instead of compiling source.

Default URL in .env.example:

You may switch to zip/tar.gz by setting OPENSIM_RELEASE_URL.

Run:

docker compose -f docker-compose.release.yml up --build

Or use:

./run-release.sh

Mode 3: OSGrid-ready Hypergrid package

This mode downloads the OSGrid distribution:

It includes its own MariaDB service in this compose stack. It creates Regions/Region.ini with the minimum required details for joining Hypergrid.

Required variables in .env for this mode:

  • OSGRID_REGION_NAME
  • OSGRID_REGION_UUID
  • OSGRID_REGION_LOCATION
  • OSGRID_EXTERNAL_HOSTNAME

Optional:

  • OSGRID_INTERNAL_PORT (default 9000)

Run:

docker compose -f docker-compose.osgrid.yml up --build

Or use:

./run-osgrid.sh

Required OSGrid Region Fields

The generated Regions/Region.ini contains:

  • Region Name (OSGRID_REGION_NAME)
  • RegionUUID (OSGRID_REGION_UUID)
  • Location (OSGRID_REGION_LOCATION)
  • ExternalHostName (OSGRID_EXTERNAL_HOSTNAME)

Standalone (MariaDB) Variables

These apply to modes 1 and 2:

  • OPENSIM_HOSTNAME
  • OPENSIM_REGION_NAME
  • OPENSIM_REGION_X
  • OPENSIM_REGION_Y
  • OPENSIM_REGION_PORT
  • OPENSIM_ESTATE_NAME
  • OPENSIM_ESTATE_OWNER_FIRST
  • OPENSIM_ESTATE_OWNER_LAST
  • OPENSIM_ESTATE_OWNER_PASSWORD
  • OPENSIM_ESTATE_OWNER_EMAIL
  • OPENSIM_ESTATE_OWNER_UUID
  • OPENSIM_GRID_NAME
  • OPENSIM_GRID_NICK
  • OPENSIM_WELCOME_MESSAGE
  • OPENSIM_CONSOLE_MODE
  • OPENSIM_CONSOLE_USER
  • OPENSIM_CONSOLE_PASS
  • MARIADB_HOST
  • MARIADB_DATABASE
  • MARIADB_USER
  • MARIADB_PASSWORD
  • MARIADB_ROOT_PASSWORD

Legacy compatibility: MYSQL_* names are still accepted as fallbacks, but new setups should use MARIADB_*.

REST Console

This project enables the OpenSimulator REST console by default via:

  • OPENSIM_CONSOLE_MODE=rest
  • OPENSIM_CONSOLE_USER
  • OPENSIM_CONSOLE_PASS

The REST endpoints are available on the simulator HTTP port:

  • POST /StartSession/
  • POST /ReadResponses/<SessionID>/
  • POST /SessionCommand/
  • POST /CloseSession/

For default standalone settings, this is usually:

  • http://<host>:${OPENSIM_REGION_PORT}

If you already initialized a config volume before enabling these settings, recreate the stack with volumes to regenerate config files:

docker compose down -v
docker compose up --build -d

OpenSim MCP Server (opensim-console2mcp)

This project uses the published Docker image bithatch/opensim-console2mcp:latest.

The MCP server uses these environment variables:

  • MCP_TRANSPORT (http, sse, or stdio)
  • MCP_HOST
  • MCP_PORT
  • OPENSIM_CONSOLE_URL
  • OPENSIM_CONSOLE_USER
  • OPENSIM_CONSOLE_PASS

These should match the REST console credentials already configured in this project (OPENSIM_CONSOLE_USER / OPENSIM_CONSOLE_PASS).

Compose fragment to add the MCP sidecar service (source/release/osgrid stacks):

  opensim-console2mcp:
    image: "${OPENSIM_CONSOLE2MCP_IMAGE:-bithatch/opensim-console2mcp:latest}"
    pull_policy: always
    restart: unless-stopped
    environment:
      MCP_TRANSPORT: "${MCP_TRANSPORT:-http}"
      MCP_HOST: "${MCP_HOST:-0.0.0.0}"
      MCP_PORT: "${MCP_PORT:-9001}"
      OPENSIM_CONSOLE_URL: "${OPENSIM_CONSOLE_URL:-http://opensim:9000}"
      OPENSIM_CONSOLE_USER: "${OPENSIM_CONSOLE_USER:-ConsoleUser}"
      OPENSIM_CONSOLE_PASS: "${OPENSIM_CONSOLE_PASS:-ConsolePass}"
    ports:
      - "${MCP_PORT:-9001}:9001/tcp"
    depends_on:
      opensim:
        condition: service_started

Notes:

  • http://opensim:9000 uses the internal Docker network service name.
  • If your simulator HTTP listener is not 9000 internally, adjust OPENSIM_CONSOLE_URL.
  • This image defaults to HTTP transport for remote MCP access in stack deployments.
  • To run classic subprocess mode instead, set MCP_TRANSPORT=stdio and remove port mapping.

Publish Images To Docker Hub (bithatch)

These commands publish all runtime variants to the Docker Hub namespace bithatch.

1) Login

docker login

2) Set optional tag suffix

export TAG_DATE=$(date +%Y%m%d)

3) Build and push source-runtime image

docker build \
  --target source-runtime \
  --build-arg OPENSIM_GIT_URL=git://opensimulator.org/git/opensim \
  --build-arg OPENSIM_GIT_REF=master \
  -t bithatch/opensim-standalone:source-latest \
  -t bithatch/opensim-standalone:source-${TAG_DATE} \
  .

docker push bithatch/opensim-standalone:source-latest
docker push bithatch/opensim-standalone:source-${TAG_DATE}

4) Build and push official-release runtime image

docker build \
  --target release-runtime \
  --build-arg OPENSIM_RELEASE_URL=http://opensimulator.org/dist/opensim-0.9.3.0.tar.gz \
  -t bithatch/opensim-standalone:release-latest \
  -t bithatch/opensim-standalone:release-${TAG_DATE} \
  .

docker push bithatch/opensim-standalone:release-latest
docker push bithatch/opensim-standalone:release-${TAG_DATE}

5) Build and push OSGrid runtime image

docker build \
  --target osgrid-runtime \
  --build-arg OSGRID_RELEASE_URL=https://download.osgrid.org/osgrid-opensim-04172026.v0.9.3.ef8a36b.zip \
  -t bithatch/opensim-osgrid:latest \
  -t bithatch/opensim-osgrid:${TAG_DATE} \
  .

docker push bithatch/opensim-osgrid:latest
docker push bithatch/opensim-osgrid:${TAG_DATE}

6) Publish OpenSim MCP bridge image reference

docker pull bithatch/opensim-console2mcp:latest
docker tag bithatch/opensim-console2mcp:latest bithatch/opensim-console2mcp:${TAG_DATE}
docker push bithatch/opensim-console2mcp:latest
docker push bithatch/opensim-console2mcp:${TAG_DATE}

7) Use published images in Compose (pull-only hosts)

For Docker hosts that import compose stacks and should not build images, use one of the following optimized compose files as-is.

Source mode (pulls prebuilt source-runtime image):

services:
  mariadb:
    image: mariadb:11
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD:-${MYSQL_ROOT_PASSWORD:-rootpassword}}"
      MARIADB_DATABASE: "${MARIADB_DATABASE:-${MYSQL_DATABASE:-opensim}}"
      MARIADB_USER: "${MARIADB_USER:-${MYSQL_USER:-opensim}}"
      MARIADB_PASSWORD: "${MARIADB_PASSWORD:-${MYSQL_PASSWORD:-opensimpassword}}"
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
    volumes:
      - opensim-mariadb:/var/lib/mysql
    healthcheck:
      test: ["CMD-SHELL", "mariadb-admin ping -h localhost -u root --password=\"$$MARIADB_ROOT_PASSWORD\" --silent"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 30s

  opensim-init:
    image: bithatch/opensim-standalone:source-latest
    pull_policy: always
    entrypoint: ["/opt/opensim/docker/init-standalone.sh"]
    restart: "no"
    environment:
      OPENSIM_HOSTNAME: "${OPENSIM_HOSTNAME:-127.0.0.1}"
      OPENSIM_REGION_NAME: "${OPENSIM_REGION_NAME:-Welcome Island}"
      OPENSIM_REGION_X: "${OPENSIM_REGION_X:-1000}"
      OPENSIM_REGION_Y: "${OPENSIM_REGION_Y:-1000}"
      OPENSIM_REGION_PORT: "${OPENSIM_REGION_PORT:-9000}"
      OPENSIM_ESTATE_NAME: "${OPENSIM_ESTATE_NAME:-My Estate}"
      OPENSIM_ESTATE_OWNER_FIRST: "${OPENSIM_ESTATE_OWNER_FIRST:-Admin}"
      OPENSIM_ESTATE_OWNER_LAST: "${OPENSIM_ESTATE_OWNER_LAST:-User}"
      OPENSIM_ESTATE_OWNER_PASSWORD: "${OPENSIM_ESTATE_OWNER_PASSWORD:-changeme}"
      OPENSIM_ESTATE_OWNER_EMAIL: "${OPENSIM_ESTATE_OWNER_EMAIL:-admin@example.com}"
      OPENSIM_ESTATE_OWNER_UUID: "${OPENSIM_ESTATE_OWNER_UUID:-00000000-0000-0000-0000-000000000000}"
      OPENSIM_GRID_NAME: "${OPENSIM_GRID_NAME:-My OpenSim Grid}"
      OPENSIM_GRID_NICK: "${OPENSIM_GRID_NICK:-opensimgrid}"
      OPENSIM_WELCOME_MESSAGE: "${OPENSIM_WELCOME_MESSAGE:-Welcome to My OpenSim Grid!}"
      OPENSIM_CONSOLE_MODE: "${OPENSIM_CONSOLE_MODE:-rest}"
      OPENSIM_CONSOLE_USER: "${OPENSIM_CONSOLE_USER:-ConsoleUser}"
      OPENSIM_CONSOLE_PASS: "${OPENSIM_CONSOLE_PASS:-ConsolePass}"
      MARIADB_HOST: "${MARIADB_HOST:-${MYSQL_HOST:-mariadb}}"
      MARIADB_DATABASE: "${MARIADB_DATABASE:-${MYSQL_DATABASE:-opensim}}"
      MARIADB_USER: "${MARIADB_USER:-${MYSQL_USER:-opensim}}"
      MARIADB_PASSWORD: "${MARIADB_PASSWORD:-${MYSQL_PASSWORD:-opensimpassword}}"
    volumes:
      - opensim-config:/config
    depends_on:
      mariadb:
        condition: service_healthy

  opensim:
    image: bithatch/opensim-standalone:source-latest
    pull_policy: always
    restart: unless-stopped
    environment:
      CONFIG_DIR: /config
    volumes:
      - opensim-config:/config
      - opensim-assetcache:/opt/opensim/bin/assetcache
      - opensim-maptiles:/opt/opensim/bin/maptiles
    ports:
      - "${OPENSIM_REGION_PORT:-9000}:9000/tcp"
      - "${OPENSIM_REGION_PORT:-9000}:9000/udp"
    depends_on:
      opensim-init:
        condition: service_completed_successfully

volumes:
  opensim-mariadb:
  opensim-config:
  opensim-assetcache:
  opensim-maptiles:

Release mode (pulls official-release runtime image):

services:
  mariadb:
    image: mariadb:11
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD:-${MYSQL_ROOT_PASSWORD:-rootpassword}}"
      MARIADB_DATABASE: "${MARIADB_DATABASE:-${MYSQL_DATABASE:-opensim}}"
      MARIADB_USER: "${MARIADB_USER:-${MYSQL_USER:-opensim}}"
      MARIADB_PASSWORD: "${MARIADB_PASSWORD:-${MYSQL_PASSWORD:-opensimpassword}}"
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
    volumes:
      - opensim-mariadb:/var/lib/mysql
    healthcheck:
      test: ["CMD-SHELL", "mariadb-admin ping -h localhost -u root --password=\"$$MARIADB_ROOT_PASSWORD\" --silent"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 30s

  opensim-init:
    image: bithatch/opensim-standalone:release-latest
    pull_policy: always
    entrypoint: ["/opt/opensim/docker/init-standalone.sh"]
    restart: "no"
    environment:
      OPENSIM_HOSTNAME: "${OPENSIM_HOSTNAME:-127.0.0.1}"
      OPENSIM_REGION_NAME: "${OPENSIM_REGION_NAME:-Welcome Island}"
      OPENSIM_REGION_X: "${OPENSIM_REGION_X:-1000}"
      OPENSIM_REGION_Y: "${OPENSIM_REGION_Y:-1000}"
      OPENSIM_REGION_PORT: "${OPENSIM_REGION_PORT:-9000}"
      OPENSIM_ESTATE_NAME: "${OPENSIM_ESTATE_NAME:-My Estate}"
      OPENSIM_ESTATE_OWNER_FIRST: "${OPENSIM_ESTATE_OWNER_FIRST:-Admin}"
      OPENSIM_ESTATE_OWNER_LAST: "${OPENSIM_ESTATE_OWNER_LAST:-User}"
      OPENSIM_ESTATE_OWNER_PASSWORD: "${OPENSIM_ESTATE_OWNER_PASSWORD:-changeme}"
      OPENSIM_ESTATE_OWNER_EMAIL: "${OPENSIM_ESTATE_OWNER_EMAIL:-admin@example.com}"
      OPENSIM_ESTATE_OWNER_UUID: "${OPENSIM_ESTATE_OWNER_UUID:-00000000-0000-0000-0000-000000000000}"
      OPENSIM_GRID_NAME: "${OPENSIM_GRID_NAME:-My OpenSim Grid}"
      OPENSIM_GRID_NICK: "${OPENSIM_GRID_NICK:-opensimgrid}"
      OPENSIM_WELCOME_MESSAGE: "${OPENSIM_WELCOME_MESSAGE:-Welcome to My OpenSim Grid!}"
      OPENSIM_CONSOLE_MODE: "${OPENSIM_CONSOLE_MODE:-rest}"
      OPENSIM_CONSOLE_USER: "${OPENSIM_CONSOLE_USER:-ConsoleUser}"
      OPENSIM_CONSOLE_PASS: "${OPENSIM_CONSOLE_PASS:-ConsolePass}"
      MARIADB_HOST: "${MARIADB_HOST:-${MYSQL_HOST:-mariadb}}"
      MARIADB_DATABASE: "${MARIADB_DATABASE:-${MYSQL_DATABASE:-opensim}}"
      MARIADB_USER: "${MARIADB_USER:-${MYSQL_USER:-opensim}}"
      MARIADB_PASSWORD: "${MARIADB_PASSWORD:-${MYSQL_PASSWORD:-opensimpassword}}"
    volumes:
      - opensim-config:/config
    depends_on:
      mariadb:
        condition: service_healthy

  opensim:
    image: bithatch/opensim-standalone:release-latest
    pull_policy: always
    restart: unless-stopped
    environment:
      CONFIG_DIR: /config
    volumes:
      - opensim-config:/config
      - opensim-assetcache:/opt/opensim/bin/assetcache
      - opensim-maptiles:/opt/opensim/bin/maptiles
    ports:
      - "${OPENSIM_REGION_PORT:-9000}:9000/tcp"
      - "${OPENSIM_REGION_PORT:-9000}:9000/udp"
    depends_on:
      opensim-init:
        condition: service_completed_successfully

volumes:
  opensim-mariadb:
  opensim-config:
  opensim-assetcache:
  opensim-maptiles:

OSGrid mode (pulls OSGrid runtime image):

services:
  mariadb:
    image: mariadb:11
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD:-${MYSQL_ROOT_PASSWORD:-rootpassword}}"
      MARIADB_DATABASE: "${MARIADB_DATABASE:-${MYSQL_DATABASE:-opensim}}"
      MARIADB_USER: "${MARIADB_USER:-${MYSQL_USER:-opensim}}"
      MARIADB_PASSWORD: "${MARIADB_PASSWORD:-${MYSQL_PASSWORD:-opensimpassword}}"
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
    volumes:
      - osgrid-mariadb:/var/lib/mysql
    healthcheck:
      test: ["CMD-SHELL", "mariadb-admin ping -h localhost -u root --password=\"$$MARIADB_ROOT_PASSWORD\" --silent"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 30s

  opensim-osgrid-init:
    image: bithatch/opensim-osgrid:latest
    pull_policy: always
    entrypoint: ["/opt/opensim/docker/init-osgrid.sh"]
    restart: "no"
    environment:
      OSGRID_REGION_NAME: "${OSGRID_REGION_NAME}"
      OSGRID_REGION_UUID: "${OSGRID_REGION_UUID}"
      OSGRID_REGION_LOCATION: "${OSGRID_REGION_LOCATION}"
      OSGRID_EXTERNAL_HOSTNAME: "${OSGRID_EXTERNAL_HOSTNAME}"
      OSGRID_INTERNAL_PORT: "${OSGRID_INTERNAL_PORT:-9000}"
      OPENSIM_ESTATE_NAME: "${OPENSIM_ESTATE_NAME:-My Estate}"
      OPENSIM_ESTATE_OWNER_FIRST: "${OPENSIM_ESTATE_OWNER_FIRST:-Admin}"
      OPENSIM_ESTATE_OWNER_LAST: "${OPENSIM_ESTATE_OWNER_LAST:-User}"
      OPENSIM_ESTATE_OWNER_PASSWORD: "${OPENSIM_ESTATE_OWNER_PASSWORD:-changeme}"
      OPENSIM_ESTATE_OWNER_EMAIL: "${OPENSIM_ESTATE_OWNER_EMAIL:-admin@example.com}"
      OPENSIM_ESTATE_OWNER_UUID: "${OPENSIM_ESTATE_OWNER_UUID:-00000000-0000-0000-0000-000000000000}"
      OPENSIM_GRID_NAME: "${OPENSIM_GRID_NAME:-OSGrid Region}"
      OPENSIM_GRID_NICK: "${OPENSIM_GRID_NICK:-osgrid}"
      OPENSIM_WELCOME_MESSAGE: "${OPENSIM_WELCOME_MESSAGE:-Welcome to OSGrid!}"
      OPENSIM_CONSOLE_MODE: "${OPENSIM_CONSOLE_MODE:-rest}"
      OPENSIM_CONSOLE_USER: "${OPENSIM_CONSOLE_USER:-ConsoleUser}"
      OPENSIM_CONSOLE_PASS: "${OPENSIM_CONSOLE_PASS:-ConsolePass}"
      MARIADB_HOST: "${MARIADB_HOST:-${MYSQL_HOST:-mariadb}}"
      MARIADB_DATABASE: "${MARIADB_DATABASE:-${MYSQL_DATABASE:-opensim}}"
      MARIADB_USER: "${MARIADB_USER:-${MYSQL_USER:-opensim}}"
      MARIADB_PASSWORD: "${MARIADB_PASSWORD:-${MYSQL_PASSWORD:-opensimpassword}}"
    volumes:
      - osgrid-config:/config
    depends_on:
      mariadb:
        condition: service_healthy

  opensim:
    image: bithatch/opensim-osgrid:latest
    pull_policy: always
    restart: unless-stopped
    environment:
      CONFIG_DIR: /config
    volumes:
      - osgrid-config:/config
      - osgrid-assetcache:/opt/opensim/bin/assetcache
      - osgrid-maptiles:/opt/opensim/bin/maptiles
    ports:
      - "${OSGRID_INTERNAL_PORT:-9000}:9000/tcp"
      - "${OSGRID_INTERNAL_PORT:-9000}:9000/udp"
    depends_on:
      opensim-osgrid-init:
        condition: service_completed_successfully

volumes:
  osgrid-mariadb:
  osgrid-config:
  osgrid-assetcache:
  osgrid-maptiles:

For all three blocks, deploy with:

docker compose pull
docker compose up -d

If you prefer immutable deployments, replace *-latest tags with pinned date/version tags.

Notes

  • The container starts OpenSim with -background=true to avoid interactive prompt loops.
  • DefaultEstateOwnerUUID is set from env so first-run estate owner creation does not block on prompt input.
  • Archive handling supports .zip, .tar.gz, .tgz URLs.

Reset

To wipe persistent data for the active compose stack:

docker compose down -v

For multi-file invocations, use the same -f ... arguments when calling down.

About

Builds docker images for snapshot or release versions of OpenSim and OSGrid and provides compositions for several configurations

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages