You need a valid FFXI client installation to connect to the server. LandSandBoat does not distribute game data.
The fastest path to a running server is Docker Compose. It handles the database, all four server processes, and database migrations automatically.
Clone the repository
git clone https://github.com/LandSandBoat/server.git
cd server
Load the mesh volumes
Navigation and line-of-sight meshes are distributed as a separate image. Run this once to populate the named volumes:docker run --rm \
-v losmeshes:/losmeshes \
-v navmeshes:/navmeshes \
ghcr.io/landsandboat/ximeshes:latest
You can remove the image after the volumes are created. Create your docker-compose.yml
Copy the example below into a file named docker-compose.yml in the repository root. Change the passwords before deploying anything public-facing.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:
- losmeshes:/server/losmeshes
- 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:
losmeshes:
external: true
navmeshes:
external: true
Start the server
Docker Compose will:
- Start a MariaDB container and wait for it to be healthy.
- Run
dbtool.py update to import all SQL and run migrations.
- Start
xi_connect, xi_search, xi_world, and xi_map.
Verify the server is running
Check that all services started cleanly:docker compose ps
docker compose logs database-update
Once database-update shows Finished importing! and all other services show running, the server is ready to accept connections.
Port reference
| Port | Protocol | Process | Purpose |
|---|
| 54001 | TCP | xi_connect | Login view |
| 54002 | TCP | xi_search | Search/auction |
| 54230 | TCP/UDP | xi_connect / xi_map | Login data / zone data |
| 54231 | TCP | xi_connect | Login auth |
| 8088 | TCP | xi_world | HTTP API (optional) |
Next steps
Requirements
Full system requirements for building from source.
Build from source
Compile the server binaries yourself.
Docker deployment
Full Docker and Docker Compose reference.
Database setup
Configure MariaDB and run initial migrations.