Repository navigation
Expand file tree
/
Copy pathDockerfile
More file actions
306 lines (275 loc) · 13.1 KB
/
Copy pathDockerfile
File metadata and controls
306 lines (275 loc) · 13.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
FROM golang:1.27.3-alpine AS rcon-cli_builder
ARG RCON_VERSION="0.10.3"
ARG RCON_TGZ_SHA1SUM=33ee8077e66bea6ee097db4d9c923b5ed390d583
WORKDIR /build
# install rcon
SHELL ["/bin/ash", "-o", "pipefail", "-c"]
ENV CGO_ENABLED=0
RUN wget -q https://github.com/gorcon/rcon-cli/archive/refs/tags/v${RCON_VERSION}.tar.gz -O rcon.tar.gz \
&& echo "${RCON_TGZ_SHA1SUM}" rcon.tar.gz | sha1sum -c - \
&& tar -xzvf rcon.tar.gz \
&& rm rcon.tar.gz \
&& mv rcon-cli-${RCON_VERSION}/* ./ \
&& rm -rf rcon-cli-${RCON_VERSION} \
&& go build -v ./cmd/gorcon
FROM cm2network/steamcmd:root-trixie AS base-amd64
# Ignoring --platform=arm64 as this is required for the multi-arch build to continue to work on amd64 hosts
# hadolint ignore=DL3029
FROM --platform=arm64 sonroyaalmerol/steamcmd-arm64:root-trixie-2026-06-07 AS base-arm64
ARG TARGETARCH
# Ignoring the lack of a tag here because the tag is defined in the above FROM lines
# and hadolint isn't aware of those.
# hadolint ignore=DL3006
FROM base-${TARGETARCH}
ARG TARGETARCH
ARG TARGET_SERVER_PLATFORM=Linux
LABEL maintainer="thijs@loef.dev" \
name="thijsvanloef/palworld-server-docker" \
github="https://github.com/thijsvanloef/palworld-server-docker" \
dockerhub="https://hub.docker.com/r/thijsvanloef/palworld-server-docker" \
org.opencontainers.image.authors="Thijs van Loef" \
org.opencontainers.image.source="https://github.com/thijsvanloef/palworld-server-docker"
# set envs
# SUPERCRONIC: Latest releases available at https://github.com/aptible/supercronic/releases
# RCON: Latest releases available at https://github.com/gorcon/rcon-cli/releases
# DEPOT_DOWNLOADER: Latest releases available at https://github.com/SteamRE/DepotDownloader/releases
# NOTICE: edit RCON_MD5SUM SUPERCRONIC_SHA1SUM when using binaries of another version or arch.
ARG SUPERCRONIC_SHA1SUM_ARM64="639ab81a72771990790df7ee87d9acfe88e5fa83"
ARG SUPERCRONIC_SHA1SUM_AMD64="5bcefed628e32adc08e32634db2d10e9230dbca0"
ARG SUPERCRONIC_VERSION="0.2.46"
ARG DEPOT_DOWNLOADER_VERSION="3.4.0"
ARG KNOCK_VERSION="0.8.1"
ARG WINE_BRANCH="stable"
# install wine source list for Windows only
# hadolint ignore=DL4001
RUN if [ "${TARGET_SERVER_PLATFORM}" = "Windows" ]; then \
dpkg --add-architecture i386 \
&& mkdir -p /etc/apt/keyrings && chmod 755 /etc/apt/keyrings \
&& curl -fsSL https://dl.winehq.org/wine-builds/winehq.key -o /etc/apt/keyrings/winehq-archive.key \
&& curl -fsSL https://dl.winehq.org/wine-builds/debian/dists/trixie/winehq-trixie.sources -o /etc/apt/sources.list.d/winehq-trixie.sources ; \
fi
# update and install dependencies
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
procps \
wget \
gettext-base \
xdg-user-dirs \
jo \
jq \
netcat-traditional \
unzip \
iproute2 \
iptables \
tcpdump \
libcap2-bin libpcap0.8 \
ca-certificates \
python3 python3-venv python3-pip \
&& (apt-get install -y --no-install-recommends libicu76 || apt-get install -y --no-install-recommends libicu72 || apt-get install -y --no-install-recommends libicu67) \
&& (apt-get install -y --no-install-recommends libsdl3-0 || apt-get install -y --no-install-recommends libsdl3-0-0) \
&& if [ "${TARGET_SERVER_PLATFORM}" = "Windows" ]; then apt-get install -y --no-install-recommends cabextract gnupg winbind xvfb xauth winehq-${WINE_BRANCH}; fi \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN python3 -m venv /opt/mitmproxy-venv \
&& /opt/mitmproxy-venv/bin/pip install --no-cache-dir mitmproxy \
&& ln -s /opt/mitmproxy-venv/bin/mitmproxy /usr/local/bin/ \
&& ln -s /opt/mitmproxy-venv/bin/mitmdump /usr/local/bin/ \
&& ln -s /opt/mitmproxy-venv/bin/mitmweb /usr/local/bin/
# install rcon and supercronic
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
COPY --from=rcon-cli_builder /build/gorcon /usr/bin/rcon-cli
# hadolint ignore=DL4001
RUN case "${TARGETARCH}" in \
"amd64") SUPERCRONIC_SHA1SUM=${SUPERCRONIC_SHA1SUM_AMD64} ;; \
"arm64") SUPERCRONIC_SHA1SUM=${SUPERCRONIC_SHA1SUM_ARM64} ;; \
esac \
&& wget --progress=dot:giga "https://github.com/aptible/supercronic/releases/download/v${SUPERCRONIC_VERSION}/supercronic-linux-${TARGETARCH}" -O supercronic \
&& echo "${SUPERCRONIC_SHA1SUM}" supercronic | sha1sum -c - \
&& chmod +x supercronic \
&& mv supercronic /usr/local/bin/supercronic
# hadolint ignore=DL4001
RUN case "${TARGETARCH}" in \
"amd64") DEPOT_DOWNLOADER_FILENAME=DepotDownloader-linux-x64.zip ;; \
"arm64") DEPOT_DOWNLOADER_FILENAME=DepotDownloader-linux-arm64.zip ;; \
esac \
&& wget --progress=dot:giga "https://github.com/SteamRE/DepotDownloader/releases/download/DepotDownloader_${DEPOT_DOWNLOADER_VERSION}/${DEPOT_DOWNLOADER_FILENAME}" -O DepotDownloader.zip \
&& unzip DepotDownloader.zip \
&& rm -rf DepotDownloader.xml \
&& chmod +x DepotDownloader \
&& mv DepotDownloader /usr/local/bin/DepotDownloader
# AUTO_PAUSE: install backend monitoring tools (iptables, tcpdump, knockd) and set capabilities for non-root usage
# setcap for tcpdump/iptables to allow non-root NFLOG monitoring and rule updates
RUN setcap cap_net_raw,cap_net_admin=ep "$(readlink -f "$(command -v tcpdump)")" && \
setcap cap_net_admin=ep "$(readlink -f "$(command -v iptables)")"
# install winetricks, create wine group/user and add steam to wine group (amd64 only).
# The wine group lets the Wine prefix live in /opt/wine (outside /palworld and /home/steam),
# so init.sh's chown -R never traverses it regardless of PUID/PGID changes.
# hadolint ignore=DL4001
RUN if [ "${TARGET_SERVER_PLATFORM}" = "Windows" ]; then \
wget -nv -O /usr/local/bin/winetricks https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks \
&& chmod +x /usr/local/bin/winetricks \
&& groupadd -r wine \
&& useradd -r -g wine -M -s /usr/sbin/nologin wine \
&& usermod -a -G wine steam ; \
fi
# install patched knockd (as same as https://github.com/itzg/docker-minecraft-server/blob/master/build/ubuntu/install-packages.sh)
# hadolint ignore=DL4001
RUN wget --progress=dot:giga https://github.com/Metalcape/knock/releases/download/0.8.1/knock-${KNOCK_VERSION}-${TARGETARCH}.tar.gz -O /tmp/knock.tar.gz && \
tar -xf /tmp/knock.tar.gz -C /usr/local/ && rm /tmp/knock.tar.gz && \
ln -s /usr/local/sbin/knockd /usr/sbin/knockd && \
setcap cap_net_raw=ep /usr/local/sbin/knockd && \
find /usr/lib -name 'libpcap.so.0.8' -execdir cp '{}' libpcap.so.1 \;
# hadolint ignore=DL3044
ENV HOME=/home/steam \
SERVER_PLATFORM=${TARGET_SERVER_PLATFORM} \
PORT= \
PUID=1000 \
PGID=1000 \
PLAYERS= \
MULTITHREADING=false \
COMMUNITY=false \
PUBLIC_IP= \
PUBLIC_PORT= \
SERVER_PASSWORD= \
SERVER_NAME= \
ADMIN_PASSWORD= \
UPDATE_ON_BOOT=true \
SETUP_ONLY=false \
RCON_ENABLED=false \
RCON_PORT=25575 \
QUERY_PORT=27015 \
REST_API_ENABLED=true \
REST_API_PORT=8212 \
TZ=UTC \
SERVER_DESCRIPTION= \
BACKUP_ENABLED=true \
DELETE_OLD_BACKUPS=false \
OLD_BACKUP_DAYS=30 \
BACKUP_CRON_EXPRESSION="0 0 * * *" \
AUTO_UPDATE_ENABLED=false \
AUTO_UPDATE_CRON_EXPRESSION="0 * * * *" \
AUTO_UPDATE_WARN_MINUTES=30 \
AUTO_REBOOT_ENABLED=false \
AUTO_REBOOT_WARN_MINUTES=5 \
AUTO_REBOOT_EVEN_IF_PLAYERS_ONLINE=false \
AUTO_REBOOT_CRON_EXPRESSION="0 0 * * *" \
AUTO_PAUSE_ENABLED=false \
AUTO_PAUSE_TIMEOUT_EST=180 \
AUTO_PAUSE_LOG=true \
AUTO_PAUSE_DEBUG=false \
AUTO_PAUSE_KNOCKD_IF=auto \
DISCORD_SUPPRESS_NOTIFICATIONS= \
DISCORD_WEBHOOK_URL= \
DISCORD_CONNECT_TIMEOUT=30 \
DISCORD_MAX_TIMEOUT=30 \
DISCORD_PRE_UPDATE_BOOT_MESSAGE="Server is updating..." \
DISCORD_PRE_UPDATE_BOOT_MESSAGE_URL= \
DISCORD_PRE_UPDATE_BOOT_MESSAGE_ENABLED=true \
DISCORD_POST_UPDATE_BOOT_MESSAGE="Server update complete!" \
DISCORD_POST_UPDATE_BOOT_MESSAGE_URL= \
DISCORD_POST_UPDATE_BOOT_MESSAGE_ENABLED=true \
DISCORD_PRE_START_MESSAGE="Server has been started!" \
DISCORD_PRE_START_MESSAGE_URL= \
DISCORD_PRE_START_MESSAGE_ENABLED=true \
DISCORD_PRE_SHUTDOWN_MESSAGE="Server is shutting down..." \
DISCORD_PRE_SHUTDOWN_MESSAGE_URL= \
DISCORD_PRE_SHUTDOWN_MESSAGE_ENABLED=true \
DISCORD_POST_SHUTDOWN_MESSAGE="Server has been stopped!" \
DISCORD_POST_SHUTDOWN_MESSAGE_URL= \
DISCORD_POST_SHUTDOWN_MESSAGE_ENABLED=true \
DISCORD_PLAYER_JOIN_MESSAGE="player_name has joined Palworld!" \
DISCORD_PLAYER_JOIN_MESSAGE_URL= \
DISCORD_PLAYER_JOIN_MESSAGE_ENABLED=true \
DISCORD_PLAYER_LEAVE_MESSAGE="player_name has left Palworld." \
DISCORD_PLAYER_LEAVE_MESSAGE_URL= \
DISCORD_PLAYER_LEAVE_MESSAGE_ENABLED=true \
DISCORD_PRE_BACKUP_MESSAGE="Creating backup..." \
DISCORD_PRE_BACKUP_MESSAGE_URL= \
DISCORD_PRE_BACKUP_MESSAGE_ENABLED=true \
DISCORD_POST_BACKUP_MESSAGE="Backup created at file_path" \
DISCORD_POST_BACKUP_MESSAGE_URL= \
DISCORD_POST_BACKUP_MESSAGE_ENABLED=true \
DISCORD_PRE_BACKUP_DELETE_MESSAGE="Removing backups older than old_backup_days days" \
DISCORD_PRE_BACKUP_DELETE_MESSAGE_URL= \
DISCORD_PRE_BACKUP_DELETE_MESSAGE_ENABLED=true \
DISCORD_POST_BACKUP_DELETE_MESSAGE="Removed backups older than old_backup_days days" \
DISCORD_POST_BACKUP_DELETE_MESSAGE_URL= \
DISCORD_POST_BACKUP_DELETE_MESSAGE_ENABLED=true \
DISCORD_ERR_BACKUP_DELETE_MESSAGE="Unable to delete old backups, OLD_BACKUP_DAYS is not an integer. OLD_BACKUP_DAYS=old_backup_days" \
DISCORD_ERR_BACKUP_DELETE_MESSAGE_URL= \
DISCORD_ERR_BACKUP_DELETE_MESSAGE_ENABLED=true \
ENABLE_PLAYER_LOGGING=true \
PLAYER_LOGGING_POLL_PERIOD=5 \
ARM64_DEVICE=generic \
PALWORLD_ALLOW_NEGATIVE_DELTA_TIME=false \
DISABLE_GENERATE_ENGINE=true \
CROSSPLAY_PLATFORMS="(Steam,Xbox,PS5,Mac)" \
USE_DEPOT_DOWNLOADER=false \
INSTALL_BETA_INSIDER=false \
MOD_UPDATE_ON_BOOT=true \
MOD_ENABLED=true \
MOD_IDS= \
MOD_URL_UE4SS="https://github.com/Okaetsu/RE-UE4SS/releases/download/2281fa31/UE4SS-Palworld-g2281fa31.zip" \
MOD_ID_PALSCHEMA="3625280368" \
MOD_USE_PALDEFENDER=false \
MOD_URL_PALDEFENDER="https://github.com/Ultimeit/PalDefender/releases/latest/download/PalDefender.zip" \
MOD_DEBUG=false \
LOG_FILTER_ENABLED=true \
LOG_LEVEL=INFO \
LOG_FORMAT_TYPE=default
# Sane Box64 config defaults
# hadolint ignore=DL3044
ENV BOX64_DYNAREC_STRONGMEM=1 \
BOX64_DYNAREC_BIGBLOCK=1 \
BOX64_DYNAREC_SAFEFLAGS=1 \
BOX64_DYNAREC_FASTROUND=1 \
BOX64_DYNAREC_FASTNAN=1 \
BOX64_DYNAREC_X87DOUBLE=0
# Passed from Github Actions
ARG GIT_VERSION_TAG=unspecified
COPY ./scripts /home/steam/server/
RUN chmod +x /home/steam/server/*.sh && \
mv /home/steam/server/backup.sh /usr/local/bin/backup && \
mv /home/steam/server/update.sh /usr/local/bin/update && \
mv /home/steam/server/restore.sh /usr/local/bin/restore && \
ln -sf /home/steam/server/rest_api.sh /usr/local/bin/rest-cli
# AUTO_PAUSE
RUN chmod +x /home/steam/server/autopause/*.sh && \
ln -sf /home/steam/server/autopause/autopause.sh /usr/local/bin/autopause && \
ln -sf /home/steam/server/autopause/knockd-ctl.sh /usr/local/sbin/knockd-ctl
# AUTO_PAUSE with Community
RUN mkdir -p /home/steam/.mitmproxy && \
openssl genrsa -out ca.key 2048 && \
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt -addext keyUsage=critical,keyCertSign -subj "/CN=rootca" && \
cat ca.key ca.crt > /home/steam/.mitmproxy/mitmproxy-ca.pem && \
chown -R steam:steam /home/steam/.mitmproxy && \
rm ca.key && \
mv ca.crt /usr/local/share/ca-certificates/mitmproxy.crt && \
update-ca-certificates
# mods
RUN chmod +x /home/steam/server/mods/*.sh /home/steam/server/mods/wine-run.py && \
ln -sf /home/steam/server/mods/update.sh /usr/local/bin/mods-update && \
ln -sf /home/steam/server/mods/update-wine-rt.sh /usr/local/bin/update-wine-rt && \
ln -sf /home/steam/server/mods/steam-login.sh /usr/local/bin/steam-login && \
ln -sf /home/steam/server/mods/wine-run.py /usr/local/bin/wine-run
# Bake Visual C++ 2022 Runtime into the image at build time (Windows only).
# Pre-create directories as root before dropping to steam:
# /tmp/.X11-unix — Xvfb cannot create this as non-root
# /opt/wine — /opt is root-owned; owned by steam:wine so Wine's owner check passes
RUN if [ "${TARGET_SERVER_PLATFORM}" = "Windows" ]; then \
mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix && \
mkdir -p /opt/wine && chown steam:wine /opt/wine && chmod 2770 /opt/wine && \
su steam -c '/usr/local/bin/update-wine-rt' && \
rm -rf /home/steam/Steam ; \
fi
WORKDIR /home/steam/server
# Make GIT_VERSION_TAG file to be able to check the version
RUN echo $GIT_VERSION_TAG > GIT_VERSION_TAG
RUN touch rcon.yaml crontab && \
rm -rf /tmp/dumps && \
chmod o+w rcon.yaml crontab && \
chown steam:steam -R /home/steam/server
HEALTHCHECK --start-period=5m \
CMD bash -c '. ./helper_functions.sh && PalworldServerPid > /dev/null || exit 1'
EXPOSE ${PORT} ${RCON_PORT}
ENTRYPOINT ["/home/steam/server/init.sh"]