Add dedicated server packaging
This commit is contained in:
commit
b9c031dfab
13 changed files with 275 additions and 0 deletions
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
packages
|
||||||
|
dist/SHA256SUMS
|
||||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
/dist/*
|
||||||
|
!/dist/.gitkeep
|
||||||
|
/packages/
|
||||||
|
/.env
|
||||||
26
Dockerfile
Normal file
26
Dockerfile
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
RUN groupadd --system --gid 10001 netfishing \
|
||||||
|
&& useradd --system --uid 10001 --gid netfishing \
|
||||||
|
--home-dir /var/lib/netfishing-server netfishing \
|
||||||
|
&& install -d -o netfishing -g netfishing \
|
||||||
|
/opt/netfishing-server /var/lib/netfishing-server
|
||||||
|
|
||||||
|
COPY --chown=netfishing:netfishing \
|
||||||
|
dist/NETfishingServer.x86_64 \
|
||||||
|
dist/NETfishingServer.pck \
|
||||||
|
/opt/netfishing-server/
|
||||||
|
COPY --chown=netfishing:netfishing \
|
||||||
|
config/server.cfg.example /etc/netfishing-server.cfg
|
||||||
|
|
||||||
|
RUN chmod 0555 /opt/netfishing-server/NETfishingServer.x86_64 \
|
||||||
|
&& chmod 0444 /opt/netfishing-server/NETfishingServer.pck \
|
||||||
|
/etc/netfishing-server.cfg
|
||||||
|
|
||||||
|
USER 10001:10001
|
||||||
|
WORKDIR /opt/netfishing-server
|
||||||
|
VOLUME ["/var/lib/netfishing-server"]
|
||||||
|
EXPOSE 7777/udp
|
||||||
|
|
||||||
|
ENTRYPOINT ["/opt/netfishing-server/NETfishingServer.x86_64"]
|
||||||
|
CMD ["--", "--config=/etc/netfishing-server.cfg"]
|
||||||
80
README.md
Normal file
80
README.md
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
# NETfishing Dedicated Server
|
||||||
|
|
||||||
|
This repository packages the headless NETfishing server produced by the main
|
||||||
|
game project. Gameplay and networking code remain in the `netfishing`
|
||||||
|
repository so clients and servers use the same protocol implementation.
|
||||||
|
|
||||||
|
## Stage a build
|
||||||
|
|
||||||
|
Export the `Linux Dedicated Server` preset from the game project, then stage
|
||||||
|
its executable and PCK:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./scripts/stage-build.sh ../netfishing/builds/v0.6.4-alpha/server-linux-x86_64
|
||||||
|
```
|
||||||
|
|
||||||
|
The staged binaries under `dist/` are release inputs and are intentionally not
|
||||||
|
tracked by Git.
|
||||||
|
|
||||||
|
Create a deterministic native archive after staging:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./scripts/package-native.sh 0.6.4-alpha
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run natively
|
||||||
|
|
||||||
|
Copy `dist/NETfishingServer.x86_64` and `dist/NETfishingServer.pck` into the
|
||||||
|
same directory, make the executable runnable, and start it with a persistent
|
||||||
|
data directory:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./NETfishingServer.x86_64 \
|
||||||
|
-- \
|
||||||
|
--config=/etc/netfishing-server.cfg \
|
||||||
|
--data-dir=/var/lib/netfishing-server
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy `config/server.cfg.example` to `/etc/netfishing-server.cfg` and adjust the
|
||||||
|
room name, UDP port, player limit, and public-listing preference. Forward the
|
||||||
|
configured UDP port through the host firewall and router when accepting
|
||||||
|
Internet players.
|
||||||
|
|
||||||
|
The data directory contains the server identity and moderation state. Keep it
|
||||||
|
persistent and back it up; replacing it changes the server fingerprint shown
|
||||||
|
to returning players.
|
||||||
|
|
||||||
|
Configuration is applied in this order: config file, environment variables,
|
||||||
|
then command-line overrides. Supported command-line options are `--name`,
|
||||||
|
`--bind`, `--port`, `--max-players`, `--data-dir`, `--discovery-url`,
|
||||||
|
`--public`, and `--private`. Value options use `--option=value`. Keep the first
|
||||||
|
standalone `--` shown above; it separates Godot engine flags from server flags.
|
||||||
|
|
||||||
|
Public listing requires the discovery URL and a publicly reachable ENet UDP
|
||||||
|
port. Discovery makes a server findable but does not relay gameplay traffic.
|
||||||
|
|
||||||
|
For a systemd installation, create a dedicated `netfishing` system user, place
|
||||||
|
the two staged build files in `/opt/netfishing-server`, install the sample
|
||||||
|
configuration and environment files under `/etc`, and copy
|
||||||
|
`systemd/netfishing-server.service` to the system unit directory. The service
|
||||||
|
expects `/var/lib/netfishing-server` to be writable by that user.
|
||||||
|
|
||||||
|
## Run with Docker Compose
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./scripts/stage-build.sh ../netfishing/builds/v0.6.4-alpha/server-linux-x86_64
|
||||||
|
docker compose build
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Set values such as `NETFISHING_SERVER_NAME`, `NETFISHING_SERVER_PORT`,
|
||||||
|
`NETFISHING_SERVER_MAX_PLAYERS`, and `NETFISHING_SERVER_PUBLIC` in a local
|
||||||
|
`.env` file. The Compose service runs without Linux capabilities, uses a
|
||||||
|
read-only root filesystem, and stores persistent state in a named volume.
|
||||||
|
|
||||||
|
## Steam distribution
|
||||||
|
|
||||||
|
Publish the server as a separate Steam Tool AppID/depot linked to the base
|
||||||
|
game. Replace the placeholders in copies of the files under `steam/`, then use
|
||||||
|
SteamCMD to upload the staged `dist/` directory. Keep the example files free of
|
||||||
|
private Steam credentials.
|
||||||
27
compose.yaml
Normal file
27
compose.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
services:
|
||||||
|
netfishing-server:
|
||||||
|
build: .
|
||||||
|
restart: unless-stopped
|
||||||
|
init: true
|
||||||
|
read_only: true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
ports:
|
||||||
|
- "${NETFISHING_SERVER_PORT:-7777}:${NETFISHING_SERVER_PORT:-7777}/udp"
|
||||||
|
environment:
|
||||||
|
NETFISHING_SERVER_NAME: "${NETFISHING_SERVER_NAME:-NETfishing Dedicated Server}"
|
||||||
|
NETFISHING_SERVER_BIND: "*"
|
||||||
|
NETFISHING_SERVER_PORT: "${NETFISHING_SERVER_PORT:-7777}"
|
||||||
|
NETFISHING_SERVER_MAX_PLAYERS: "${NETFISHING_SERVER_MAX_PLAYERS:-8}"
|
||||||
|
NETFISHING_SERVER_PUBLIC: "${NETFISHING_SERVER_PUBLIC:-false}"
|
||||||
|
NETFISHING_DISCOVERY_URL: "${NETFISHING_DISCOVERY_URL:-https://discovery.netfishing.org}"
|
||||||
|
NETFISHING_DATA_DIR: /var/lib/netfishing-server
|
||||||
|
volumes:
|
||||||
|
- netfishing-server-data:/var/lib/netfishing-server
|
||||||
|
tmpfs:
|
||||||
|
- /tmp:rw,noexec,nosuid,size=64m
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
netfishing-server-data:
|
||||||
7
config/netfishing-server.env.example
Normal file
7
config/netfishing-server.env.example
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
NETFISHING_SERVER_NAME="NETfishing Dedicated Server"
|
||||||
|
NETFISHING_SERVER_BIND=*
|
||||||
|
NETFISHING_SERVER_PORT=7777
|
||||||
|
NETFISHING_SERVER_MAX_PLAYERS=8
|
||||||
|
NETFISHING_SERVER_PUBLIC=false
|
||||||
|
NETFISHING_DISCOVERY_URL=https://discovery.netfishing.org
|
||||||
|
NETFISHING_DATA_DIR=/var/lib/netfishing-server
|
||||||
10
config/server.cfg.example
Normal file
10
config/server.cfg.example
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[server]
|
||||||
|
name="NETfishing Dedicated Server"
|
||||||
|
bind_address="*"
|
||||||
|
port=7777
|
||||||
|
max_players=8
|
||||||
|
public=false
|
||||||
|
data_directory="/var/lib/netfishing-server"
|
||||||
|
|
||||||
|
[discovery]
|
||||||
|
url="https://discovery.netfishing.org"
|
||||||
1
dist/.gitkeep
vendored
Normal file
1
dist/.gitkeep
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
40
scripts/package-native.sh
Executable file
40
scripts/package-native.sh
Executable file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ $# -ne 1 || -z "$1" ]]; then
|
||||||
|
echo "Usage: $0 VERSION" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
version="$1"
|
||||||
|
repository_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
dist_dir="${repository_dir}/dist"
|
||||||
|
packages_dir="${repository_dir}/packages"
|
||||||
|
package_name="netfishing-dedicated-server-${version}-linux-x86_64"
|
||||||
|
staging_dir="$(mktemp -d)"
|
||||||
|
trap 'rm -rf -- "${staging_dir}"' EXIT
|
||||||
|
|
||||||
|
for filename in NETfishingServer.x86_64 NETfishingServer.pck; do
|
||||||
|
if [[ ! -f "${dist_dir}/${filename}" ]]; then
|
||||||
|
echo "Run scripts/stage-build.sh before packaging." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
install -d "${staging_dir}/${package_name}"
|
||||||
|
install -m 0755 "${dist_dir}/NETfishingServer.x86_64" \
|
||||||
|
"${staging_dir}/${package_name}/NETfishingServer.x86_64"
|
||||||
|
install -m 0644 "${dist_dir}/NETfishingServer.pck" \
|
||||||
|
"${staging_dir}/${package_name}/NETfishingServer.pck"
|
||||||
|
install -m 0644 "${repository_dir}/config/server.cfg.example" \
|
||||||
|
"${staging_dir}/${package_name}/server.cfg"
|
||||||
|
install -m 0644 "${repository_dir}/README.md" \
|
||||||
|
"${staging_dir}/${package_name}/README.md"
|
||||||
|
|
||||||
|
mkdir -p -- "${packages_dir}"
|
||||||
|
archive="${packages_dir}/${package_name}.tar.gz"
|
||||||
|
tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner \
|
||||||
|
-C "${staging_dir}" -czf "${archive}" "${package_name}"
|
||||||
|
cd -- "${packages_dir}"
|
||||||
|
sha256sum "${package_name}.tar.gz" > "${package_name}.tar.gz.sha256"
|
||||||
|
echo "Created ${archive}"
|
||||||
27
scripts/stage-build.sh
Executable file
27
scripts/stage-build.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
echo "Usage: $0 /path/to/server-linux-x86_64" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
source_dir="${1%/}"
|
||||||
|
repository_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
destination_dir="${repository_dir}/dist"
|
||||||
|
|
||||||
|
for filename in NETfishingServer.x86_64 NETfishingServer.pck; do
|
||||||
|
if [[ ! -f "${source_dir}/${filename}" ]]; then
|
||||||
|
echo "Missing ${source_dir}/${filename}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
install -m 0755 "${source_dir}/NETfishingServer.x86_64" \
|
||||||
|
"${destination_dir}/NETfishingServer.x86_64"
|
||||||
|
install -m 0644 "${source_dir}/NETfishingServer.pck" \
|
||||||
|
"${destination_dir}/NETfishingServer.pck"
|
||||||
|
|
||||||
|
cd -- "${destination_dir}"
|
||||||
|
sha256sum NETfishingServer.x86_64 NETfishingServer.pck > SHA256SUMS
|
||||||
|
echo "Staged dedicated server build in ${destination_dir}"
|
||||||
14
steam/app_build.vdf.example
Normal file
14
steam/app_build.vdf.example
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
"appbuild"
|
||||||
|
{
|
||||||
|
"appid" "<SERVER_TOOL_APP_ID>"
|
||||||
|
"desc" "NETfishing Dedicated Server"
|
||||||
|
"buildoutput" "output"
|
||||||
|
"contentroot" "../dist"
|
||||||
|
"setlive" ""
|
||||||
|
"preview" "0"
|
||||||
|
"local" ""
|
||||||
|
"depots"
|
||||||
|
{
|
||||||
|
"<SERVER_DEPOT_ID>" "depot_build.vdf"
|
||||||
|
}
|
||||||
|
}
|
||||||
11
steam/depot_build.vdf.example
Normal file
11
steam/depot_build.vdf.example
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
"DepotBuildConfig"
|
||||||
|
{
|
||||||
|
"DepotID" "<SERVER_DEPOT_ID>"
|
||||||
|
"ContentRoot" "../dist"
|
||||||
|
"FileMapping"
|
||||||
|
{
|
||||||
|
"LocalPath" "*"
|
||||||
|
"DepotPath" "."
|
||||||
|
"recursive" "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
24
systemd/netfishing-server.service
Normal file
24
systemd/netfishing-server.service
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
[Unit]
|
||||||
|
Description=NETfishing Dedicated Server
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=netfishing
|
||||||
|
Group=netfishing
|
||||||
|
WorkingDirectory=/opt/netfishing-server
|
||||||
|
EnvironmentFile=-/etc/netfishing-server.env
|
||||||
|
ExecStart=/opt/netfishing-server/NETfishingServer.x86_64 -- --config=/etc/netfishing-server.cfg
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
ReadWritePaths=/var/lib/netfishing-server
|
||||||
|
CapabilityBoundingSet=
|
||||||
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Loading…
Add table
Add a link
Reference in a new issue