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