diff --git a/.editorconfig b/.editorconfig index 6583457a..c8fbb7e9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,2 +1,4 @@ [start-*] -indent_size = 2 \ No newline at end of file +indent_size = 2 +indent_style = space +end_of_line = lf diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9e436904..93c06f1e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,12 +8,14 @@ on: - openj9-nightly - adopt11 - adopt13 + - adopt14 tags: - "[0-9]+.[0-9]+.[0-9]+" - "[0-9]+.[0-9]+.[0-9]+-openj9" - "[0-9]+.[0-9]+.[0-9]+-openj9-nightly" - "[0-9]+.[0-9]+.[0-9]+-adopt11" - "[0-9]+.[0-9]+.[0-9]+-adopt13" + - "[0-9]+.[0-9]+.[0-9]+-adopt14" jobs: test: diff --git a/Dockerfile b/Dockerfile index f75b7b7c..6b59ce61 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,7 +50,7 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ - --var version=1.4.3 --var app=mc-server-runner --file {{.app}} \ + --var version=1.5.0 --var app=mc-server-runner --file {{.app}} \ --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ diff --git a/README.md b/README.md index a9b71349..0aa245fa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![Docker Pulls](https://img.shields.io/docker/pulls/itzg/minecraft-server.svg)](https://hub.docker.com/r/itzg/minecraft-server/) [![Docker Stars](https://img.shields.io/docker/stars/itzg/minecraft-server.svg?maxAge=2592000)](https://hub.docker.com/r/itzg/minecraft-server/) [![GitHub Issues](https://img.shields.io/github/issues-raw/itzg/docker-minecraft-server.svg)](https://github.com/itzg/docker-minecraft-server/issues) -[![Discord](https://img.shields.io/discord/660567679458869252)](https://discord.gg/DXfKpjB) +[![Discord](https://img.shields.io/discord/660567679458869252?label=Discord&logo=discord)](https://discord.gg/DXfKpjB) [![Build and Publish](https://github.com/itzg/docker-minecraft-server/workflows/Build%20and%20Publish/badge.svg)](https://github.com/itzg/docker-minecraft-server/actions) [![](https://img.shields.io/badge/Donate-Buy%20me%20a%20coffee-orange.svg)](https://www.buymeacoffee.com/itzg) @@ -147,6 +147,7 @@ To use a different version of Java, please use a docker tag to run your Minecraf | Tag name | Description | Linux | | -------------- | ------------------------------------------- | ------------ | | latest | **Default**. Uses Java version 8 update 212 | Alpine Linux | +| adopt14 | Uses Java version 14 latest update | Alpine Linux | | adopt13 | Uses Java version 13 latest update | Alpine Linux | | adopt11 | Uses Java version 11 latest update | Alpine Linux | | openj9 | Uses Eclipse OpenJ9 JVM | Alpine Linux | @@ -226,6 +227,10 @@ describes period of the daemonized state machine, that handles the pausing of th The [examples directory](https://github.com/itzg/docker-minecraft-server/tree/master/examples) also provides examples of deploying the [itzg/minecraft-server](https://hub.docker.com/r/itzg/minecraft-server/) Docker image. +### Amazon Web Services (AWS) Deployment + +If you're looking for a simple way to deploy this to the Amazon Web Services Cloud, check out the [Minecraft Server Deployment (CloudFormation) repository](https://github.com/vatertime/minecraft-spot-pricing). This repository contains a CloudFormation template that will get you up and running in AWS in a matter of minutes. Optionally it uses Spot Pricing so the server is very cheap, and you can easily turn it off when not in use. + ## Running a Forge Server Enable Forge server mode by adding a `-e TYPE=FORGE` to your command-line. @@ -296,7 +301,7 @@ or downloading a world with the `WORLD` option. There are two additional volumes that can be mounted; `/mods` and `/config`. Any files in either of these filesystems will be copied over to the main -`/data` filesystem before starting Minecraft. +`/data` filesystem before starting Minecraft. If you want old mods to be removed as the `/mods` content is updated, then add `-e REMOVE_OLD_MODS=TRUE`. This works well if you want to have a common set of modules in a separate location, but still have multiple worlds with different server requirements @@ -421,9 +426,9 @@ You can build spigot from source by adding `-e BUILD_FROM_SOURCE=true` If you have attached a host directory to the `/data` volume, then you can install plugins within the `plugins` subdirectory. You can also [attach a `/plugins` volume](#deploying-plugins-from-attached-volume). If you add plugins while the container is running, you'll need to restart it to pick those up. -## Running a PaperSpigot server +## Running a Paper server -Enable PaperSpigot server mode by adding a `-e TYPE=PAPER` to your command-line. +Enable Paper server mode by adding a `-e TYPE=PAPER` to your command-line. By default the container will run the latest build of [Paper server](https://papermc.io/downloads) but you can also choose to run a specific build with `-e PAPERBUILD=205`. @@ -432,7 +437,7 @@ but you can also choose to run a specific build with `-e PAPERBUILD=205`. -e TYPE=PAPER \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server -If you are hosting your own copy of PaperSpigot you can override the download URL with: +If you are hosting your own copy of Paper you can override the download URL with: - -e PAPER_DOWNLOAD_URL= @@ -482,7 +487,7 @@ A [Catserver](http://catserver.moe/) type server can be used with [Feed the Beast application](https://www.feed-the-beast.com/) modpacks are supported by using `-e TYPE=FTBA` (**note** the "A" at the end of the type). This server type will automatically take care of downloading and installing the modpack and appropriate version of Forge, so the `VERSION` does not need to be specified. ### Environment Variables: -- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by finding the modpack at [Neptune FTB](https://ftb.neptunepowered.org/) and using the "Pack ID" +- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by [finding the modpack](https://www.feed-the-beast.com/modpack) and using the "ID" displayed next to the name - `FTB_MODPACK_VERSION_ID`: optional, the numerical Id of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by drilling into the Versions tab and clicking a specific version. ### Upgrading @@ -557,29 +562,31 @@ Just change it with `SPONGEBRANCH`, such as: ## Running a Fabric Server -Enable Fabric server mode by adding a `-e TYPE=FABRIC` to your command-line. -By default the container will run the latest version of [Fabric server](http://fabricmc.net/use/) -but you can also choose to run a specific version with `-e FABRICVERSION=0.5.0.32`. +Enable [Fabric server](http://fabricmc.net/use/) mode by adding a `-e TYPE=FABRIC` to your command-line. By default, the container will run the latest version, but you can also choose to run a specific version with `VERSION`. - $ docker run -d -v /path/on/host:/data \ - -e TYPE=FABRIC -e FABRICVERSION=0.5.0.32 \ - -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server +``` +docker run -d -v /path/on/host:/data \ + -e TYPE=FABRIC \ + -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server +``` -To use a pre-downloaded Fabric installer, place it in the attached `/data` directory and -specify the name of the installer file with `FABRIC_INSTALLER`, such as: +A specific installer version can be requested using `FABRIC_INSTALLER_VERSION`. - $ docker run -d -v /path/on/host:/data ... \ - -e FABRIC_INSTALLER=fabric-installer-0.5.0.32.jar ... +To use a pre-downloaded Fabric installer, place it in a directory attached into the container, such as the `/data` volume and specify the name of the installer file with `FABRIC_INSTALLER`, such as: -To download a Fabric installer from a custom location, such as your own file repository, specify -the URL with `FABRIC_INSTALLER_URL`, such as: +``` +docker run -d -v /path/on/host:/data ... \ + -e FABRIC_INSTALLER=fabric-installer-0.5.0.32.jar ... +``` - $ docker run -d -v /path/on/host:/data ... \ - -e FORGE_INSTALLER_URL=http://HOST/fabric-installer-0.5.0.32.jar ... +To download a Fabric installer from a custom location, such as your own file repository, specify the URL with `FABRIC_INSTALLER_URL`, such as: -In both of the cases above, there is no need for the `VERSION` or `FABRICVERSION` variables. +``` +docker run -d -v /path/on/host:/data ... \ + -e FABRIC_INSTALLER_URL=http://HOST/fabric-installer-0.5.0.32.jar ... +``` -In order to add mods, you have two options. +In order to add mods, you have two options: ### Using the /data volume @@ -1104,10 +1111,14 @@ Some older versions (pre-1.14) of Spigot required `--noconsole` to be passed whe Some older servers get confused and think that the GUI interface is enabled. You can explicitly disable that by passing `-e GUI=FALSE`. +### Stop Duration + +When the container is signalled to stop, the Minecraft process wrapper will attempt to send a "stop" command via RCON or console and waits for the process to gracefully finish. By defaul it waits 60 seconds, but that duration can be configured by setting the environment variable `STOP_DURATION` to the number of seconds. + ## Running on RaspberryPi To run this image on a RaspberryPi 3 B+, 4, or newer, use the image tag itzg/minecraft-server:multiarch -> NOTE: you may need to lower the memory allocation, such as `-e MEMORY=750m` +> NOTE: you may need to lower the memory allocation, such as `-e MEMORY=750m` \ No newline at end of file diff --git a/docker-versions-create.sh b/docker-versions-create.sh index 8ed98c54..b9a4c0a9 100755 --- a/docker-versions-create.sh +++ b/docker-versions-create.sh @@ -1,7 +1,7 @@ #!/bin/bash #set -x # Use this variable to indicate a list of branches that docker hub is watching -branches_list=('openj9' 'openj9-nightly' 'adopt11' 'adopt13' 'multiarch') +branches_list=('openj9' 'openj9-nightly' 'adopt11' 'adopt13' 'adopt14' 'multiarch' 'multiarch-latest') function TrapExit { echo "Checking out back in master" diff --git a/files/autopause/autopause-fcns.sh b/files/autopause/autopause-fcns.sh index aea37a6f..5ebae93c 100644 --- a/files/autopause/autopause-fcns.sh +++ b/files/autopause/autopause-fcns.sh @@ -13,7 +13,7 @@ rcon_client_exists() { } mc_server_listening() { - [[ -n $(netstat -tln | grep "0.0.0.0:$SERVER_PORT" | grep LISTEN) ]] + [[ -n $(netstat -tln | grep -e "0.0.0.0:$SERVER_PORT" -e ":::$SERVER_PORT" | grep LISTEN) ]] } java_clients_connected() { @@ -29,7 +29,7 @@ java_clients_connected() { # remember, that the host network mode does not work with autopause because of the knockd utility for (( i=0; i<${#connections[@]}; i++ )) do - if [[ ! $(echo "${connections[$i]}" | awk '{print $5}') =~ ^\s*127\.0\.0\.1:.*$ ]] ; then + if [[ ! $(echo "${connections[$i]}" | awk '{print $5}') =~ ^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$ ]] ; then # not localhost return 0 fi diff --git a/start-deployBukkitSpigot b/start-deployBukkitSpigot index cb2309e5..37b59269 100644 --- a/start-deployBukkitSpigot +++ b/start-deployBukkitSpigot @@ -1,6 +1,7 @@ #!/bin/bash . ${SCRIPTS:-/}start-utils +isDebugging && set -x set -e @@ -58,16 +59,24 @@ function downloadSpigot { ;; esac + if [[ ${VERSION^^} = LATEST ]]; then + VANILLA_VERSION=$(restify https://getbukkit.org/download/spigot --attribute='property=og:title' | jq -r '.[0] | .attributes | select(.property == "og:title") | .content | split(" ") | .[-1]') + fi + if [[ -z $downloadUrl ]]; then downloadUrl="https://cdn.getbukkit.org/${getbukkitFlavor}/${getbukkitFlavor}-${VANILLA_VERSION}.jar" fi + setServerVar if [ -f $SERVER ]; then # tell curl to only download when newer - zarg="-z $SERVER" + curlArgs="-z $SERVER" + fi + if isDebugging; then + curlArgs="$curlArgs -v" fi log "Downloading $match from $downloadUrl ..." - curl -fsSL -o $SERVER $zarg "$downloadUrl" + curl -fsSL -o $SERVER $curlArgs "$downloadUrl" if [[ $? != 0 || $(grep -c "DOCTYPE html" $SERVER) != 0 ]]; then cat < $installMarker fi - export SERVER=$(find ${FTB_BASE_DIR} -not -name "forge*installer.jar" -name "forge*.jar") + export SERVER=$(find ${FTB_BASE_DIR} -path "*/libraries/*" -prune -type f -o -not -name "forge*installer.jar" -name "forge*.jar") if [[ -z "${SERVER}" || ! -f "${SERVER}" ]]; then log "ERROR unable to locate installed forge server jar" isDebugging && find ${FTB_BASE_DIR} -name "forge*.jar" @@ -89,7 +93,7 @@ fi # this allows saving just the world separate from the rest of the data directory if [[ $startScriptCount = 0 ]]; then srv_modpack=${FTB_SERVER_MOD} - if isURL ${srv_modpack}; then + if isURL "${srv_modpack}"; then case $srv_modpack in https://www.feed-the-beast.com/*/download|https://www.curseforge.com/minecraft/modpacks/*/download/*/file) ;; @@ -107,19 +111,19 @@ if [[ $startScriptCount = 0 ]]; then fi srv_modpack=$downloaded fi - if [[ ${srv_modpack:0:5} == "data/" ]]; then + if [[ "${srv_modpack:0:5}" == "data/" ]]; then # Prepend with "/" - srv_modpack=/${srv_modpack} + srv_modpack="/${srv_modpack}" fi - if [[ ! ${srv_modpack:0:1} == "/" ]]; then + if [[ ! "${srv_modpack:0:1}" == "/" ]]; then # If not an absolute path, assume file is in "/data" srv_modpack=/data/${srv_modpack} fi - if [[ ! -f ${srv_modpack} ]]; then + if [[ ! -f "${srv_modpack}" ]]; then log "FTB server modpack ${srv_modpack} not found." exit 2 fi - if [[ ! ${srv_modpack: -4} == ".zip" ]]; then + if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then log "FTB server modpack ${srv_modpack} is not a zip archive." log "Please set FTB_SERVER_MOD to a file with a .zip extension." exit 2 @@ -127,7 +131,7 @@ if [[ $startScriptCount = 0 ]]; then log "Unpacking FTB server modpack ${srv_modpack} ..." mkdir -p ${FTB_BASE_DIR} - unzip -o ${srv_modpack} -d ${FTB_BASE_DIR} | awk '{printf "."} END {print ""}' + unzip -o "${srv_modpack}" -d ${FTB_BASE_DIR} | awk '{printf "."} END {print ""}' fi if [[ $(find ${FTB_BASE_DIR} $entryScriptExpr | wc -l) = 0 ]]; then @@ -165,7 +169,7 @@ export FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr) export FTB_DIR=$(dirname "${FTB_SERVER_START}") chmod a+x "${FTB_SERVER_START}" -grep fml.queryResult=confirm ${FTB_SERVER_START} > /dev/null || \ +grep fml.queryResult=confirm "${FTB_SERVER_START}" > /dev/null || \ sed -i 's/-jar/-Dfml.queryResult=confirm -jar/' "${FTB_SERVER_START}" sed -i 's/.*read.*Restart now/#\0/' "${FTB_SERVER_START}" legacyJavaFixerPath="${FTB_DIR}/mods/legacyjavafixer.jar" diff --git a/start-deployFabric b/start-deployFabric index 0c748455..e933b6f7 100644 --- a/start-deployFabric +++ b/start-deployFabric @@ -7,36 +7,34 @@ export TYPE=FABRIC FABRIC_INSTALLER=${FABRIC_INSTALLER:-} FABRIC_INSTALLER_URL=${FABRIC_INSTALLER_URL:-} -FABRICVERSION=${FABRICVERSION:-LATEST} +FABRIC_INSTALLER_VERSION=${FABRIC_INSTALLER_VERSION:-${FABRICVERSION:-LATEST}} if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then log "Checking Fabric version information." - case $FABRICVERSION in + case $FABRIC_INSTALLER_VERSION in LATEST) - FABRIC_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml) - ;; - - *) - FABRIC_VERSION=$FABRICVERSION + FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml) ;; esac - FABRIC_INSTALLER="/tmp/fabric-installer-$FABRIC_VERSION.jar" + FABRIC_INSTALLER="/tmp/fabric-installer-${FABRIC_INSTALLER_VERSION}.jar" + markerVersion=$FABRIC_INSTALLER_VERSION elif [[ -z $FABRIC_INSTALLER ]]; then FABRIC_INSTALLER="/tmp/fabric-installer.jar" + markerVersion=custom elif [[ ! -e $FABRIC_INSTALLER ]]; then log "ERROR: the given Fabric installer doesn't exist : $FABRIC_INSTALLER" exit 2 fi -installMarker="/data/.fabric-installed-${VANILLA_VERSION}-${FABRIC_VERSION:-manual}" +installMarker="/data/.fabric-installed-${VANILLA_VERSION}-${markerVersion}" debug Checking for installMarker ${installMarker} if [[ ! -e $installMarker ]]; then if [[ ! -e $FABRIC_INSTALLER ]]; then if [[ -z $FABRIC_INSTALLER_URL ]]; then - log "Downloading $FABRIC_VERSION" - downloadUrl="https://maven.fabricmc.net/net/fabricmc/fabric-installer/$FABRIC_VERSION/fabric-installer-$FABRIC_VERSION.jar" + log "Downloading installer version $FABRIC_INSTALLER_VERSION" + downloadUrl="https://maven.fabricmc.net/net/fabricmc/fabric-installer/${FABRIC_INSTALLER_VERSION}/fabric-installer-${FABRIC_INSTALLER_VERSION}.jar" log "...trying $downloadUrl" curl -o $FABRIC_INSTALLER -fsSL $downloadUrl else @@ -49,9 +47,9 @@ if [[ ! -e $installMarker ]]; then fi if isDebugging; then - debug "Installing Fabric $FABRIC_VERSION using $FABRIC_INSTALLER with mcversion ${VANILLA_VERSION}" + debug "Installing Fabric ${VANILLA_VERSION} using $FABRIC_INSTALLER" else - log "Installing Fabric $FABRIC_VERSION using $FABRIC_INSTALLER" + log "Installing Fabric using $FABRIC_INSTALLER" fi tries=3 set +e diff --git a/start-deployPaper b/start-deployPaper index 1bc5839e..16e80edb 100644 --- a/start-deployPaper +++ b/start-deployPaper @@ -1,19 +1,57 @@ #!/bin/bash . ${SCRIPTS:-/}start-utils +set -o pipefail +isDebugging && set -x -: ${PAPERBUILD:=latest} -export SERVER=paper_server-${VANILLA_VERSION}-${PAPERBUILD}.jar +# PaperMC API v2 docs : https://papermc.io/api/docs/swagger-ui/index.html?configUrl=/api/openapi/swagger-config -if [ -f "$SERVER" ] && ! isTrue "$FORCE_REDOWNLOAD"; then - zarg="-z '$SERVER'" +build=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}" -H "accept: application/json" \ + | jq '.builds[-1]') +case $? in + 0) + ;; + 22) + versions=$(curl -fsSL "https://papermc.io/api/v2/projects/paper" -H "accept: application/json") + if [[ $VERSION = LATEST ]]; then + VANILLA_VERSION=$(echo "$versions" | jq -r '.versions[-1]') + log "WARN: using ${VANILLA_VERSION} since that's the latest provided by PaperMC" + # re-execute the current script with the newly computed version + exec $0 "$@" + fi + log "ERROR: ${VANILLA_VERSION} is not published by PaperMC" + log " Set VERSION to one of the following: " + log " $(echo "$versions" | jq -r '.versions | join(", ")')" + exit 1 + ;; + *) + echo "ERROR: unknown error while looking up PaperMC version=${VANILLA_VERSION}" + exit 1 + ;; +esac +if [ $? != 0 ]; then + echo "ERROR: failed to lookup PaperMC build from version ${VANILLA_VERSION}" + exit 1 fi -downloadUrl=${PAPER_DOWNLOAD_URL:-https://papermc.io/api/v1/paper/${VANILLA_VERSION}/${PAPERBUILD}/download} -log "Downloading Paper $VANILLA_VERSION (build $PAPERBUILD) from $downloadUrl ..." -if ! curl -fsSL -o "$SERVER" $zarg "$downloadUrl"; then - log "ERROR: failed to download from $downloadUrl (status=$?)" - exit 3 +export SERVER=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}/builds/${build}" -H "accept: application/json" \ + | jq -r '.downloads.application.name') +if [ $? != 0 ]; then + echo "ERROR: failed to lookup PaperMC download file from version=${VANILLA_VERSION} build=${build}" + exit 1 +fi + +if [ -f "$SERVER" ]; then + zarg=(-z "$SERVER") +fi + +log "Downloading PaperMC $VANILLA_VERSION (build $build) ..." +curl -fsSL -o "$SERVER" "${zarg[@]}" \ + "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}/builds/${build}/downloads/${SERVER}" \ + -H "accept: application/java-archive" +if [ $? != 0 ]; then + echo "ERROR: failed to download PaperMC from version=${VANILLA_VERSION} build=${build} download=${SERVER}" + exit 1 fi # Normalize on Spigot for downstream operations diff --git a/start-minecraftFinalSetup b/start-minecraftFinalSetup index fdec5022..14410555 100644 --- a/start-minecraftFinalSetup +++ b/start-minecraftFinalSetup @@ -54,7 +54,10 @@ done if [ -d /mods ]; then log "Copying any mods over..." mkdir -p /data/mods - rsync -a --out-format="update:%f:Last Modified %M" --prune-empty-dirs --update /mods /data + if isTrue "${REMOVE_OLD_MODS}"; then + rsyncArgs=(--delete) + fi + rsync -a --out-format="update:%f:Last Modified %M" "${rsyncArgs[@]}" --prune-empty-dirs --update /mods /data fi [ -d /data/config ] || mkdir /data/config @@ -173,7 +176,7 @@ function copyFilesForCurseForge() { cp -f /data/eula.txt "${FTB_DIR}/" } -mcServerRunnerArgs="--stop-duration 60s" +mcServerRunnerArgs="--stop-duration ${STOP_DURATION:-60}s" if [[ ${TYPE} == "CURSE_INSTANCE" ]]; then if isTrue ${DEBUG_EXEC}; then set -x