├── .gitignore ├── Config ├── .create └── DefaultConfig.json ├── Dockerfile ├── Logs └── .create ├── README.md ├── build.sh ├── docker-compose.sample.yaml ├── k8s ├── resonite-config.sample.yaml └── resonite-pod.sample.yaml ├── run.sh └── src ├── setup_resonite.sh └── start_resonite.sh /.gitignore: -------------------------------------------------------------------------------- 1 | Config/Config.json 2 | Logs/*.log 3 | k8s/resonite-config.yaml 4 | docker-compose.yaml 5 | -------------------------------------------------------------------------------- /Config/.create: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shadowpanther/resonite-headless/73f97a8010e4f8fa94d6cefbbe9e6f83536c63ce/Config/.create -------------------------------------------------------------------------------- /Config/DefaultConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/Yellow-Dog-Man/JSONSchemas/main/schemas/HeadlessConfig.schema.json", 3 | "comment": "DO NOT EDIT THIS FILE! Your changes will be lost. Copy it over and create a new file called Config.json", 4 | "universeId": null, 5 | "tickRate": 60.0, 6 | "maxConcurrentAssetTransfers": 4, 7 | "usernameOverride": null, 8 | "loginCredential": null, 9 | "loginPassword": null, 10 | "startWorlds": [ 11 | { 12 | "isEnabled": true, 13 | "sessionName": null, 14 | "customSessionId": null, 15 | "description": null, 16 | "maxUsers": 16, 17 | "accessLevel": "Anyone", 18 | "useCustomJoinVerifier": false, 19 | "hideFromPublicListing": null, 20 | "tags": null, 21 | "mobileFriendly": false, 22 | "loadWorldURL": null, 23 | "loadWorldPresetName": "Grid", 24 | "overrideCorrespondingWorldId": null, 25 | "forcePort": null, 26 | "keepOriginalRoles": false, 27 | "defaultUserRoles": null, 28 | "roleCloudVariable": null, 29 | "allowUserCloudVariable": null, 30 | "denyUserCloudVariable": null, 31 | "requiredUserJoinCloudVariable": null, 32 | "requiredUserJoinCloudVariableDenyMessage": null, 33 | "awayKickMinutes": -1.0, 34 | "parentSessionIds": null, 35 | "autoInviteUsernames": null, 36 | "autoInviteMessage": null, 37 | "saveAsOwner": null, 38 | "autoRecover": true, 39 | "idleRestartInterval": -1.0, 40 | "forcedRestartInterval": -1.0, 41 | "saveOnExit": false, 42 | "autosaveInterval": -1.0, 43 | "autoSleep": true 44 | } 45 | ], 46 | "dataFolder": null, 47 | "cacheFolder": null, 48 | "logsFolder": null, 49 | "allowedUrlHosts": null, 50 | "autoSpawnItems": null 51 | } 52 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:oracular 2 | 3 | LABEL name=resonite-headless org.opencontainers.image.authors="panther.ru@gmail.com" 4 | 5 | ENV STEAMAPPID=2519830 \ 6 | STEAMAPP=resonite \ 7 | STEAMCMDURL="https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" \ 8 | STEAMCMDDIR=/opt/steamcmd \ 9 | STEAMBETA=__CHANGEME__ \ 10 | STEAMBETAPASSWORD=__CHANGEME__ \ 11 | STEAMLOGIN=__CHANGEME__ \ 12 | USER=2000 \ 13 | HOMEDIR=/home/steam 14 | ENV STEAMAPPDIR="${HOMEDIR}/${STEAMAPP}-headless" 15 | 16 | # Prepare the basic environment 17 | RUN set -x && \ 18 | apt -y update && \ 19 | apt -y upgrade && \ 20 | apt -y install curl lib32gcc-s1 libopus-dev libopus0 opus-tools libc6-dev libfreetype6 dotnet-runtime-9.0 && \ 21 | rm -rf /var/lib/{apt,dpkg,cache} 22 | 23 | # Add locales 24 | RUN apt-get update && \ 25 | DEBIAN_FRONTEND=noninteractive apt-get install -y locales && \ 26 | sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ 27 | sed -i -e 's/# en_GB.UTF-8 UTF-8/en_GB.UTF-8 UTF-8/' /etc/locale.gen && \ 28 | dpkg-reconfigure --frontend=noninteractive locales && \ 29 | update-locale LANG=en_US.UTF-8 && \ 30 | update-locale LANG=en_GB.UTF-8 && \ 31 | rm -rf /var/lib/{apt,dpkg,cache} 32 | ENV LANG=en_GB.UTF-8 33 | 34 | # Fix the LetsEncrypt CA cert (is this still needed?) 35 | #RUN sed -i 's#mozilla/DST_Root_CA_X3.crt#!mozilla/DST_Root_CA_X3.crt#' /etc/ca-certificates.conf && update-ca-certificates 36 | 37 | # Create user, install SteamCMD 38 | RUN groupadd --gid ${USER} steam && \ 39 | useradd --home-dir ${HOMEDIR} \ 40 | --create-home \ 41 | --shell /bin/bash \ 42 | --comment "" \ 43 | --gid ${USER} \ 44 | --uid ${USER} \ 45 | steam && \ 46 | mkdir -p ${STEAMCMDDIR} ${STEAMAPPDIR} /Config /Logs /Scripts && \ 47 | cd ${STEAMCMDDIR} && \ 48 | curl -sqL ${STEAMCMDURL} | tar zxfv - && \ 49 | chown -R ${USER}:${USER} ${STEAMCMDDIR} ${STEAMAPPDIR} /Config /Logs 50 | 51 | COPY --chown=${USER}:${USER} --chmod=755 ./src/setup_resonite.sh ./src/start_resonite.sh /Scripts/ 52 | 53 | #RUN chown -R ${USER}:${USER} /Scripts/setup_resonite.sh /Scripts/start_resonite.sh && \ 54 | # chmod +x /Scripts/setup_resonite.sh /Scripts/start_resonite.sh 55 | 56 | # Switch to user 57 | USER ${USER} 58 | 59 | WORKDIR ${STEAMAPPDIR} 60 | 61 | VOLUME ["${STEAMAPPDIR}", "/Config", "/Logs"] 62 | 63 | STOPSIGNAL SIGINT 64 | 65 | ENTRYPOINT ["/Scripts/setup_resonite.sh"] 66 | CMD ["/Scripts/start_resonite.sh"] 67 | -------------------------------------------------------------------------------- /Logs/.create: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shadowpanther/resonite-headless/73f97a8010e4f8fa94d6cefbbe9e6f83536c63ce/Logs/.create -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # resonite-headless 2 | Docker image of a Resonite headless server 3 | 4 | Send the command `/headlessCode` to **Resonite** bot (the one that sends you messages about Patreon and storage) in Resonite to get the beta key. 5 | 6 | Steam login is required to download the client. You'll have to disable SteamGuard, so probably create a separate Steam account for your headless server. 7 | 8 | Sample docker-compose: 9 | ``` 10 | version: "3.3" 11 | services: 12 | resonite: 13 | image: shadowpanther/resonite-headless:latest 14 | container_name: resonite-headless 15 | tty: true 16 | stdin_open: true 17 | environment: 18 | STEAMBETA: headless 19 | STEAMBETAPASSWORD: ask-bot-for-code 20 | STEAMLOGIN: "your_steam_login your_steam_password" 21 | volumes: 22 | - resonite-data:/home/steam/resonite-headless 23 | - ./Config:/Config:ro 24 | - ./Logs:/Logs:rw 25 | - /etc/localtime:/etc/localtime:ro 26 | restart: unless-stopped 27 | volumes: 28 | resonite-data: 29 | ``` 30 | 31 | Place your `Config.json` into `Config` folder. Logs would be stored in `Logs` folder. 32 | 33 | You probably need to set `vm.max_map_count=262144` by doing `echo "vm.max_map_count=262144" >> /etc/sysctl.conf` lest you end up with frequent GC crashes. 34 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | docker buildx build -t shadowpanther/resonite-headless . 4 | -------------------------------------------------------------------------------- /docker-compose.sample.yaml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | services: 3 | resonite: 4 | image: shadowpanther/resonite-headless:latest 5 | container_name: resonite-headless 6 | tty: true 7 | stdin_open: true 8 | environment: 9 | STEAMBETA: headless 10 | STEAMBETAPASSWORD: CHANGEME 11 | STEAMLOGIN: "USER PASSWORD" 12 | volumes: 13 | - resonite-data:/home/steam/resonite-headless 14 | - ./Config:/Config:ro 15 | - ./Logs:/Logs 16 | - /etc/localtime:/etc/localtime:ro 17 | restart: unless-stopped 18 | volumes: 19 | resonite-data: 20 | -------------------------------------------------------------------------------- /k8s/resonite-config.sample.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | Config.json: | 4 | { 5 | "comment": "This is the main config", 6 | "tickRate": 60.0, 7 | "maxConcurrentAssetTransfers": 16, 8 | "usernameOverride": null, 9 | "loginCredential": "yourHeadlessResoniteAccount", 10 | "loginPassword": "yourPassword", 11 | "startWorlds": [ 12 | { 13 | "isEnabled": true, 14 | "sessionName": "Sample Session", 15 | "customSessionId": "S-U-YourHeadless:Sample_Session", 16 | "description": "This is a sample session", 17 | "maxUsers": 16, 18 | "accessLevel": "Anyone", 19 | "hideFromPublicListing": false, 20 | "tags": [ 21 | "sample", 22 | "session" 23 | ], 24 | "mobileFriendly": false, 25 | "loadWorldURL": "resrec://GoesHere", 26 | "saveAsOwner": null, 27 | "loadWorldPresetName": null, 28 | "forcePort": null, 29 | "keepOriginalRoles": false, 30 | "defaultUserRoles": { 31 | "Your Main User": "Admin", 32 | "Your Friend": "Admin" 33 | }, 34 | "autoInviteUsernames": null, 35 | "autoInviteMessage": null, 36 | "autoRecover": true, 37 | "idleRestartInterval": 900.0, 38 | "forcedRestartInterval": -1.0, 39 | "saveOnExit": false, 40 | "autosaveInterval": -1.0, 41 | "awayKickMinutes": 1.0, 42 | "autoSleep": true 43 | } 44 | ], 45 | "dataFolder": null, 46 | "cacheFolder": null, 47 | "allowedUrlHosts": [ 48 | "api.prismteam.tk" 49 | ], 50 | "autoSpawnItems": null, 51 | "metamovieRoles": null 52 | } 53 | STEAMBETA: headless 54 | STEAMBETAPASSWORD: getThisFromResoniteBot 55 | STEAMLOGIN: your_steam_account_name andPassword 56 | kind: ConfigMap 57 | -------------------------------------------------------------------------------- /k8s/resonite-pod.sample.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: resonite-pod 5 | spec: 6 | containers: 7 | - name: resonite-headless 8 | image: shadowpanther/resonite-headless 9 | env: 10 | - name: STEAMBETA 11 | valueFrom: 12 | configMapKeyRef: 13 | name: resonite-config 14 | key: STEAMBETA 15 | - name: STEAMBETAPASSWORD 16 | valueFrom: 17 | configMapKeyRef: 18 | name: resonite-config 19 | key: STEAMBETAPASSWORD 20 | - name: STEAMLOGIN 21 | valueFrom: 22 | configMapKeyRef: 23 | name: resonite-config 24 | key: STEAMLOGIN 25 | volumeMounts: 26 | - name: config-vol 27 | mountPath: /Config 28 | readOnly: true 29 | - name: logs-vol 30 | mountPath: /Logs 31 | volumes: 32 | - name: config-vol 33 | configMap: 34 | name: resonite-config 35 | items: 36 | - key: Config.json 37 | path: Config.json 38 | - name: logs-vol 39 | emptyDir: {} 40 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! -f ./Config/Config.json ]; then 4 | cp ./Config/DefaultConfig.json ./Config/Config.json 5 | echo "Created a Congig.json in the ./Config folder for you. Please edit it accordingly." 6 | elif [ ! -f ./docker-compose.yaml ]; then 7 | cp ./docker-compose.sample.yaml ./docker-compose.yaml 8 | echo "Created a docker-compose.yaml in the current folder for you. Please fill in the needed parameters." 9 | else 10 | chmod a+w Logs 11 | docker-compose pull 12 | docker-compose up -d 13 | fi 14 | -------------------------------------------------------------------------------- /src/setup_resonite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | bash "${STEAMCMDDIR}/steamcmd.sh" \ 4 | +@sSteamCmdForcePlatformType windows \ 5 | +force_install_dir ${STEAMAPPDIR} \ 6 | +login ${STEAMLOGIN} \ 7 | +app_license_request ${STEAMAPPID} \ 8 | +app_update ${STEAMAPPID} -beta ${STEAMBETA} -betapassword ${STEAMBETAPASSWORD} validate \ 9 | +quit 10 | find ${STEAMAPPDIR}/Data/Assets -type f -atime +7 -delete 11 | find ${STEAMAPPDIR}/Data/Cache -type f -atime +7 -delete 12 | find /Logs -type f -name *.log -atime +30 -delete 13 | mkdir -p Headless/Migrations 14 | exec $* 15 | -------------------------------------------------------------------------------- /src/start_resonite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -f ${STEAMAPPDIR}/Headless/Resonite.dll ]; then 4 | echo 'Resonite.dll is in the new (permanent) location, running...' 5 | exec dotnet ${STEAMAPPDIR}/Headless/Resonite.dll -HeadlessConfig /Config/Config.json -Logs /Logs 6 | else 7 | echo 'Resonite.dll not found, weird!' 8 | sleep 10 9 | fi 10 | 11 | --------------------------------------------------------------------------------