diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8574a5e..06c8318 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -6,9 +6,8 @@ on: workflow_dispatch: env: - MC_VERSION: "1.20" - VELOCITY_VERSION: 3.2.0-SNAPSHOT - WATERFALL_VERSION: "1.20" + MC_VERSION: "1.21" + VELOCITY_VERSION: 3.3.0-SNAPSHOT jobs: build: @@ -23,8 +22,8 @@ jobs: fail-fast: false matrix: include: - - name: plain - - name: waterfall + # - name: plain + - name: velocity steps: - uses: actions/checkout@v3 - name: Set up Docker Buildx @@ -48,7 +47,6 @@ jobs: cache-to: type=gha,mode=max build-args: | VELOCITY_VERSION=${{ env.VELOCITY_VERSION }} - WATERFALL_VERSION=${{ env.WATERFALL_VERSION }} tags: | ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/${{ matrix.name }}:latest ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/${{ matrix.name }}:${{ env.MC_VERSION }} diff --git a/velocity/.dockerignore b/velocity/.dockerignore new file mode 100644 index 0000000..e166442 --- /dev/null +++ b/velocity/.dockerignore @@ -0,0 +1 @@ +.gitkeep diff --git a/velocity/Dockerfile b/velocity/Dockerfile new file mode 100644 index 0000000..29ddaf0 --- /dev/null +++ b/velocity/Dockerfile @@ -0,0 +1,63 @@ +FROM docker.io/alpine:latest AS download_assets +WORKDIR /velocity + +ARG VELOCITY_VERSION=3.3.0-SNAPSHOT +ARG TARGETPLATFORM +ARG TARGETOS +ARG TARGETARCH + +RUN apk add --no-cache curl jq +COPY utils/velocity.sh /velocity/ + +# Download tools +WORKDIR /tmp +RUN wget -O packy.tar.gz https://github.com/synchthia/packy/releases/latest/download/packy_${TARGETOS}_${TARGETARCH}.tar.gz && \ + tar -xvzf ./packy.tar.gz && \ + wget -O yq https://github.com/mikefarah/yq/releases/latest/download/yq_${TARGETOS}_${TARGETARCH} && \ + chmod +x yq + +# Download velocity +WORKDIR /velocity +RUN sh /velocity/velocity.sh ${VELOCITY_VERSION} + +# --- +# --- +FROM docker.io/eclipse-temurin:21 +EXPOSE 25565 + +ENV LANG en_US.UTF-8 + +# Config +ENV ONLINE_MODE true +ENV PORT 25565 + +# Install assets +COPY --from=download_assets /tmp/packy /tmp/yq /usr/local/bin/ + +# Install velocity +COPY --from=download_assets /velocity/velocity.jar /velocity/ + +# Setup user +RUN apt-get update -qq && \ + apt-get install -y gosu && \ + apt-get clean + +# Copy Entry point +COPY entrypoint.sh launcher.sh autoconfig.sh / + +RUN addgroup --gid 1000 app && \ + useradd app --uid 1000 -g app -s /bin/bash + +# Copy basements... +COPY templates/ /app/templates/ +COPY server/ /app/server/ + +# Create internal directories +# Make symbolic link (for compatibility) +RUN mkdir -p \ + /app/plugins \ + && ln -sfnv /app/plugins /app/server/plugins + +WORKDIR /app/server + +CMD ["bash", "/entrypoint.sh"] diff --git a/velocity/autoconfig.sh b/velocity/autoconfig.sh new file mode 100644 index 0000000..aafaf2f --- /dev/null +++ b/velocity/autoconfig.sh @@ -0,0 +1,37 @@ +#!/bin/sh +set -e + +# Rewrite velocity.toml +rewriteSettings() { + local TARGET="velocity.toml" + local key=$1 + local value=$2 + + if [ "$value" == "" ]; then + [ "$DEBUG" != "" ] && echo "!! ${key} env has not provided. ignoring..." + return 0 + fi + + if [ $(echo -ne "$key" | grep "secret") ]; then + _display_value="" + else + _display_value="${value}" + fi + + if grep "${key}" "$TARGET" > /dev/null; then + echo "- Overwrite settings: (${key}: ${_display_value})" + sed -i "/^${key}\s* = / c ${key}\ =\ ${value//\\/\\\\}" "$TARGET" + else + echo "- Append settings: (${key}: ${_display_value})" + echo "${key} = ${value}" >> "$TARGET" + fi +} + +echo "=> Rewrite settings..." +# Deprecated +#rewriteSettings "forwarding-secret" "\"${VELOCITY_SECRET}\"" +echo -ne "${VELOCITY_SECRET}" > /app/server/forwarding.secret + +rewriteSettings "bind" "\"${BIND_ADDRESS:-0.0.0.0}:${PORT:-25565}\"" +rewriteSettings "show-max-players" "${MAX_PLAYERS:-5000}" +rewriteSettings "online-mode" "${ONLINE_MODE:-true}" diff --git a/velocity/entrypoint.sh b/velocity/entrypoint.sh new file mode 100644 index 0000000..cf4d93d --- /dev/null +++ b/velocity/entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +# Initialize Running user +if [ $(id -u) = 0 ]; then + # Switch provided user + if [ "${UID:+defined}" ] && [ "$UID" != 0 ] && [[ $UID != $(id -u app) ]]; then + echo ":: $UID" + usermod -u $UID app + fi + if [ "${GID:+defined}" ] && [ "$GID" != 0 ] && [[ $GID != $(id -g app) ]]; then + echo ":: $GID" + groupmod -o -g $GID app + fi +fi + +chown ${UID:-app}:${GID:-app} -R /app/ +exec gosu ${UID:-app} bash /launcher.sh start diff --git a/velocity/launcher.sh b/velocity/launcher.sh new file mode 100644 index 0000000..3ac8ed4 --- /dev/null +++ b/velocity/launcher.sh @@ -0,0 +1,58 @@ +#!/bin/bash +set -e +cd "$(dirname $0)" + +## prepare - copy files from templates +_task_prepare() { + _template() { + # Copy from templates directory + echo "Make from template" + + # plugins (symlink / keep templates plugin) + # make symlink from provided plugin + cd /app/templates/plugins + for target in $(find . -mindepth 1 -maxdepth 1 | sed -e 's/\.\///'); do + ln -sfnv ${PWD}/${target} /app/plugins/${target} + done + + # files (ex. velocity.toml) + cd /app/templates + for target in $(find . -mindepth 1 -maxdepth 1 -type f | sed -e 's/\.\///'); do + cp -TRpnv ${PWD}/${target} /app/server/${target} + done + } + + _fetch() { + if [ "$USE_PACKY" ]; then + packy fetch -s "velocity" -d /app/plugins + fi + } + + _template + + _fetch +} + +## start - start server +_task_start() { + _task_prepare + + # Auto configuration + echo "Running pre-configuration..." + cd /app/server + bash /autoconfig.sh + + echo "Starting server..." + exec java \ + -jar /velocity/velocity.jar \ + --port="${PORT:-25565}" +} + +if [ "$1" == "" ] && [ "$2" == "" ]; then + cmds="$(cat $0 | grep -E '^(_task).*\{$' | sort | tr -d '\ (){}' | tr '\n' '|' | sed -e 's/_task_//g' -e 's/|$/\n/g')" + echo -e "Usage: $0 <${cmds}> [options...]" + exit 1 +fi + +_args=$(shift 1 && echo $@) +_task_$1 $_args diff --git a/velocity/server/.gitkeep b/velocity/server/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/velocity/templates/plugins/.gitkeep b/velocity/templates/plugins/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/velocity/templates/velocity.toml b/velocity/templates/velocity.toml new file mode 100644 index 0000000..04321d8 --- /dev/null +++ b/velocity/templates/velocity.toml @@ -0,0 +1,120 @@ +# Config version. Do not change this +config-version = "2.7" +# What port should the proxy be bound to? By default, we'll bind to all addresses on port 25577. +bind = "0.0.0.0:25565" +# What should be the MOTD? This gets displayed when the player adds your server to +# their server list. Only MiniMessage format is accepted. +motd = "<#09add3>A Velocity Server" +# What should we display for the maximum number of players? (Velocity does not support a cap +# on the number of players online.) +show-max-players = 500 +# Should we authenticate players with Mojang? By default, this is on. +online-mode = true +# Should the proxy enforce the new public key security standard? By default, this is on. +force-key-authentication = true +# If client's ISP/AS sent from this proxy is different from the one from Mojang's +# authentication server, the player is kicked. This disallows some VPN and proxy +# connections but is a weak form of protection. +prevent-client-proxy-connections = true +# Should we forward IP addresses and other data to backend servers? +# Available options: +# - "none": No forwarding will be done. All players will appear to be connecting +# from the proxy and will have offline-mode UUIDs. +# - "legacy": Forward player IPs and UUIDs in a BungeeCord-compatible format. Use this +# if you run servers using Minecraft 1.12 or lower. +# - "bungeeguard": Forward player IPs and UUIDs in a format supported by the BungeeGuard +# plugin. Use this if you run servers using Minecraft 1.12 or lower, and are +# unable to implement network level firewalling (on a shared host). +# - "modern": Forward player IPs and UUIDs as part of the login process using +# Velocity's native forwarding. Only applicable for Minecraft 1.13 or higher. +player-info-forwarding-mode = "modern" +# If you are using modern or BungeeGuard IP forwarding, configure a file that contains a unique secret here. +# The file is expected to be UTF-8 encoded and not empty. +forwarding-secret-file = "forwarding.secret" +# Announce whether or not your server supports Forge. If you run a modded server, we +# suggest turning this on. +# +# If your network runs one modpack consistently, consider using ping-passthrough = "mods" +# instead for a nicer display in the server list. +announce-forge = false +# If enabled (default is false) and the proxy is in online mode, Velocity will kick +# any existing player who is online if a duplicate connection attempt is made. +kick-existing-players = true +# Should Velocity pass server list ping requests to a backend server? +# Available options: +# - "disabled": No pass-through will be done. The velocity.toml and server-icon.png +# will determine the initial server list ping response. +# - "mods": Passes only the mod list from your backend server into the response. +# The first server in your try list (or forced host) with a mod list will be +# used. If no backend servers can be contacted, Velocity won't display any +# mod information. +# - "description": Uses the description and mod list from the backend server. The first +# server in the try (or forced host) list that responds is used for the +# description and mod list. +# - "all": Uses the backend server's response as the proxy response. The Velocity +# configuration is used if no servers could be contacted. +ping-passthrough = "DISABLED" +# If not enabled (default is true) player IP addresses will be replaced by in logs +enable-player-address-logging = true + +#[servers] +# # Configure your servers here. Each key represents the server's name, and the value +# # represents the IP address of the server to connect to. +# none = "" +# lobby = "127.0.0.1:33401" +# minigames = "127.0.0.1:33402" +# # In what order we should try servers when a player logs in or is kicked from a server. +# try = ["lobby"] +# factions = "127.0.0.1:30067" +#[forced-hosts] +# "minigames.example.com" = ["minigames"] +# # Configure your forced hosts here. +# "lobby.example.com" = ["lobby"] +# "factions.example.com" = ["factions"] +[advanced] + # Specify a read timeout for connections here. The default is 30 seconds. + read-timeout = 30000 + # Enables TCP fast open support on the proxy. Requires the proxy to run on Linux. + tcp-fast-open = false + # How much compression should be done (from 0-9). The default is -1, which uses the + # default level of 6. + compression-level = -1 + # How large a Minecraft packet has to be before we compress it. Setting this to zero will + # compress all packets, and setting it to -1 will disable compression entirely. + compression-threshold = 256 + # How fast (in milliseconds) are clients allowed to connect after the last connection? By + # default, this is three seconds. Disable this by setting this to 0. + login-ratelimit = 3000 + # Specify a custom timeout for connection timeouts here. The default is five seconds. + connection-timeout = 5000 + # Enables logging of player connections when connecting to the proxy, switching servers + # and disconnecting from the proxy. + log-player-connections = true + # Enables BungeeCord plugin messaging channel support on Velocity. + bungee-plugin-message-channel = true + # Shows ping requests to the proxy from clients. + show-ping-requests = false + #Allows players transferred from other hosts via the + #Transfer packet (Minecraft 1.20.5) to be received. + accepts-transfers = false + # By default, Velocity will attempt to gracefully handle situations where the user unexpectedly + # loses connection to the server without an explicit disconnect message by attempting to fall the + # user back, except in the case of read timeouts. BungeeCord will disconnect the user instead. You + # can disable this setting to use the BungeeCord behavior. + failover-on-unexpected-server-disconnect = true + # Declares the proxy commands to 1.13+ clients. + announce-proxy-commands = true + # Enables compatibility with HAProxy's PROXY protocol. If you don't know what this is for, then + # don't enable it. + haproxy-protocol = false + # Enables the logging of commands + log-command-executions = true +[query] + # If query is enabled, on what port should the query protocol listen on? + port = 25577 + # Whether plugins should be shown in query response by default or not + show-plugins = false + # This is the map name that is reported to the query services. + map = "Velocity" + # Whether to enable responding to GameSpy 4 query responses or not. + enabled = false diff --git a/velocity/utils/velocity.sh b/velocity/utils/velocity.sh new file mode 100644 index 0000000..dabf648 --- /dev/null +++ b/velocity/utils/velocity.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +VERSION="$1" +if [ "$VERSION" == "" ]; then + echo "Usage: " + exit 1 +fi + +echo ":: Retrieve latest builds..." +BUILD=$(curl -fsSL https://papermc.io/api/v2/projects/velocity/versions/$VERSION | jq '.builds | max') + +echo "-- Detected: $BUILD" + +echo ":: Downloading Velocity..." +curl -o velocity.jar -fsSL https://papermc.io/api/v2/projects/velocity/versions/${VERSION}/builds/${BUILD}/downloads/velocity-${VERSION}-${BUILD}.jar