diff --git a/Dockerfile b/Dockerfile index 5aa3cff3..ddbf5256 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ RUN apk add --no-cache -U \ RUN pip install mcstatus yq -HEALTHCHECK CMD mcstatus localhost:$SERVER_PORT ping +HEALTHCHECK --start-period=1m CMD mcstatus localhost:$SERVER_PORT ping RUN addgroup -g 1000 minecraft \ && adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft \ @@ -31,22 +31,20 @@ EXPOSE 25565 25575 RUN echo 'hosts: files dns' > /etc/nsswitch.conf -ARG RESTIFY_VER=1.1.6 -ARG RCON_CLI_VER=1.4.6 -ARG MC_SERVER_RUNNER_VER=1.3.2 ARG ARCH=amd64 -ADD https://github.com/itzg/restify/releases/download/${RESTIFY_VER}/restify_${RESTIFY_VER}_linux_${ARCH}.tar.gz /tmp/restify.tgz -RUN tar -x -C /usr/local/bin -f /tmp/restify.tgz restify && \ - rm /tmp/restify.tgz +ARG EASY_ADD_VER=0.3.0 +ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${EASY_ADD_VER}_linux_${ARCH} /usr/bin/easy-add +RUN chmod +x /usr/bin/easy-add -ADD https://github.com/itzg/rcon-cli/releases/download/${RCON_CLI_VER}/rcon-cli_${RCON_CLI_VER}_linux_${ARCH}.tar.gz /tmp/rcon-cli.tgz -RUN tar -x -C /usr/local/bin -f /tmp/rcon-cli.tgz rcon-cli && \ - rm /tmp/rcon-cli.tgz +ARG RESTIFY_VER=1.2.1 +RUN easy-add --file restify --from https://github.com/itzg/restify/releases/download/${RESTIFY_VER}/restify_${RESTIFY_VER}_linux_${ARCH}.tar.gz -ADD https://github.com/itzg/mc-server-runner/releases/download/${MC_SERVER_RUNNER_VER}/mc-server-runner_${MC_SERVER_RUNNER_VER}_linux_${ARCH}.tar.gz /tmp/mc-server-runner.tgz -RUN tar -x -C /usr/local/bin -f /tmp/mc-server-runner.tgz mc-server-runner && \ - rm /tmp/mc-server-runner.tgz +ARG RCON_CLI_VER=1.4.7 +RUN easy-add --file rcon-cli --from https://github.com/itzg/rcon-cli/releases/download/${RCON_CLI_VER}/rcon-cli_${RCON_CLI_VER}_linux_${ARCH}.tar.gz + +ARG MC_RUN_VER=1.3.3 +RUN easy-add --file mc-server-runner --from https://github.com/itzg/mc-server-runner/releases/download/${MC_RUN_VER}/mc-server-runner_${MC_RUN_VER}_linux_${ARCH}.tar.gz COPY mcadmin.jq /usr/share RUN chmod +x /usr/local/bin/* @@ -61,6 +59,7 @@ ENV UID=1000 GID=1000 \ MEMORY="1G" \ TYPE=VANILLA VERSION=LATEST FORGEVERSION=RECOMMENDED SPONGEBRANCH=STABLE SPONGEVERSION= FABRICVERSION=LATEST LEVEL=world \ PVP=true DIFFICULTY=easy ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \ + RESOURCE_PACK= RESOURCE_PACK_SHA1= \ LEVEL_TYPE=DEFAULT GENERATOR_SETTINGS= WORLD= MODPACK= MODS= SERVER_PORT=25565 ONLINE_MODE=TRUE CONSOLE=true SERVER_NAME="Dedicated Server" \ REPLACE_ENV_VARIABLES="FALSE" ENV_VARIABLE_PREFIX="CFG_" diff --git a/README.md b/README.md index 513d82c7..019bf39b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ This docker image provides a Minecraft Server that will automatically download t version at startup. You can also run/upgrade to any specific version or the latest snapshot. See the *Versions* section below for more information. +[![Click for more docs](https://i.imgur.com/jS02ebD.png)](https://github.com/itzg/docker-minecraft-server/blob/master/README.md) + To simply use the latest stable version, run docker run -d -p 25565:25565 --name mc itzg/minecraft-server @@ -238,6 +240,9 @@ There are some limitations to what characters you can use. | Name | `0-9a-zA-Z_-` | | Value | `0-9a-zA-Z_-:/=?.+` | +Variables will be replaced in files with the following extensions: +`.yml`, `.yaml`, `.txt`, `.cfg`, `.conf`, `.properties`. + Here is a full example where we want to replace values inside a `database.yml`. ```yml @@ -821,6 +826,12 @@ Determines if monsters will be spawned. Determines if villagers will be spawned. docker run -d -e SPAWN_NPCS=true + +### Set spawn protection + +Sets the area that non-ops can not edit (0 to disable) + + docker run -d -e SPAWN_PROTECTION=0 ### View Distance Sets the amount of world data the server sends the client, measured in chunks in each direction of the player (radius, not diameter). @@ -894,6 +905,14 @@ For example (just the `-e` bits): -e LEVEL_TYPE=flat -e 'GENERATOR_SETTINGS=3;minecraft:bedrock,3*minecraft:stone,52*minecraft:sandstone;2;' +### Custom Server Resource Pack + +You can set a link to a custom resource pack and set it's checksum using the `RESOURCE_PACK` and `RESOURCE_PACK_SHA1` options respectively, the default is blank: + + docker run -d -e 'RESROUCE_PACK=http\://link.com/to/pack.zip?\=1' -e 'RESOURCE_PACK_SHA1=d5db29cd03a2ed055086cef9c31c252b4587d6d0' + +**NOTE:** `:` and `=` must be escaped using `\`. The checksum plain-text hexadecimal. + ### World Save Name You can either switch between world saves or run multiple containers with different saves by using the `LEVEL` option, @@ -1004,7 +1023,9 @@ ways to adjust the memory settings: * `MAX_MEMORY`, independently sets the max heap size The values of all three are passed directly to the JVM and support format/units as -`[g|G|m|M|k|K]`. +`[g|G|m|M|k|K]`. For example: + + -e MEMORY=2G ### JVM Options @@ -1039,4 +1060,4 @@ pass that at the end of `docker run` after the image name or set `-e CONSOLE=FAL ### Explicitly disable GUI Some older servers get confused and think that the GUI interface is enabled. You can explicitly -disable that by passing `-e GUI=FALSE`. \ No newline at end of file +disable that by passing `-e GUI=FALSE`. diff --git a/docker-versions-create.sh b/docker-versions-create.sh new file mode 100755 index 00000000..8337ea85 --- /dev/null +++ b/docker-versions-create.sh @@ -0,0 +1,71 @@ +#!/bin/bash +#set -x +# Use this variable to indicate a list of branches that docker hub is watching +branches_list=('openj9' 'openj9-nightly') + +function TrapExit { + echo "Checking out back in master" + git checkout master +} + +trap TrapExit EXIT SIGTERM + +test -d ./.git || { echo ".git folder was not found. Please start this script from root directory of the project!"; + exit 1; } + +# Making sure we are in master +git checkout master +git pull --all || { echo "Can't pull the repo!"; \ + exit 1; } + +git_branches=$(git branch -a) + +for branch in "${branches_list[@]}"; do + if [[ "$git_branches" != *"$branch"* ]]; then + echo "Can't update $branch because I can't find it in the list of branches." + exit 1 + else + echo "Branch $branch found. Working with it." + git checkout "$branch" || { echo "Can't checkout into the branch. Don't know the cause."; \ + exit 1; } + proceed='False' + while [[ "$proceed" == "False" ]]; do + if git merge master; then + proceed="True" + echo "Branch $branch updated to current master successfully" + # pushing changes to remote for this branch + git commit -m "Auto merge branch with master" -a + # push may fail if remote doesn't have this branch yet. In this case - sending branch + git push || git push -u origin "$branch" || { echo "Can't push changes to the origin."; exit 1; } + else + cat< eula.txt - echo "eula=$EULA" >> eula.txt - if [ $? != 0 ]; then - echo "ERROR: unable to write eula to /data. Please make sure attached directory is writable by uid=${UID}" - exit 2 - fi - else + EULA="${EULA,,}" + if [ "$EULA" != "true" ]; then echo "" echo "Please accept the Minecraft EULA at" echo " https://account.mojang.com/documents/minecraft_eula" @@ -22,8 +16,16 @@ if [ ! -e /data/eula.txt ]; then echo "" exit 1 fi + + echo "# Generated via Docker on $(date)" > eula.txt + echo "eula=$EULA" >> eula.txt + if [ $? != 0 ]; then + echo "ERROR: unable to write eula to /data. Please make sure attached directory is writable by uid=${UID}" + exit 2 + fi fi + echo "Running as uid=$(id -u) gid=$(id -g) with /data as '$(ls -lnd /data)'" if ! touch /data/.verify_access; then diff --git a/start-deployFabric b/start-deployFabric index 68b9d38b..13ace55b 100644 --- a/start-deployFabric +++ b/start-deployFabric @@ -1,5 +1,7 @@ #!/bin/bash -set -u +set -eu + +. /start-utils export TYPE=FABRIC @@ -28,8 +30,9 @@ elif [[ ! -e $FABRIC_INSTALLER ]]; then exit 2 fi -installMarker=".fabric-installed-${FABRIC_VERSION:-manual}" +installMarker=".fabric-installed-${VANILLA_VERSION}-${FABRIC_VERSION:-manual}" +debug Checking for installMarker ${installMarker} if [[ ! -e $installMarker ]]; then if [[ ! -e $FABRIC_INSTALLER ]]; then if [[ -z $FABRIC_INSTALLER_URL ]]; then @@ -46,7 +49,11 @@ if [[ ! -e $installMarker ]]; then fi fi - echo "Installing Fabric $FABRIC_VERSION using $FABRIC_INSTALLER" + if isDebugging; then + debug "Installing Fabric $FABRIC_VERSION using $FABRIC_INSTALLER with mcversion ${VANILLA_VERSION}" + else + echo "Installing Fabric $FABRIC_VERSION using $FABRIC_INSTALLER" + fi tries=3 set +e while ((--tries >= 0)); do diff --git a/start-deployPaper b/start-deployPaper index b1c47c34..aac76d30 100644 --- a/start-deployPaper +++ b/start-deployPaper @@ -1,11 +1,11 @@ #!/bin/bash -export SERVER=paper_server.jar -if [ ! -f $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then +export SERVER=paper_server-${VANILLA_VERSION}.jar +if [ ! -f "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then downloadUrl=${PAPER_DOWNLOAD_URL:-https://papermc.io/api/v1/paper/${VANILLA_VERSION}/latest/download} echo "Downloading Paper $VANILLA_VERSION from $downloadUrl ..." - curl -fsSL -o $SERVER "$downloadUrl" - if [ ! -f $SERVER ]; then + curl -fsSL -o "$SERVER" "$downloadUrl" + if [ ! -f "$SERVER" ]; then echo "ERROR: failed to download from $downloadUrl (status=$?)" exit 3 fi diff --git a/start-finalSetup02Modpack b/start-finalSetup02Modpack index 25cd680d..782377c0 100644 --- a/start-finalSetup02Modpack +++ b/start-finalSetup02Modpack @@ -1,5 +1,9 @@ #!/bin/bash +set -e + +. /start-utils + # CURSE_URL_BASE used in manifest downloads below CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects} @@ -106,4 +110,25 @@ case "X$EFFECTIVE_MANIFEST_URL" in esac fi +if [[ "${GENERIC_PACK}" ]]; then + if isURL "${GENERIC_PACK}"; then + generic_pack_url=${GENERIC_PACK} + GENERIC_PACK=/tmp/$(basename ${generic_pack_url}) + echo "Downloading generic pack from ${generic_pack_url} ..." + curl -fsSL -o ${GENERIC_PACK} ${generic_pack_url} + fi + + sum_file=/data/.generic_pack.sum + if ! sha256sum -c ${sum_file} -s 2> /dev/null; then + base_dir=/tmp/generic_pack_base + mkdir -p ${base_dir} + unzip -q -d ${base_dir} ${GENERIC_PACK} + depth=$(( ${GENERIC_PACK_STRIP_DIRS:-1} + 1 )) + echo "Applying generic pack, stripping $(( depth - 1 )) level ..." + find ${base_dir} -type d -mindepth $depth -maxdepth $depth -exec cp -r {} /data/ + + rm -rf ${base_dir} + sha256sum ${GENERIC_PACK} > ${sum_file} + fi +fi + exec /start-finalSetup03Modconfig $@ diff --git a/start-finalSetup04ServerProperties b/start-finalSetup04ServerProperties index 0f2e7580..b9df16e8 100644 --- a/start-finalSetup04ServerProperties +++ b/start-finalSetup04ServerProperties @@ -49,6 +49,7 @@ function customizeServerProps { setServerProp "spawn-animals" "$SPAWN_ANIMALS" setServerProp "spawn-monsters" "$SPAWN_MONSTERS" setServerProp "spawn-npcs" "$SPAWN_NPCS" + setServerProp "spawn-protection" "$SPAWN_PROTECTION" setServerProp "generate-structures" "$GENERATE_STRUCTURES" setServerProp "view-distance" "$VIEW_DISTANCE" setServerProp "hardcore" "$HARDCORE" @@ -70,6 +71,8 @@ function customizeServerProps { setServerProp "online-mode" "$ONLINE_MODE" setServerProp "allow-flight" "$ALLOW_FLIGHT" setServerProp "level-type" "${LEVEL_TYPE^^}" + setServerProp "resource-pack" "$RESOURCE_PACK" + setServerProp "resource-pack-sha1" "$RESOURCE_PACK_SHA1" if [ -n "$DIFFICULTY" ]; then case $DIFFICULTY in diff --git a/start-finalSetup05EnvVariables b/start-finalSetup05EnvVariables index d1c44f49..532e28e4 100644 --- a/start-finalSetup05EnvVariables +++ b/start-finalSetup05EnvVariables @@ -1,15 +1,20 @@ #!/bin/bash -if [ "$REPLACE_ENV_VARIABLES" = "TRUE" ]; then +if [ "${REPLACE_ENV_VARIABLES^^}" = "TRUE" ]; then echo "Replacing env variables in configs that match the prefix $ENV_VARIABLE_PREFIX..." while IFS='=' read -r name value ; do # check if name of env variable matches the prefix # sanity check environment variables to avoid code injections - if [[ "$name" = $ENV_VARIABLE_PREFIX* ]] && [[ $value =~ ^[0-9a-zA-Z_:/=?.+\-]*$ ]] && [[ $name =~ ^[0-9a-zA-Z_\-]*$ ]]; then - echo "Replacing $name with $value ..." - find /data/ -type f \( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" -or -name "*.properties" \) -exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \; + if [[ "$name" = $ENV_VARIABLE_PREFIX* ]] \ + && [[ $value =~ ^[0-9a-zA-Z_:/=?.+\-]*$ ]] \ + && [[ $name =~ ^[0-9a-zA-Z_\-]*$ ]]; then + echo "Replacing $name with $value ..." + find /data/ -type f \ + \( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" \ + -or -name "*.conf" -or -name "*.properties" \) \ + -exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \; fi done < <(env) fi -exec /start-minecraftFinalSetup $@ \ No newline at end of file +exec /start-minecraftFinalSetup $@ diff --git a/start-minecraftFinalSetup b/start-minecraftFinalSetup index 6dccba6c..84c6a38c 100644 --- a/start-minecraftFinalSetup +++ b/start-minecraftFinalSetup @@ -2,14 +2,16 @@ . /start-utils -if [ -n "$OPS" -a ! -e ops.txt.converted ]; then - echo "Setting ops" - echo $OPS | awk -v RS=, '{print}' >> ops.txt +if [ -n "$OPS" ]; then + echo "Setting/adding ops" + rm -rf ops.txt.converted + echo $OPS | awk -v RS=, '{print}' > ops.txt fi -if [ -n "$WHITELIST" -a ! -e white-list.txt.converted ]; then +if [ -n "$WHITELIST" ]; then echo "Setting whitelist" - echo $WHITELIST | awk -v RS=, '{print}' >> white-list.txt + rm -rf white-list.txt.converted + echo $WHITELIST | awk -v RS=, '{print}' > white-list.txt fi if [ -n "$ICON" -a ! -e server-icon.png ]; then @@ -117,7 +119,7 @@ if [[ ${TYPE} == "FEED-THE-BEAST" ]]; then cat > "${FTB_DIR}/settings-local.sh" <