-
Notifications
You must be signed in to change notification settings - Fork 0
Installation wslc
Run FICSIT Foreman on Windows 11 using WSL Containers (wslc.exe) — the Linux
container runtime built into the Windows Subsystem for Linux — with no Docker Desktop.
Preview feature — but tested.
wslcshipped as a public preview in WSL 2.9.3 (June 2026). It has no Docker Compose, so the stack runs as three individual containers below. The primary path here was verified end-to-end on the preview — a bridge network with container-name DNS, Windows bind mounts, and a working browser → backend → MCP tool calls → LLM round-trip. Two preview gaps worth knowing (both covered below):wslcdoesn't run imageHEALTHCHECKs, and there's no restart-on-boot. If you just want the smoothest path, use Installation — Docker instead.
It runs the same ghcr.io/stuartmeeks/foreman-* images and ends up at the same place:
http://localhost:8725.
Shell note. The commands below use PowerShell line-continuation — a backtick (
`) at the end of each line. Incmd.exe, put each command on a single line (drop the backticks); everything else is identical.
Run these in PowerShell:
wsl --update # get a WSL version that includes wslc
wslc version # confirm the CLI is present
wslc run --rm hello-world # pulls + runs a tiny image to prove it worksThen probe the capabilities this guide depends on — wslc is evolving, so confirm
these before you start:
wslc --help
wslc network --help # is there a `network create`? (needed for name-based DNS)
wslc run --help # confirm -d -p -e -v --name --networkIf wslc network exists and wslc run accepts --network, use the primary path
below. If not, jump to Fallback: no user-defined network.
The Docker path uses docker compose up -d to start everything at once. wslc has no
Compose yet, so you start each service by hand. Two of them talk to each other by
container name — this is baked into the images, so the --name values below are
not optional:
-
ff-client's web server proxies/api/tohttp://ff-server:8724 -
ff-serverreaches the MCP server athttp://sf-mcp:8723/mcp
So the containers must share a network on which they can resolve each other by name,
and they must be named exactly sf-mcp and ff-server.
wslc's preview doesn't confirm Docker-style named volumes, but Windows bind
mounts are supported — and they keep your database and saves in a folder you control
(this also avoids container file-ownership quirks). Create two folders:
mkdir C:\foreman\data # SQLite DB, auth secret, sessions, work orders
mkdir C:\foreman\saves # uploaded playthrough .sav files (shared by two services)Anything under C:\foreman is fine — just use the same paths consistently below.
wslc network create foreman-netThis gives the containers automatic name-based DNS (so ff-server can find sf-mcp,
and ff-client can find ff-server). wslc network list should now show it on the
bridge driver:
NETWORK ID NAME DRIVER
609305e105ca foreman-net bridge
wslc run -d --name sf-mcp --network foreman-net `
-p 8723:8723 `
-v C:\foreman\saves:/data/saves `
-e SAVE_DATA_DIR=/data/saves `
ghcr.io/stuartmeeks/foreman-sf-mcp:latestPublishing -p 8723:8723 is optional (handy for hitting /health from Windows); the
other services reach it over foreman-net, not via the published port. Confirm it's
serving:
curl http://localhost:8723/health{"status":"ok","version":"1.2.3.1","build":495413,"saveName":"none"}wslc run -d --name ff-server --network foreman-net `
-p 8724:8724 `
-v C:\foreman\data:/data `
-v C:\foreman\saves:/data/saves `
-e MCP_URL=http://sf-mcp:8723/mcp `
-e SAVE_DATA_DIR=/data/saves `
-e DATABASE_URL=file:/data/foreman.db `
-e ANTHROPIC_API_KEY=sk-ant-... `
ghcr.io/stuartmeeks/foreman-ff-server:latest-
ANTHROPIC_API_KEYis optional — leave it out to have each browser client supply its own key. To run on an OpenAI-compatible provider instead, passLLM_PROVIDER/LLM_API_KEY/LLM_MODEL/LLM_BASE_URL(see Configuration). -
MCP_URLandDATABASE_URLshown here match the image defaults; they're listed so the command is self-explanatory. - On first start it runs its database migrations, then boots.
Check the logs — one line proves the cross-container connection worked:
wslc container logs ff-serverAll migrations have been successfully applied.
[foreman-ff-server] Loaded system prompt from /app/SYSTEM_PROMPT.md
[foreman-ff-server] Connected to MCP server at http://sf-mcp:8723/mcp (game version 1.2.3.1)
[foreman-ff-server] Listening on http://0.0.0.0:8724 (health: /health)
Connected to MCP server at http://sf-mcp:8723/mcp means ff-server resolved sf-mcp
by name over foreman-net — the whole reason the shared network matters. A
first-boot warning that BETTER_AUTH_SECRET was auto-generated (and persisted under
/data) is normal; set it explicitly only for multi-instance setups.
wslc run -d --name ff-client --network foreman-net `
-p 8725:80 `
ghcr.io/stuartmeeks/foreman-ff-client:latestBrowse to http://localhost:8725.
wslc container list # all three should be running
wslc container logs ff-server # look for DB migrations + a successful MCP connect
wslc container logs sf-mcp
wslc container logs ff-clientAll three should be listed as running:
CONTAINER ID NAME IMAGE STATUS PORTS
6b779f558e99 ff-client ghcr.io/stuartmeeks… running 2 minutes ago 127.0.0.1:8725->80/tcp
19392c6fa7b6 ff-server ghcr.io/stuartmeeks… running 4 minutes ago 127.0.0.1:8724->8724/tcp
e64a418d2e55 sf-mcp ghcr.io/stuartmeeks… running 8 minutes ago 127.0.0.1:8723->8723/tcp
No health column. This
wslcpreview doesn't run imageHEALTHCHECKs, so the STATUS above only ever showsrunning(never(healthy)), andwslc container inspecthas noHealthblock. Check health yourself by hitting the endpoints —curl http://localhost:8723/healthandcurl http://localhost:8724/healthboth return{"status":"ok",...}when up.
Everyday control:
wslc container stop ff-client ff-server sf-mcp
wslc container start sf-mcp ff-server ff-client # start mcp first
wslc container rm ff-client ff-server sf-mcp # remove (your C:\foreman data stays)Auto-start on boot: Docker Compose's
restart: unless-stoppedhas no confirmedwslcequivalent in the preview, so the containers won't come back by themselves after a reboot. Re-run the start commands (or the script below), or wire the script into Windows Task Scheduler at logon.
To update to newer images later:
wslc container stop ff-client ff-server sf-mcp
wslc container rm ff-client ff-server sf-mcp
wslc image pull ghcr.io/stuartmeeks/foreman-sf-mcp:latest
wslc image pull ghcr.io/stuartmeeks/foreman-ff-server:latest
wslc image pull ghcr.io/stuartmeeks/foreman-ff-client:latest
# then re-run steps 3–5. Your C:\foreman data (DB + saves) is preserved.Save as start-foreman-wslc.ps1 and run it in PowerShell (e.g.
./start-foreman-wslc.ps1 -AnthropicApiKey sk-ant-...). It's just the commands above,
made idempotent.
param(
[string]$DataRoot = "C:\foreman",
[string]$AnthropicApiKey = "",
[string]$Network = "foreman-net"
)
$ErrorActionPreference = "Stop"
New-Item -ItemType Directory -Force -Path "$DataRoot\data", "$DataRoot\saves" | Out-Null
# Create the network if it doesn't already exist (ignore the error if it does).
wslc network create $Network 2>$null
# Remove any previous containers so this is re-runnable.
wslc container rm -f ff-client ff-server sf-mcp 2>$null
wslc run -d --name sf-mcp --network $Network `
-p 8723:8723 `
-v "$DataRoot\saves:/data/saves" `
-e SAVE_DATA_DIR=/data/saves `
ghcr.io/stuartmeeks/foreman-sf-mcp:latest
$serverArgs = @(
"run","-d","--name","ff-server","--network",$Network,
"-p","8724:8724",
"-v","$DataRoot\data:/data",
"-v","$DataRoot\saves:/data/saves",
"-e","MCP_URL=http://sf-mcp:8723/mcp",
"-e","SAVE_DATA_DIR=/data/saves",
"-e","DATABASE_URL=file:/data/foreman.db"
)
if ($AnthropicApiKey) { $serverArgs += @("-e","ANTHROPIC_API_KEY=$AnthropicApiKey") }
$serverArgs += "ghcr.io/stuartmeeks/foreman-ff-server:latest"
wslc @serverArgs
wslc run -d --name ff-client --network $Network `
-p 8725:80 `
ghcr.io/stuartmeeks/foreman-ff-client:latest
Write-Host "FICSIT Foreman is starting — open http://localhost:8725"To stop everything: wslc container stop ff-client ff-server sf-mcp.
If your wslc build has no network create / --network, the two name-based hops
(ff-server → sf-mcp, and ff-client → ff-server) can't resolve. Route them
through the Windows host instead — this only works if your wslc exposes a
host-gateway address reachable from inside a container (commonly
host.docker.internal; confirm with wslc run --help / the release notes).
-
Publish both backend ports (
-p 8723:8723onsf-mcp,-p 8724:8724onff-server) so they're reachable on the host. -
Point the backend at the MCP server via the host gateway:
-e MCP_URL=http://host.docker.internal:8723/mcp(drop--network foreman-net). -
The client's
/api/proxy target (ff-server:8724) is baked into its image, so override it with your own nginx config mounted over the default. Save this asC:\foreman\default.conf:server { listen 80; root /usr/share/nginx/html; index index.html; location /api/ { proxy_pass http://host.docker.internal:8724; } location / { try_files $uri $uri/ /index.html; } }
then run the client with it mounted:
wslc run -d --name ff-client ` -p 8725:80 ` -v C:\foreman\default.conf:/etc/nginx/conf.d/default.conf:ro ` ghcr.io/stuartmeeks/foreman-ff-client:latest
If neither a user-defined network nor a host gateway is available in your preview
build, use Installation — Docker until wslc networking
matures.
- Configuration — environment variables
- Game data channels — stable vs experimental
- Troubleshooting
FICSIT Foreman
- Home
- Installation
- API keys
- Configuration
- Game data channels
- Troubleshooting
- MCP clients