| .. | ||
| alpine.Dockerfile | ||
| entrypoint.sh | ||
| meshes.Dockerfile | ||
| README.md | ||
| ubuntu.Dockerfile | ||
Docker
Meshes
navmeshes are included in a separate image. You can load these into a volume with the following command:
docker run --rm -v navmeshes:/navmeshes ghcr.io/landsandboat/ximeshes:latest
Once the volumes are created, you can delete the image.
Database
A DATABASE IS NOT INCLUDED WITH THIS IMAGE! Database connection credentials are required to run the executables, you can set these through environment variables:
XI_NETWORK_SQL_HOST
XI_NETWORK_SQL_PORT
XI_NETWORK_SQL_DATABASE or MARIADB_DATABASE
XI_NETWORK_SQL_LOGIN or MARIADB_USER
XI_NETWORK_SQL_PASSWORD or MARIADB_PASSWORD
Running the container
Default user
The image is built with a default user and group named xiadmin with UID and GID 1000.
Configuration
Database migrations
You should run a dbtool update inside the container before starting the executables.
To increase the efficiency and avoid a full import every time the container is recreated, you should create and mount config.yaml to /server/tools/config.yaml.
Port binding
The server executables running within the container will listen on ports 54001, 54002, 54230, and 54231 (and 8088 if you enable the HTTP API).
Starting using a minimal configuration
docker run --name some-lsb-server \
-p 54001:54001 \
-p 54002:54002 \
-p 54230:54230 \
-p 54231:54231 \
-v navmeshes:/server/navmeshes \
-it ghcr.io/landsandboat/server:latest
There is no database in this configuration. You can install MariaDB Server through apt inside the container or connect to an external database using some additional args such as:
--network server_default \
-e XI_NETWORK_SQL_HOST=database \
-e XI_NETWORK_SQL_PORT=3306 \
-e XI_NETWORK_SQL_DATABASE=xidb \
-e XI_NETWORK_SQL_LOGIN=xiadmin \
-e XI_NETWORK_SQL_PASSWORD='password' \
Customization
Environment variables
You can use environment variables to adjust individual settings in the following format:
-e XI_{file}_{setting}=value
Settings files
Mount settings for more extensive changes.
--mount type=bind,src="$(pwd)"/settings/map.lua,dst=/server/settings/map.lua
Modules
Mount Lua and SQL runtime modules for further customization.
--mount type=bind,src="$(pwd)"/modules,dst=/server/modules
- You must build the image to use C++ modules.
...via Docker Compose
Example docker-compose.yml:
x-dbcreds: &dbcreds
# MARIADB_ROOT_PASSWORD required if setting up fresh database.
# Or generate a random root password and print it to build log:
# MARIADB_RANDOM_ROOT_PASSWORD: true
MARIADB_ROOT_PASSWORD: 'root'
MARIADB_DATABASE: xidb
MARIADB_USER: xiadmin
MARIADB_PASSWORD: 'password'
x-common: &common
image: ghcr.io/landsandboat/server:latest
environment:
<<: *dbcreds
XI_NETWORK_HTTP_HOST: 0.0.0.0
XI_NETWORK_ZMQ_IP: world
XI_NETWORK_SQL_HOST: database
# XI_{file}_{setting}: value
volumes:
- navmeshes:/server/navmeshes
# - ./config.yaml:/server/tools/config.yaml
# - ./map.lua:/server/settings/map.lua
# - ./modules:/server/modules
services:
database:
image: mariadb:lts
restart: always
command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_general_ci']
environment:
<<: *dbcreds
volumes:
- database:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
database-update:
<<: *common
command: ["python", "/server/tools/dbtool.py", "update"]
depends_on:
database:
condition: service_healthy
connect:
<<: *common
command: ["/server/xi_connect"]
restart: unless-stopped
ports:
- "54001:54001"
- "54230:54230"
- "54231:54231"
depends_on:
database:
condition: service_healthy
restart: true
database-update:
condition: service_completed_successfully
search:
<<: *common
command: ["/server/xi_search"]
restart: unless-stopped
ports:
- "54002:54002"
depends_on:
database:
condition: service_healthy
restart: true
database-update:
condition: service_completed_successfully
world:
<<: *common
command: ["/server/xi_world"]
restart: unless-stopped
ports:
- "8088:8088"
depends_on:
database:
condition: service_healthy
restart: true
database-update:
condition: service_completed_successfully
map:
<<: *common
command: ["/server/xi_map"]
restart: unless-stopped
ports:
- "54230:54230/udp"
depends_on:
database:
condition: service_healthy
restart: true
database-update:
condition: service_completed_successfully
world:
condition: service_started
volumes:
database:
navmeshes:
external: true
Building the image
docker build -f docker/ubuntu.Dockerfile .
The Dockerfiles support a few build args, use these if you want to use a different compiler/version/user/etc:
BASE_TAG=24.04
UNAME=xiadmin
UGROUP=xiadmin
UID=1000
GID=1000
COMPILER=gcc
GCC_VERSION=14
LLVM_VERSION=20
CMAKE_BUILD_TYPE=Release
TRACY_ENABLE=OFF
ENABLE_CLANG_TIDY=OFF
PCH_ENABLE=ON
WARNINGS_AS_ERRORS=TRUE
REPO_URL="https://github.com/USERNAME/server"
COMMIT_SHA="$(git rev-parse HEAD)"
REPO_URL and COMMIT_SHA are required for dbtool unless you mount the host .git directory at runtime.
Be mindful of the license requirements if you publish your image, as not all source files are included in the final image. Providing the REPO_URL and COMMIT_SHA will add labels that link to your published source when viewed with docker inspect.
docker build -f docker/ubuntu.Dockerfile \
--tag USERNAME/server:latest \
--build-arg REPO_URL="https://github.com/USERNAME/server" \
--build-arg COMMIT_SHA="$(git rev-parse HEAD)" \
.
Devtools
The devtools image contains build and CI tools, but no built executables or server source files. This can be useful for testing or as the base for experimental containers.
Local CI/Testing
The dev.docker-compose.yml file contains a template for running the CI tests locally. This file should be copied into an untracked file if edits are needed. Don't forget to run the build (or clang_tidy) and setup_database services before running the test or startup_checks services if they need to be created/updated.
By default there is no database volume, so the database used is ephemeral and is tied to the database service container.
Alpine
Alpine based images are available for both the server and devtools. These are significantly smaller and should work well in most situations, but be aware that they use some different libraries and dependency versions and should be considered experimental.