Docker hosting
The published StoryForce image runs a dedicated server on a NAS or a VPS without you building anything.
The image does not contain
storyforce.pk3. You have to supply that file yourself. Without it the server runs with no models, no shaders, no sound, no interface files and no NPC definitions.
What it does
The image bundles an OpenJK dedicated server, the StoryForce game module and a copy of the shipped config file. It expects 2 folders from the host. One holds the base-game assets and is mounted read only. The other is writable and holds everything the server creates.
What the image leaves out is the asset pack and the llm/ folder. Both are built by the release
packer, which never runs in the container build. Steps 4 and 5 of the setup put them in place.
Setting it up
- Make a folder on the host for the server, with
baseandhomepathfolders inside it. - Copy
assets0.pk3,assets1.pk3,assets2.pk3andassets3.pk3from a copy of Jedi Academy intobase/. - Make a
StoryForcefolder insidehomepath. - Download StoryForce - Server from the StoryForce releases, open the zip, and copy
storyforce.pk3intohomepath/StoryForce/. Skip this and players connect to a server with no art, no interface and no NPCs. - Copy the
llm/folder from the same zip intohomepath/StoryForce/if you intend to use AI NPCs. The image does not carry that folder either. - Save the compose file at the end of these steps, changing the 2 host paths on the left of each colon to match step 1.
- Forward external UDP port 29070 to the host on your router or firewall.
- Run
docker compose up -d.
services:
storyforce:
image: ghcr.io/wheezypipes/storyforce:latest
restart: unless-stopped
ports:
- "29070:29070/udp"
volumes:
# Read-only: Jedi Academy base game assets
- /volume1/StoryForce/base:/opt/openjk/cdpath/base:ro
# Persistent: database, logs, config overrides and the mod pk3
- /volume1/StoryForce/homepath:/opt/openjk/homepath
The database is created inside homepath/StoryForce/db/ on the first run, along with the log folder,
the ban list and the scenes folder. Nothing outside those 2 mounts survives a redeploy.
Where the config and secrets go
The image already carries storyforce_server.cfg, and the container starts with
+exec storyforce_server.cfg already on its command line. Homepath sits above the image's own copy in
the file search order. A storyforce_server.cfg you place in homepath/StoryForce/ therefore shadows
the baked-in one and is the file that actually runs.
That homepath copy is also where your 3 credentials belong: rconpassword, sf_d1token and
sf_llmnpc_token. Homepath is a host folder you control, and the image is public. What each
one does, and why the 2 tokens must be set on every boot, is covered under
server configuration.
Start from the copy of storyforce_server.cfg in the server zip rather than writing one from nothing.
It carries the permission values the compiled defaults are missing.
Updating
- Pull the new image with
docker compose pull. - Recreate the container with
docker compose up -d.
Your database, config file and asset pack all live in homepath, so they survive the swap. Check
whether the release also shipped a new storyforce.pk3. If it did, copy that over too, because the
image will not do it for you.
Things to note
- The image ships no asset pack. This is the most common failure, and it looks like a broken game
rather than a missing file. Copy
storyforce.pk3intohomepath/StoryForce/. - The image ships no
llm/folder. AI NPCs read their base prompt and write their persona files there. See LLM NPC setup. - Set an rcon password or shutdown is not clean. Stopping the container sends a quit over rcon,
and that lookup reads
rconpasswordout of your config file. With no password set, nothing is sent and the container is killed instead. - The port is UDP. Forwarding TCP 29070 does nothing at all.
baseis mounted read only on purpose. Everything the server writes has to land in homepath.- The server comes up on
mp/ffa3. The shipped config ends with that map. - An unhealthy container usually means the game module failed. The healthcheck queries the running server every 10 seconds and only fails when nothing answers, so a network fault is rarely the cause.
- The database and its backups are sensitive. They sit in
homepath/StoryForce/db/, on the host. The database explains what they hold and why.
Next
- Server configuration: the settings in the file your homepath copy shadows, and where the credentials go
- Backups and D1 sync: protecting the database that now lives in your homepath mount