# palworld-server-docker: a Compose file for a Palworld dedicated server

> The image wraps SteamCMD, config generation and backups behind environment variables, so a Palworld server becomes a compose.yaml and a volume. It is a good fit for a self-hoster with 16GB of RAM and a Linux box, and the wrong one if you want a managed panel.

**thijsvanloef/palworld-server-docker** — A Docker Container to easily run a Palworld dedicated server.

- Repository: https://github.com/thijsvanloef/palworld-server-docker
- Website: https://hub.docker.com/r/thijsvanloef/palworld-server-docker
- Stars: 3,209 · Forks: 372
- Language: Shell
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/thijsvanloef-palworld-server-docker

## What problem palworld-server-docker removes

Running a Palworld dedicated server by hand means installing SteamCMD, pulling the app, writing a config file, keeping the process alive, and repeating the whole thing every time the game updates. The repository packages that sequence into one image. The README describes it plainly as a Docker container to help you get started with hosting your own Palworld dedicated server, and the compose.yaml in the repository root is the intended entry point.

The audience is narrow and specific: someone who already has Docker, wants the server on hardware they control, and is willing to read environment variable names instead of clicking through a control panel. The README lists the tested platforms as Linux (Ubuntu/Debian), Windows 10 and 11, macOS including Apple Silicon M1/M2/M3, and Raspberry Pi 4/5, on both x64 and ARM64. That breadth is unusual for a game server image and it comes from a multi-arch Dockerfile that swaps the SteamCMD base image per architecture.

What it does not do is abstract the game. Every gameplay knob in .env.example, from EXP_RATE to PAL_CAPTURE_RATE, is a direct passthrough to the server's own settings. If Palworld's server does not expose a setting, this image does not invent one.

## How the image turns environment variables into a running server

The Dockerfile is a multi-stage build. The first stage compiles rcon-cli from a pinned source tarball, verifying it against a SHA1 checksum before unpacking, and builds it with CGO_ENABLED=0 so the resulting binary is static. The second stage picks a SteamCMD base image by target architecture: cm2network/steamcmd for amd64 and sonroyaalmerol/steamcmd-arm64 for arm64. The ARM64 base is pinned to a dated tag, root-trixie-2026-06-07, which is the kind of pin that keeps a rebuild reproducible but also means ARM users wait for that tag to move.

At runtime the entrypoint scripts do the work the README does not spell out in detail. The compose file mounts a single volume, ./palworld:/palworld/, and that directory holds the installed server, its generated configuration and the save data. The environment block is the control surface: PUID and PGID set the file ownership, PORT and PLAYERS set the basics, SERVER_PASSWORD gates entry, and ADMIN_PASSWORD feeds the admin and REST API credentials. UPDATE_ON_BOOT defaults to true in .env.example, so a restart can pull a newer server build before the process starts.

Backups are not an afterthought. BACKUP_ENABLED defaults to true, BACKUP_CRON_EXPRESSION defaults to 0 0 * * *, and DELETE_OLD_BACKUPS with OLD_BACKUP_DAYS controls retention. The repository also ships AUTO_UPDATE_ENABLED, AUTO_REBOOT_ENABLED and AUTO_PAUSE_ENABLED blocks in .env.example, all defaulting to false, which is the right default for a feature that can interrupt players.

## Installing it with Docker Compose and logging in

The repository includes a compose.yaml you can copy. The service pulls thijsvanloef/palworld-server-docker:latest, restarts unless stopped, and maps two UDP ports: 8211 for the game and 27015 for the query port, which the file notes is required if you want the server to appear in the community servers tab. A third port, 8212, is commented out with the instruction not to port forward it, because it is the REST API.

```yaml
services:
  palworld:
    image: thijsvanloef/palworld-server-docker:latest
    restart: unless-stopped
    container_name: palworld-server
    stop_grace_period: 30s
    ports:
      - 8211:8211/udp
      - 27015:27015/udp
    volumes:
      - ./palworld:/palworld/
```

That block is the shape of the file in the repository, trimmed to the parts you must not get wrong. Bring it up with Compose from the directory holding the file.

```bash
docker compose up -d
```

On first start the container downloads the server through SteamCMD into /palworld/, generates the configuration from your environment variables, and launches the process. Expect the first boot to take a while: the download is the slow part, not the container start. Follow it with docker compose logs -f palworld-server and wait for the server to report that it is listening before you try to connect.

To connect, players use the host's address and port 8211. If you set SERVER_PASSWORD, they need it. If you want the server listed publicly, set COMMUNITY to true and keep a password set, as the compose file comment warns, and set PUBLIC_PORT if your public port differs from 8211.

The environment block is where the real configuration lives. A minimal version of what the repository shows looks like this.

```yaml
    environment:
      PUID: 1000
      PGID: 1000
      PORT: 8211
      PLAYERS: 16
      SERVER_PASSWORD: "worldofpals"
      ADMIN_PASSWORD: "adminPasswordHere"
      REST_API_ENABLED: true
      REST_API_PORT: 8212
      TZ: "UTC"
```

Change every password. The values in the repository are examples, and ADMIN_PASSWORD protects the admin interface, not just a display name.

## The resource floor and the ports you must not forward

The README's requirements table is the first thing to check against your hardware. Minimum is 4 CPU cores, 16GB of RAM and 8GB of storage; recommended is 4+ cores, over 32GB of RAM for stable operation, and 20GB of storage. Those numbers are higher than most small game servers, and the recommended RAM figure is the one worth taking seriously. A 16GB host running this image alongside anything else is at the edge of the stated minimum, not comfortably inside it.

The security boundary is the second constraint. REST_API_ENABLED defaults to true in both the compose.yaml and .env.example, and the compose file carries an explicit comment: DO NOT PORT FORWARD THIS. The REST API on port 8212 is reachable from the container network by default, and the README's warning implies the intended deployment keeps it on a private network. If you expose 8212 to the internet because it made testing easier, you have handed the admin surface to anyone who scans for it.

The third is log noise and secret leakage. LOG_LEVEL defaults to INFO, and the compose file warns that DEBUG will log all command arguments, including secrets, to the logs. Anyone who has pasted container logs into a Discord thread for help has already made this mistake once. The same file sets LOG_FORMAT_TYPE, so you can change the output shape without changing the level.

Finally, the graceful shutdown window. stop_grace_period is 30s in the repository file, with a comment telling you to set it to however long you are willing to wait. A save in progress at shutdown is the classic way to lose an hour of progress, and that value is the only thing standing between a clean stop and a truncated one.

## Autopause, mods and the parts the README leaves open

The .env.example exposes a set of features that go beyond a thin wrapper. AUTO_PAUSE_ENABLED defaults to false, and the accompanying keys, AUTO_PAUSE_TIMEOUT_EST at 180, AUTO_PAUSE_LOG, AUTO_PAUSE_DEBUG and AUTO_PAUSE_KNOCKD_IF set to auto, suggest a mechanism that pauses the server when nobody is connected. The repository also carries an examples/autopause/ directory, which is where the actual configuration for that feature lives. The README itself does not explain the pause mechanism, so treat the example directory as the source of truth rather than guessing from the variable names.

Player logging is on by default. ENABLE_PLAYER_LOGGING is true and PLAYER_LOGGING_POLL_PERIOD is 5 seconds, with LOG_FILTER_ENABLED true. That is a five-second poll writing to the container's log stream, which is cheap but not free, and it is the kind of setting you want to know about before you wonder why your logs are busy.

Mods are the weakest documented area. The related searches around this project include mods, and the repository has an examples/map/ directory, but the README does not describe a mod-loading workflow. The image installs the vanilla server through SteamCMD into /palworld/, and anything beyond that is not covered in the README. If mods are a requirement for your group, verify the current state of that support before you migrate a running world onto this image.

The same caution applies to the 1.0 compatibility note at the top of the README. It points readers to issue 834 for known problems with the Palworld 1.0 release rather than asserting that everything works. That is an honest framing and worth following before a first deployment.

## LinuxGSM and hand-rolled systemd units

The obvious alternative for a self-hoster is LinuxGSM, which manages game servers as plain processes on the host with its own scripts for install, update and monitoring. The difference in approach is where the isolation sits. LinuxGSM gives you a server user, a directory and a set of shell commands you run directly on the machine; palworld-server-docker gives you an image, a volume and environment variables, and the server's dependencies never touch the host. If you already run other services in Docker and want one Compose file to bring the whole stack up, the container wins. If you want to attach a debugger, edit files in place and read the process list, LinuxGSM's model is closer to the metal.

A hand-written systemd unit plus a SteamCMD update script is the other path, and it is more work than it sounds. You own the update logic, the config templating, the backup cron and the file ownership. The repository has already made those decisions and encoded them, which is the actual product here. The trade is that you inherit its choices: the image's update-on-boot behaviour, its backup schedule defaults, and its opinion that the REST API lives on port 8212.

For anyone who wants a managed panel rather than a Compose file, a rented Palworld host is the honest comparison. The README itself links a sponsor's hosting with a two-day trial, which is a reasonable signal that the project's author sees renting as a legitimate alternative rather than a competitor to defeat.

## Maintenance, licensing and what an upgrade actually costs

The repository is not archived, and the last push was on 2026-09-13, which is recent. Releases have been frequent: 2.7.3 on 2026-08-25, 2.7.2 on 2026-08-15 and 2.7.1 on 2026-07-23. That cadence matters because Palworld's server binary changes under the image, and a wrapper that does not track those changes becomes a wrapper that breaks on patch day.

The licence is MIT. In practical terms that permits commercial use, modification and redistribution provided the copyright notice and permission notice are included. It offers no warranty, and it says nothing about Palworld itself, which is a separate product with its own terms. If you plan to run a monetised server, the licence of this image is not the question you need to answer; the game's own server terms are. That is a legal question for someone qualified to answer it, not something to infer from an MIT header.

Upgrade cost is low but not zero. Because the server lives in the /palworld/ volume and the image is pulled by tag, updating the wrapper is a pull and a recreate, while updating the game is what UPDATE_ON_BOOT handles. The risk sits in the volume, not the image: a container recreate that points at a different host path, or a backup cron that was never verified to produce restorable archives, is where a working server turns into a lost world. The .env.example defaults BACKUP_ENABLED to true and DELETE_OLD_BACKUPS to false, which means backups accumulate rather than rotate away until you set OLD_BACKUP_DAYS and flip that flag.

## Conclusion

Adopt it if you already run Docker on a Linux host with 16GB of RAM or more and want the server config expressed as environment variables in a compose.yaml you keep in version control. Do not adopt it if you want a web panel, per-player permissions or a hosted control plane, or if your host has 8GB of RAM and no swap headroom, because the README's minimum is 16GB and 8GB of storage. Before you commit, verify three things on your own machine: that the /palworld/ volume lands on a disk with the free space you expect, that the UDP ports 8211 and 27015 are open end to end, and that REST_API_PORT 8212 is reachable only from your own network, since the README marks it as a port you must not forward.

## FAQ

### Is there a way to host a Palworld server with palworld-server-docker?

Yes. The repository provides a compose.yaml that runs the image, maps UDP ports 8211 and 27015, and mounts ./palworld:/palworld/ for the server files and saves. The README states the container has been tested on Linux, Windows 10 and 11, macOS including Apple Silicon, and Raspberry Pi 4/5.

### How do I update a Palworld server running in Docker?

UPDATE_ON_BOOT defaults to true in .env.example, so a container restart can pull a newer server build before the process starts. The repository also exposes AUTO_UPDATE_ENABLED with AUTO_UPDATE_CRON_EXPRESSION and AUTO_UPDATE_WARN_MINUTES, all defaulting to false, for scheduled updates that warn players first.

### What are the server requirements for palworld-server-docker?

The README's table lists a minimum of 4 CPU cores, 16GB of RAM and 8GB of storage, and recommends 4+ cores, over 32GB of RAM for stable operation, and 20GB of storage. The image supports both x64 and ARM64 CPU architectures.

### Which ports does palworld-server-docker need open?

The compose.yaml maps 8211/udp for the game and 27015/udp for the query port, which the file notes is required for the server to appear in the community servers tab. Port 8212/tcp is the REST API and the file explicitly says DO NOT PORT FORWARD THIS.

### Does palworld-server-docker work on ARM64 or a Raspberry Pi?

The README lists Raspberry Pi 4/5 among the tested platforms and states the container works on both x64 and ARM64 CPU architectures. The Dockerfile confirms this by selecting a separate SteamCMD base image per target architecture.

## Sources

- [License: MIT](https://github.com/thijsvanloef/palworld-server-docker/blob/main/LICENSE)
- [Project website](https://hub.docker.com/r/thijsvanloef/palworld-server-docker)
- [README](https://github.com/thijsvanloef/palworld-server-docker/blob/main/README.md)
- [Releases](https://github.com/thijsvanloef/palworld-server-docker/releases)
- [thijsvanloef/palworld-server-docker on GitHub](https://github.com/thijsvanloef/palworld-server-docker)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/thijsvanloef-palworld-server-docker
