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.
- Source mode: clone OpenSimulator from git and build inside Docker.
- Release mode: download official OpenSimulator binary release archive.
- OSGrid mode: download OSGrid-ready package and generate Regions.ini from minimum required values.
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.
- 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
- Docker Engine
- Docker Compose v2 (
docker compose)
cp .env.example .envThe 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.
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 --buildOr use:
./run-source.shThis mode runs standalone OpenSimulator with MariaDB.
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 --buildOr use:
./run-release.shThis 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 --buildOr use:
./run-osgrid.shThe generated Regions/Region.ini contains:
- Region Name (
OSGRID_REGION_NAME) - RegionUUID (
OSGRID_REGION_UUID) - Location (
OSGRID_REGION_LOCATION) - ExternalHostName (
OSGRID_EXTERNAL_HOSTNAME)
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_*.
This project enables the OpenSimulator REST console by default via:
OPENSIM_CONSOLE_MODE=restOPENSIM_CONSOLE_USEROPENSIM_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 -dThis project uses the published Docker image
bithatch/opensim-console2mcp:latest.
The MCP server uses these environment variables:
MCP_TRANSPORT(http,sse, orstdio)MCP_HOSTMCP_PORTOPENSIM_CONSOLE_URLOPENSIM_CONSOLE_USEROPENSIM_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_startedNotes:
http://opensim:9000uses 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=stdioand remove port mapping.
These commands publish all runtime variants to the Docker Hub namespace
bithatch.
docker loginexport TAG_DATE=$(date +%Y%m%d)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}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}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}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}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 -dIf you prefer immutable deployments, replace *-latest tags with pinned
date/version tags.
- The container starts OpenSim with
-background=trueto avoid interactive prompt loops. DefaultEstateOwnerUUIDis set from env so first-run estate owner creation does not block on prompt input.- Archive handling supports
.zip,.tar.gz,.tgzURLs.
To wipe persistent data for the active compose stack:
docker compose down -vFor multi-file invocations, use the same -f ... arguments when calling down.