Menu
 

Palworld Server Docker: Tested Compose File and Real RAM Numbers

Palworld Dedicated Server in Docker: a Tested Compose File and Which Image to Use

To run a Palworld dedicated server in Docker, save the compose file below as compose.yaml in an empty folder, change the two passwords and the server name, and run docker compose up -d. The first start downloads the 4.9 GB game server and took 12 minutes 54 seconds to ready in our test; the second start took 9.3 seconds. The file uses the community image thijsvanloef/palworld-server-docker; Pocketpair's official image is compared with it right after the file.

services:
  palworld:
    image: thijsvanloef/palworld-server-docker:v2.8.0
    container_name: palworld-server
    restart: unless-stopped
    stop_grace_period: 90s
    mem_limit: 12g
    ports:
      - "8211:8211/udp"
      - "27015:27015/udp"
      - "127.0.0.1:8212:8212/tcp"
      - "127.0.0.1:25575:25575/tcp"
    environment:
      PUID: 1000
      PGID: 1000
      TZ: "UTC"
      PORT: 8211
      PLAYERS: 16
      SERVER_NAME: "My Palworld Server"
      SERVER_DESCRIPTION: "Docker test world"
      SERVER_PASSWORD: "change-me-join"
      ADMIN_PASSWORD: "change-me-admin"
      COMMUNITY: false
      CROSSPLAY_PLATFORMS: "(Steam,Xbox,PS5,Mac)"
      REST_API_ENABLED: true
      REST_API_PORT: 8212
      RCON_ENABLED: true
      RCON_PORT: 25575
      UPDATE_ON_BOOT: true
      BACKUP_ENABLED: true
      BACKUP_CRON_EXPRESSION: "0 */6 * * *"
      DELETE_OLD_BACKUPS: true
      OLD_BACKUP_DAYS: 7
      EXP_RATE: "1.5"
      DEATH_PENALTY: "Item"
    volumes:
      - ./palworld:/palworld/

How this file was tested. We booted it on 4 October 2026 with Palworld v1.0.5 (the server reported v1.0.5.102999) and image tag v2.8.0, on a Linux workstation with about 45 GB of free RAM, using a Docker-compatible container engine and Docker Compose v2.5.0. For the test every port was bound to 127.0.0.1 on different host port numbers and the container had a different name; nothing else differed. Because the ports were loopback only, we did not test joining from another machine or appearing in the community list. Every number on this page comes from that run unless the sentence says it comes from the image documentation.

Official image or community image

Pocketpair publishes an official image, ghcr.io/pocketpairjp/palserver, with an example compose file in its pocketpairjp/palworld-dedicated-server-docker repository (201 stars, last push 15 September 2026). Both images run the native Linux server, and the build our test server reported, v1.0.5.102999, is the official image's current tag. Where they differ, according to each project's own README and documentation on 4 October 2026:

What you getOfficial: ghcr.io/pocketpairjp/palserverCommunity: thijsvanloef/palworld-server-docker
Game serverInside the image, one tag per game build (a 5.2 GB pull)Downloaded by steamcmd on first start, checked for updates on every start
Server settingsYou edit Saved/Config/LinuxServer/PalWorldSettings.ini; the defaults are in the image at /pal/Package/DefaultPalWorldSettings.iniEnvironment variables, written into PalWorldSettings.ini on every start
Game updatesBack up, docker compose down, change the tag to the new game version, docker compose up -dOn start, or on a schedule that warns players first
Backups and restartsNo built-in feature; the README says to back up before every updatebackup and restore commands, scheduled backups, scheduled restarts
Admin helpersNone in the image; the server's own REST API and RCON are switched on in the ini filerest-cli and rcon-cli, Discord webhook messages, pausing the server while nobody is online
CPUx64 onlyx64 and ARM64
Example compose filePublishes 8211/udp, mounts ./Saved and runs a small helper.sh that fixes the folder's ownership; no restart policy and no stop grace period, so Docker's 10 second default appliesRestart policy and a 30 second stop grace period

Pick the official image if you run an x64 host, want Pocketpair's own package with nothing added, and are happy to edit the ini file and write your own backup job; its README calls the compose file a sample and asks you to verify that saves are written before you rely on it. Pick the community image if you want settings in the compose file, built-in backups, scheduled updates and restarts, or ARM64; it is also the image every command on this page was tested with. Pocketpair also advises against running its image under Docker Desktop on Windows or macOS: disk access there is slow, which its server guide says raises the risk of corrupted saves.

Among community images, thijsvanloef/palworld-server-docker has the most adoption: 3,210 GitHub stars and 1,876,452 Docker Hub pulls on 4 October 2026, against 1,010 and 433,792 for the next one, which has no tagged GitHub releases and last pushed a commit on 1 August 2026. It released 2.7.2 on 15 August, 2.7.3 on 25 August and 2.8.0 on 30 September 2026, with at least 100 commits in the last three months. Its documentation is at the palworld-server-docker documentation site, and every variable on this page was checked against it on the day of the test.

The compose file, line by line

  • image: the community image, pinned to a release tag so the image only changes when you edit this line. The game itself updates on start (UPDATE_ON_BOOT below).
  • container_name: the name you type in every docker exec and docker logs command below.
  • restart: unless-stopped: brings the server back after a crash or a host reboot, and the image documentation requires it for the scheduled update and restore features.
  • stop_grace_period: 90s: how long Docker waits for the save and shutdown before it kills the process. Our stop took 7.1 seconds and the image's own example allows 30. The extra margin costs nothing, because Docker stops waiting as soon as the server exits.
  • mem_limit: 12g: a hard memory ceiling. Without it a leaking or overloaded server can push the whole host into swap. Choose the number with the RAM section below.
  • 8211/udp: the game port players connect to. This is the one to forward on your router.
  • 27015/udp: the Steam query port, needed only if you want the server in the in-game community list.
  • 127.0.0.1:8212/tcp: the REST API, bound to the host's loopback so only the machine itself can reach it. The image documentation says plainly not to port forward it.
  • 127.0.0.1:25575/tcp: RCON, also loopback only. You will use it through docker exec, not from the internet.
  • PUID / PGID: the user and group the server runs as inside the container, so the files in ./palworld belong to your normal user. Use the numbers id prints for you; 1000 is the usual first user on Linux.
  • TZ: the timezone used for backup file names and the backup schedule.
  • PORT / PLAYERS: the game port and the player cap, the two settings the image docs mark as highly recommended.
  • SERVER_NAME / SERVER_DESCRIPTION: what players see in the server list.
  • SERVER_PASSWORD: the join password. Keep one if you ever set COMMUNITY to true.
  • ADMIN_PASSWORD: the password for in-game admin, RCON and the REST API.
  • COMMUNITY: false keeps the server out of the public community list; you join by IP.
  • CROSSPLAY_PLATFORMS: which client platforms may connect. See our crossplay guide.
  • REST_API_ENABLED / REST_API_PORT: turns on the HTTP admin API. The image's graceful stop, backup and update scripts call this API, so leave it on.
  • RCON_ENABLED / RCON_PORT: turns on the classic RCON console; the image's variable table lists it as off by default, so set it explicitly.
  • UPDATE_ON_BOOT: checks Steam for a newer game build on every container start and installs it.
  • BACKUP_ENABLED / BACKUP_CRON_EXPRESSION: an automatic save archive every six hours instead of the default once a night.
  • DELETE_OLD_BACKUPS / OLD_BACKUP_DAYS: prunes archives older than a week so the disk does not fill.
  • EXP_RATE / DEATH_PENALTY: two gameplay examples showing how any line of PalWorldSettings.ini becomes an environment variable.
  • volumes: everything (game files, world, config, backups) lives in ./palworld next to the compose file, so it survives container rebuilds and image updates.

First boot: what happens

StepMeasured
Image pull (v2.8.0)918 MB, 11 seconds
Game server download by steamcmd (app 2394010)4,932,070,576 bytes
docker compose up to "Success! App '2394010' fully installed."12 minutes 46 seconds
Server start to ready line7 seconds
Total first boot, up to ready12 minutes 54 seconds
Disk used by ./palworld afterwards4.7 GB
Second boot (game already installed)9.3 seconds to ready

Most of that time is the download, so it depends on your connection. These are the lines from the end of our first boot:

Success! App '2394010' fully installed.
****GENERATING CONFIG****
Using Env vars to create PalWorldSettings.ini
****Compiling PalWorldSettings.ini****
Compiling PalWorldSettings.ini done!
****GENERATING CRONTAB****
BACKUP_ENABLED=true
Adding cronjob for auto backups
Cronjobs started
****Starting Server****
/palworld/PalServer.sh -port=8211 -queryport=27015
Setting breakpad minidump AppID = 2394010
[S_API FAIL] Tried to access Steam interface SteamUser021 before SteamAPI_Init succeeded.
Game version is v1.0.5.102999
REST API started on port 8212
Running Palworld dedicated server on :8211
REST API(8212) port is open, player logging started

The line that means ready is Running Palworld dedicated server on :8211. The image documentation treats the earlier Setting breakpad minidump AppID = 2394010 as proof the server process is alive, which is true, but the admin API is not answering yet at that point. Wait for the "Running" line before you run commands. The [S_API FAIL] lines are harmless noise; we explain them in S_API FAIL and steamclient errors.

Follow the boot with docker logs -f palworld-server. One oddity we saw: the container printed "New version available: 2.8.0 Mod Support" even though it was already running the 2.8.0 tag. Compare the tag in your compose file with the release list before acting on that message.

RAM: the part that kills most home setups

What our test world used, against what the image documentation and Pocketpair ask for:

SourceFigure
Measured: container memory right after ready, empty fresh worldabout 860 MB
Measured: same, sampled every 30 seconds for 6 minutes859.8 MB to 860.7 MB, flat
Measured: resident size of the PalServer process just after bootabout 984 MiB
Measured: after a restart of the same world894 MB
Image documentation: minimum16 GB
Image documentation: recommendedover 32 GB "for stable operation"
Pocketpair's server guide16 GB, more than 32 GB recommended; 8 GB boots but makes out of memory crashes more likely

Under 1 GB is the floor: no players, no bases, no Pals working, nothing loaded beyond the spawn area. It is not what a server uses on day ten of a busy world. Memory grows as players explore and load more of the map, as bases and working Pals pile up, and over long uptimes. The image documentation does not publish a per player figure, and neither does Pocketpair's requirements page. For player count tiers built from running servers, see our performance optimization guide and the server requirements page.

Practical rules for the compose file:

  • Size mem_limit for the busiest day, not for what the server uses today; for Palworld that means what the machine can spare. On a 16 GB machine, 12 GB leaves room for the operating system; on 32 GB you can go higher.
  • Do not set a limit near the idle figure. We tried 600 MB on purpose and the kernel killed the server during startup (details in Troubleshooting).
  • Schedule restarts. The image has AUTO_REBOOT_ENABLED and AUTO_REBOOT_CRON_EXPRESSION, which warn players and restart on a schedule; by default it skips the restart while players are online. Our restart scheduling guide explains why.
  • Watch it: docker stats palworld-server shows usage against the limit live.

The settings file and how the variables reach it

Palworld reads one file: /palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini inside the container, which is ./palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini on your disk. It has a single section, [/Script/Pal.PalGameWorldSettings], and every setting sits on one very long line that starts like this in our test:

[/Script/Pal.PalGameWorldSettings]
OptionSettings=(Difficulty=None,RandomizerType=None,RandomizerSeed="",bIsRandomizerPalLevelRandom=False,DayTimeSpeedRate=1.000000,NightTimeSpeedRate=1.000000,ExpRate

On every start the image rebuilds that line from your environment variables. The naming rule, from the image documentation: capital letters, an underscore between words, and drop the leading lowercase b of a true or false setting. So PalSpawnNumRate becomes PAL_SPAWN_NUM_RATE and bIsPvP becomes IS_PVP. This is what our variables produced in the generated file:

VariableKey it writes in OptionSettingsValue we usedWritten as
PLAYERSServerPlayerMaxNum16ServerPlayerMaxNum=16
SERVER_NAMEServerNameMy Palworld ServerServerName="My Palworld Server"
SERVER_DESCRIPTIONServerDescriptionDocker test worldServerDescription="Docker test world"
SERVER_PASSWORDServerPasswordchange-me-joinServerPassword="change-me-join"
ADMIN_PASSWORDAdminPasswordchange-me-adminAdminPassword="change-me-admin"
PORTPublicPort (and the -port start argument)8211PublicPort=8211
CROSSPLAY_PLATFORMSCrossplayPlatforms(Steam,Xbox,PS5,Mac)CrossplayPlatforms=(Steam,Xbox,PS5,Mac)
RCON_ENABLEDRCONEnabledtrueRCONEnabled=true
RCON_PORTRCONPort25575RCONPort=25575
REST_API_ENABLEDRESTAPIEnabledtrueRESTAPIEnabled=true
REST_API_PORTRESTAPIPort8212RESTAPIPort=8212
EXP_RATEExpRate1.5ExpRate=1.5
DEATH_PENALTYDeathPenaltyItemDeathPenalty=Item
USE_BACKUP_SAVE_DATA (not set)bIsUseBackupSaveDataimage defaultbIsUseBackupSaveData=True

Three things we confirmed by changing values and restarting:

  • Changes need a recreate. Edit the compose file, then docker compose up -d. Compose recreates the container and the image rewrites the file. A plain docker restart keeps the old environment.
  • Quote decimals. We set EXP_RATE: 2.0 without quotes and the file got ExpRate=2, because YAML turned it into a number first. It works, but quoting ("2.0") keeps exactly what you typed.
  • Hand edits get overwritten. If you prefer to edit PalWorldSettings.ini yourself, set DISABLE_GENERATE_SETTINGS: true and only edit while the server is stopped. Otherwise the variables win at the next start. The image documentation lists this first among its known issues.

For what each Palworld key does in gameplay terms, use our PalWorldSettings.ini guide; the image documentation lists the full variable for every key.

REST API and RCON commands we ran

The image ships two helpers inside the container: rest-cli for the REST API and rcon-cli for RCON. Both read the password from the environment, so you never type it. These are the real outputs from our test world.

$ docker exec palworld-server rest-cli info
{
    "version": "v1.0.5.102999",
    "servername": "My Palworld Server",
    "description": "Docker test world",
    "worldguid": "36B882106A4F4EBCAA16940C167F791E"
}

$ docker exec palworld-server rest-cli metrics
{
    "currentplayernum": 0,
    "serverfps": 59,
    "serverfpsaverage": 59.759998321533203,
    "serverframetime": 16.732744216918945,
    "days": 0,
    "maxplayernum": 16,
    "basecampnum": 0,
    "uptime": 13
}

$ docker exec palworld-server rest-cli players
{
    "players": []
}

$ docker exec palworld-server rcon-cli Info
Welcome to Pal Server[v1.0.5.102999] My Palworld Server

$ docker exec palworld-server rcon-cli ShowPlayers
name,playeruid,steamid

$ docker exec palworld-server rcon-cli Save
Complete Save

$ docker exec palworld-server rcon-cli "Broadcast Hello world"
Broadcasted: Hello

The RCON broadcast carried only the first word. The image documentation lists this as a known issue and points to the REST version, which sends the full sentence: docker exec palworld-server rest-cli announce "Hello world". In our test rest-cli announce and rest-cli save printed nothing on success, and the server log confirmed each one with lines such as REST accessed endpoint /v1/api/save OK.

From the host itself you can call the API directly with HTTP basic auth, user admin and your admin password:

curl -u admin:change-me-admin http://127.0.0.1:8212/v1/api/info

Without the password the server answered 401 and logged REST accessed endpoint / Unauthorized. The full command list (kick, ban, unban, shutdown with a countdown) is in our RCON and admin tools page and the admin command list.

Stopping safely, and proof the world survives

Use docker compose stop or docker compose down. The image catches Docker's stop signal, saves through the REST API, asks the server to shut down, and waits up to 30 seconds for the process to exit before it forces it. Our stop took 7.1 seconds end to end and printed:

[LOG] REST accessed endpoint /v1/api/save OK
[LOG] REST accessed endpoint /v1/api/shutdown OK
REST API stopped
Shutdown handler: cleanup.
****Ending Server****
Stopping cronjobs

Between those lines the game also prints a long block of HTTPS connection detail as it reports its session to its built-in error reporting service; it is part of the game, not a problem. The container then shows exit code 143, which is the normal code for a process ended by the stop signal.

We started the container again and asked for the world identity: the same worldguid, 36B882106A4F4EBCAA16940C167F791E, came back, and the world folder in ./palworld/Pal/Saved/SaveGames/0/ kept the same name. We checked again after a recreate with changed settings and after a deliberate out of memory kill: the same world loaded both times.

Two warnings. Never use docker kill or a power cut as a stop button; that skips the save. And if you disable the REST API, the image's stop script cannot save first, so a stop falls back to sending the server process a plain termination signal with no save call in front of it.

Updates

There are two separate things to update.

  1. The game. With UPDATE_ON_BOOT: true, every container start asks Steam whether a newer build exists. On our second boot it logged ****Checking Installation**** then The server is up to date! and moved on in under a second. When Palworld patches, a docker compose restart pulls the new build. If you want this done for you, the image's AUTO_UPDATE_ENABLED with AUTO_UPDATE_CRON_EXPRESSION checks on a schedule, warns players AUTO_UPDATE_WARN_MINUTES ahead, takes a backup, and restarts. It relies on the restart policy above to come back up.
  2. The image. Change the tag in the compose file to the new release, then run docker compose pull and docker compose up -d. Your world is in ./palworld, so nothing is lost. The image documentation's own method is docker compose down --rmi all followed by docker compose up -d.

Before any big Palworld patch, run the backup command from the next section; our restore guide covers getting back.

Backups

The image has a backup command. We ran it on the live server:

$ docker exec palworld-server backup
****Creating backup****
Backup created at /palworld/backups/palworld-save-2026-10-04_16-44-03.tar.gz
****Removing Old Backups****
Removing backups older than 7 days

It saves the world through the REST API first, then packs the whole Pal/Saved folder (the world in SaveGames plus the Config folder with your settings) into a dated archive in ./palworld/backups/. On our fresh world it took 0.7 seconds and the archive was 18,360 bytes; a lived in world is far bigger. The schedule in our compose file runs the same command every six hours.

Separately, the game keeps its own rolling copies because the image sets bIsUseBackupSaveData=True: we found timestamped folders under SaveGames/0/<world id>/backup/world/ after each save.

Both of those live on the same disk as the server. A real backup leaves the machine. The simple version:

docker compose stop
tar -czf palworld-saved-$(date +%F).tar.gz palworld/Pal/Saved
docker compose start

Copy the archive somewhere else. To restore, the image offers an interactive docker exec -it palworld-server restore; done by hand, stop the server, put the SaveGames/0/<world id> folder back, and make sure DedicatedServerName in GameUserSettings.ini matches that folder name, then start again. In our test that file held DedicatedServerName=36B882106A4F4EBCAA16940C167F791E, the same id as the world folder. We did not run the restore command itself. More detail: restore and fix saves.

Troubleshooting

The server died and the log just says "Killed"

That is the out of memory killer. We forced it by lowering mem_limit to 600 MB, below the idle footprint. The log ended like this:

Waiting for REST API(8212) port to open to show player logging...
Killed
****Ending Server****
Stopping cronjobs
The server may have stalled while starting up.

Confirm it with:

docker inspect palworld-server --format 'oom={{.State.OOMKilled}} exit={{.State.ExitCode}} limit={{.HostConfig.Memory}}'

Ours returned oom=true exit=0 limit=629145600. The exit code was 0, not the 137 you might look for, because the image's wrapper script outlived the killed game process and exited on its own. OOMKilled is the field to trust. The fix is a higher mem_limit, fewer players, scheduled restarts, or more RAM in the machine. If it happens mid session on a long running world, memory growth over time is the usual cause; see the RAM section.

Port already in use

When we started a second container on a host port the server already held, it refused to start:

Error: pasta failed with exit code 1:
Failed to bind port 28611 (Address already in use) for option '-u 127.0.0.1/28611-28611:8211-8211'

That wording is from the engine we tested with; Docker Engine phrases it differently, but either way the message names the port. Find what holds it with sudo ss -ulpn | grep 8211 (use -tlpn for the TCP ports 8212 and 25575). Usually it is a second copy of the server or an old container; docker ps -a shows it. To run two servers, give the second one different left side ports and a different PORT.

The server does not show in the community list

We could not test this, since our ports were loopback only. According to the image documentation you need all of: COMMUNITY: true (and a SERVER_PASSWORD, which the docs insist on), port 27015/udp published and forwarded alongside 8211/udp, and your firewall letting both through. If your public port differs from the container's, set PUBLIC_PORT, and PUBLIC_IP if the address is detected wrongly. The docs add that the "breakpad minidump" line means the server is up, so a server that prints it but cannot be reached is a firewall or port forward problem. Players can always join by IP and port without the list.

My settings keep resetting

The variables rewrite PalWorldSettings.ini on every start unless DISABLE_GENERATE_SETTINGS is true; see the settings section.

Health status

The image defines a Docker health check that tests whether the PalServer process is running, with a five minute start period. On Docker Engine, docker ps shows it as healthy or unhealthy. Our test run did not report it, so we have not seen it ourselves.

For log reading in general, our server logs guide and the known issues page cover the messages that are not Docker specific.

When Docker at home is the wrong tool

The container part is easy: we had a working server in under 13 minutes, most of it download. The hard parts are the ones Docker does not solve:

  • RAM. If the machine is also your gaming PC, a 16 player world competing with the game client for memory is the classic way both of them stutter and the server gets killed.
  • Uptime. Friends in other time zones want the world up when your PC is asleep, updating, or rebooting.
  • Your home connection. Port forwarding, a changing home IP, carrier grade NAT on some providers, and upload bandwidth are all on you.
  • Patch days. Palworld updates land for everyone at once, and clients cannot join until the server matches. Someone has to be home to restart it.

For a weekend with two or three friends on a spare machine with 16 GB or more, the compose file above is a fine answer. For a world that should be online every day for a bigger group, it usually is not.

Skip the setup: a Palworld server that is just running

If you would rather play than manage containers, memory limits and patch day restarts, a managed server does that part for you, with daily backups and a control panel for your server settings. Get a Palworld dedicated server from Supercraft and have your world online in minutes.

Launch a Palworld server with this setup

Pick a preset and your new server boots preconfigured - rates, rules and mods already dialed in. Change anything later in the panel.

Browse all Palworld recipes →

Palworld Classic PvE: Vanilla Rates

Baseline PvE experience with default Pocketpair rates and full death penalty. A clean starting point if you w…

Palworld Turbo PvE: 6× XP, Fast Nights

Fast-progression PvE preset: 6× XP, 3.5× capture rate, 3× resource drops, 2× night speed. Perfect for short-s…

Tired of fighting this issue every patch?

Run a managed Palworld server with us. We handle the patches, mod-version pinning, save backups, and DDoS protection. Set up in minutes, multiple datacenter regions, no contract.

See Palworld hosting plans →
Top