1 Commits
main ... main

Author SHA1 Message Date
Liam A Edwards
e26ebd1ebf Update README.md 2026-01-01 17:57:54 +00:00
6 changed files with 133 additions and 227 deletions

View File

@@ -1,93 +1,48 @@
#
name: Build SS14 Watchdog Server
name: Create and publish a Docker image
# Configures this workflow to run every time a change is pushed to the branch called `release`.
on:
push:
branches: ['main']
workflow_dispatch:
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
REGISTRY: git.wylab.me
IMAGE_NAME: wylab/ws14-docker-linux-server
BUILDKIT_PROGRESS: plain
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
build-arm64:
runs-on: [self-hosted, macos-arm64]
timeout-minutes: 60
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
#
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the container registry
uses: docker/login-action@v3
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME || github.actor }}
password: ${{ secrets.REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
- name: Build and push Docker image (arm64)
uses: docker/build-push-action@v5
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
provenance: false
platforms: linux/arm64
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-arm64
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-arm64,mode=max
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-arm64
build-amd64:
runs-on: [self-hosted, linux-amd64]
timeout-minutes: 60
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME || github.actor }}
password: ${{ secrets.REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
- name: Build and push Docker image (amd64)
uses: docker/build-push-action@v5
with:
context: .
provenance: false
platforms: linux/amd64
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-amd64
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-amd64,mode=max
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-amd64
create-manifest:
needs: [build-amd64, build-arm64]
runs-on: [self-hosted]
steps:
- name: Log in to the container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME || github.actor }}
password: ${{ secrets.REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
- name: Create and push multi-arch manifest
run: |
docker manifest create --amend ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-arm64
docker manifest push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -1,40 +1,24 @@
# syntax=docker/dockerfile:1.7
#
# SS14 Watchdog Docker Image (based on LiamAEdwards/SS14-Docker-Linux-Server)
# Downloads game server from CDN and builds SS14.Watchdog
#
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
ARG TARGETPLATFORM
# Update and install necessary tools
RUN apt-get -y update && \
apt-get -y install curl unzip wget git jq
# Determine platform RID based on Docker TARGETPLATFORM
RUN if [ "${TARGETPLATFORM:-linux/amd64}" = "linux/arm64" ]; then \
echo "linux-arm64" > /tmp/platform_rid; \
else \
echo "linux-x64" > /tmp/platform_rid; \
fi && \
echo "Building for platform: $(cat /tmp/platform_rid)"
# Download and extract SS14 server from WYLAB CDN
RUN PLATFORM_RID=$(cat /tmp/platform_rid) && \
SERVER_URL=$(curl -sL https://cdn.wylab.me/fork/wylab/manifest | \
jq -r ".builds | to_entries | sort_by(.value.time) | last | .value.server.\"${PLATFORM_RID}\".url") && \
# Download and extract SS14 server (latest version compatible with .NET 9)
# Using manifest to get current server build
RUN SERVER_URL=$(curl -sL https://central.spacestation14.io/builds/wizards/manifest.json | \
jq -r '.builds | to_entries | sort_by(.value.time) | last | .value.server."linux-x64".url') && \
echo "Downloading server from: $SERVER_URL" && \
wget -O SS14.Server.zip "$SERVER_URL" && \
unzip SS14.Server.zip -d /ss14-default/
wget -O SS14.Server_linux-x64.zip "$SERVER_URL" && \
unzip SS14.Server_linux-x64.zip -d /ss14-default/
# Download and build Watchdog
RUN PLATFORM_RID=$(cat /tmp/platform_rid) && \
wget https://github.com/space-wizards/SS14.Watchdog/archive/refs/heads/master.zip -O Watchdog.zip && \
RUN wget https://github.com/space-wizards/SS14.Watchdog/archive/refs/heads/master.zip -O Watchdog.zip && \
unzip Watchdog.zip -d Watchdog && \
cd Watchdog/SS14.Watchdog-master && \
dotnet publish SS14.Watchdog -c Release -r "${PLATFORM_RID}" --no-self-contained -o /ss14-default/publish
cd Watchdog/SS14* && \
dotnet publish -c Release -r linux-x64 --no-self-contained && \
cp -r SS14.Watchdog/bin/Release/net9.0/linux-x64/publish /ss14-default
# Server stage
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS server
@@ -43,8 +27,7 @@ FROM mcr.microsoft.com/dotnet/sdk:9.0 AS server
COPY --from=build /ss14-default /ss14-default
# Install necessary tools
RUN apt-get -y update && apt-get -y install unzip && \
rm -rf /var/lib/apt/lists/*
RUN apt-get -y update && apt-get -y install unzip
# Expose necessary ports
EXPOSE 1212/tcp
@@ -55,8 +38,8 @@ EXPOSE 8080/tcp
VOLUME [ "/ss14" ]
# Add configurations
COPY appsettings.yml /ss14-default/publish/appsettings.yml
COPY server_config.toml /ss14-default/publish/server_config.toml
ADD appsettings.yml /ss14-default/publish/appsettings.yml
ADD server_config.toml /ss14-default/publish/server_config.toml
COPY start.sh /start.sh
RUN chmod +x /start.sh

128
README.md
View File

@@ -1,4 +1,4 @@
<h1 align="center">SS14-Docker-Linux-Server 🚀</h1>
<h1 align="center">SS14-Docker-Linux-Server </h1>
<p align="center">
Containerized deployment of the <a href="https://spacestation14.io/">Space Station 14</a> server on Linux.
@@ -13,110 +13,58 @@
### Overview
This project is for those who prefer containerized solutions. It's based on the [official documentation](https://docs.spacestation14.com/en/general-development/setup/server-hosting-tutorial.html) but wraps the [wylab-station-14](https://git.wylab.me/wylab/wylab-station-14) fork in a Docker image that is built from source during the Docker build.
This project is for those who prefer containerized solutions. It's based on the [official documentation](https://docs.spacestation14.com/en/general-development/setup/server-hosting-tutorial.html) but wrapped up in a Docker container for convenience.
### Building the Image
### Quick Start
1. **Clone this repository**
1. **Clone the repository**
```bash
git clone https://git.wylab.me/wylab/WS14-Docker-Linux-Server.git
cd WS14-Docker-Linux-Server
git clone https://github.com/LiamAEdwards/SS14-Docker-Linux-Server.git && cd SS14-Docker-Linux-Server
```
2. **Configure your server defaults**
2. **Configure Your Server**
Edit `appsettings.yml` and `server_config.toml` with the values you want baked into the image. These files will be copied into `/ss14-default/publish` on first run.
Edit the `appsettings.yml` & `server_config.toml` to match your desired configuration.
3. **Build the Docker image**
3. **Run the Server**
Using Docker directly:
```bash
docker build \
--build-arg SOURCE_REPO=https://git.wylab.me/wylab/wylab-station-14.git \
--build-arg SOURCE_REF=master \
--build-arg TARGET_PLATFORM=auto \
-t git.wylab.me/wylab/WS14-Docker-Linux-Server:local .
docker run -d \
-p 1212:1212/tcp \
-p 1212:1212/udp \
-p 5000:5000/tcp \
-p 5000:5000/udp \
-v /path/on/host:/ss14 \
ghcr.io/liamaedwards/ss14-docker-linux-server:main
```
- `SOURCE_REPO` Git URL of the content repo to compile (defaults to the wylab fork).
- `SOURCE_REF` Branch, tag, or commit to check out (defaults to `master`).
- `TARGET_PLATFORM` Runtime identifier passed to the packaging tool. Use `auto` (default) to match the Docker target platform automatically, or override with `linux-x64`, `linux-arm64`, or `linux-arm` to force an architecture.
Or using Docker Compose:
If you are building on one architecture and running on another (for example, building on x86 and deploying to an ARM board), build with an explicit platform to avoid `exec format error`:
First, create a `docker-compose.yml` file:
```yaml
version: '3'
services:
ss14-server:
image: ghcr.io/liamaedwards/ss14-docker-linux-server:main
ports:
- "1212:1212/tcp"
- "1212:1212/udp"
- "5000:5000/tcp"
- "5000:5000/udp"
volumes:
- /path/on/host:/ss14
restart: always
```
Then, run with:
```bash
docker buildx build \
--platform linux/arm64 \
--build-arg TARGET_PLATFORM=linux-arm64 \
-t git.wylab.me/wylab/WS14-Docker-Linux-Server:arm64 .
docker-compose up -d
```
The build container clones the selected ref, runs `RUN_THIS.py --quiet` to fetch submodules, and executes `dotnet run --project Content.Packaging server` to generate a release zip that is baked into the final layer.
### Running the Server
```bash
docker run -d \
-p 1212:1212/tcp \
-p 1212:1212/udp \
-p 5000:5000/tcp \
-p 5000:5000/udp \
-v /path/on/host:/ss14 \
--name wylab-ss14 \
git.wylab.me/wylab/WS14-Docker-Linux-Server:latest
```
On first start the container copies `/ss14-default` into your mounted volume (if empty) so you can edit configs or upload new builds persistently.
You can still wrap the container in Docker Compose if desired:
```yaml
version: '3.9'
services:
ss14-server:
image: git.wylab.me/wylab/WS14-Docker-Linux-Server:latest
ports:
- "1212:1212/tcp"
- "1212:1212/udp"
- "5000:5000/tcp"
- "5000:5000/udp"
volumes:
- /path/on/host:/ss14
restart: unless-stopped
```
### CI/CD
Two workflows keep this image up to date:
1. **`wylab-station-14/.github/workflows/publish.yml`**
- Triggered on pushes to `master`, manual dispatch, or nightly cron.
- Checks `https://cdn.wylab.me/fork/wylab/manifest` first; if the current commit already exists on the CDN it exits early.
- Uses `actions/cache` to persist `~/.nuget/packages` and `RobustToolbox/bin`, so repeated builds reuse restored packages/engine binaries when the inputs havent changed.
- Otherwise builds the server/client packages via `Content.Packaging`, uploads them via `Tools/publish_multi_request.py`, and fires a `repository_dispatch` event (`event_type: ss14-package-ready`) to this repo.
Required secrets in the wylab-station-14 repo:
`PUBLISH_TOKEN`, `DOCKER_TRIGGER_TOKEN`, and (if used) `SECRETS_PRIVATE_KEY`.
To send the dispatch, add `DOCKER_TRIGGER_TOKEN` (a PAT with repo access).
2. **`WS14-Docker-Linux-Server/.github/workflows/main.yml`**
- Triggered on pushes here, manual dispatch, or the `ss14-package-ready` event.
- Resolves the target wylab commit (uses the payload commit if provided).
- Logs into `git.wylab.me` and runs `docker manifest inspect` before building; if an image tagged with that commit already exists it skips the build.
- Otherwise builds the Docker image with `SOURCE_REF=<commit>` and pushes:
- `git.wylab.me/wylab/ws14-docker-linux-server:latest`
- `git.wylab.me/wylab/ws14-docker-linux-server:<docker repo commit>`
- `git.wylab.me/wylab/ws14-docker-linux-server:<wylab commit>`
Required secrets here: `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` (credentials for `git.wylab.me`).
After the build finishes, Unraid (or any host) can pull:
```
git.wylab.me/wylab/ws14-docker-linux-server:latest
```
Use that string in Unraids “Repository” field and map `/ss14` to persistent storage.
---

View File

@@ -25,25 +25,35 @@ Serilog:
AllowedHosts: "*"
# Force Kestrel to bind to 0.0.0.0 (IPv4) instead of [::] (IPv6)
# This fixes the Host header issue with http://[::]:8080
Urls: "http://0.0.0.0:8080"
# API URL your watchdog is accessible from.
# This NEEDS to be reachable by the game server.
# If you don't want the watchdog to be public,
# do `http://localhost:8080/` here.
#BaseUrl: https://your.domain.com/watchdog/
BaseUrl: http://localhost:8080/
Servers:
Instances:
wylab:
Name: "WyLab Station 14"
# ID (and directory) of your server.
test:
# Name of the server
Name: "Test Instance"
# Token to control the instance remotely
ApiToken: "foobar"
# Port OF THE GAME SERVER.
# This should match the HTTP status API
# or watchdog can't contact the server.
ApiPort: 1212
TimeoutSeconds: 120
# Override the baseUrl to use localhost
# Override the baseUrl to use localhost instead of [::]
EnvironmentVariables:
ROBUST_CVAR_watchdog__baseUrl: "http://localhost:8080/"
# Auto update from WyLab CDN
# Auto update configuration. This can be
# omitted to skip auto updates.
UpdateType: "Manifest"
Updates:
ManifestUrl: "https://cdn.wylab.me/fork/wylab/manifest"
ManifestUrl: "https://central.spacestation14.io/builds/wizards/manifest.json"

View File

@@ -34,24 +34,13 @@ bind = "*:1212"
[watchdog]
# Token must match ApiToken in appsettings.yml
token = "foobar"
# Key must match the instance key in appsettings.yml
key = "wylab"
# Key must match the instance key in appsettings.yml (e.g., "test")
key = "test"
# BaseUrl must match BaseUrl in appsettings.yml
baseUrl = "http://localhost:8080/"
[game]
hostname = "MyServer"
lobbyenabled = true
# Lobby wait in seconds before round start (default 150s)
lobbyduration = 180
defaultpreset = "secret"
fallbackpreset = "Traitor,Extended"
fallbackenabled = true
# Use built-in rotation list; edit this when you add custom pools.
map_pool = "DefaultMapPool"
map_rotation = true
# How many past rounds are remembered when picking the next map.
map_memory_depth = 8
[console]
# If this is true, people connecting from this machine (loopback)
@@ -74,18 +63,37 @@ server_url = ""
hub_urls = "https://central.spacestation14.io/hub/"
[build]
# Watchdog automatically provides build info from CDN manifest
# These are only used as fallback if watchdog doesn't provide them
# *Absolutely all of these can be supplied using a "build.json" file*
# For further information, see https://github.com/space-wizards/space-station-14/blob/master/Tools/gen_build_info.py
# The main reason you'd want to supply any of these manually is for a custom fork and if you have no tools.
[database]
# Database engine: sqlite or postgres
engine = "postgres"
# PostgreSQL connection settings
pg_host = "192.168.1.50"
pg_port = 5432
pg_database = "ss14"
pg_username = "ss14"
pg_password = "hyphar-cAqtu6-wyzfet"
# Useful to override if the existing version is bad.
# See https://github.com/space-wizards/RobustToolbox/tags for version values, remove the 'v'.
# The value listed here is almost certainly wrong - it is ONLY a demonstration of format.
# engine_version = "0.7.6"
# This one is optional, the launcher will delete other ZIPs of the same fork to save space.
# fork_id = "abacusstation"
# Automatically set if self-hosting client zip, but otherwise use this when updating client build.
# There is no required format, any change counts as a new version.
# version = "Example1"
# This is where the launcher will download the client ZIP from.
# If this isn't supplied, the server will check for a file called "Content.Client.zip",
# and will host it on the status server.
# If that isn't available, the server will attempt to find and use "../../Resources" and
# "../../bin/Content.Client" to automatically construct a client zip.
# It will then host this on the status server.
# Note that these paths do not work on "FULL_RELEASE" servers.
# FULL_RELEASE servers expect to be used with a specific "packaged" layout.
# As such, whatever script you're using to package them is expected to create the ZIP.
# download_url = "http://example.com/compass.zip"
# Build hash - this is a *capitalized* SHA256 hash of the client ZIP.
# Optional in any case and automatically set if hosting a client ZIP.
# This hash is an example only.
# build = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"
[auth]
# Authentication (accounts):

View File

@@ -1,10 +1,12 @@
#!/bin/bash
# Copy default files to volume on first run
# Check if directory is empty
if [ ! "$(ls -A /ss14)" ]; then
cp -r /ss14-default/* /ss14/
# Copy the default files
cp -R /ss14-default/* /ss14/
fi
# Run watchdog
# Start the original command
cd /ss14/publish/
exec ./SS14.Watchdog "$@"
./SS14.Watchdog "$@"