diff --git a/.dockerignore b/.dockerignore index 1db22cbb..cbb305e6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ data +testdata examples k8s-examples .idea -.git \ No newline at end of file +.git diff --git a/README.md b/README.md index aa12728c..a9b71349 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ latest snapshot. See the _Versions_ section below for more information. To simply use the latest stable version, run - docker run -d -p 25565:25565 --name mc itzg/minecraft-server + docker run -d -p 25565:25565 --name mc -e EULA=TRUE itzg/minecraft-server where the standard server port, 25565, will be exposed on your host machine. @@ -35,6 +35,7 @@ With that you can easily view the logs, stop, or re-start the container: docker stop mc docker start mc +*Be sure to always include `-e EULA=TRUE` in your commands, as Mojang/Microsoft requires EULA acceptance.* ## Looking for a Bedrock Dedicated Server @@ -269,10 +270,20 @@ the `/path/on/host` folder contents look like: ├── ops.json ├── server.properties ├── whitelist.json +├── worlds +│   └── ... PLACE MAPS IN THEIR OWN FOLDERS HERE ... └── ... ``` -If you add mods while the container is running, you'll need to restart it to pick those +Providing a presistent `/data` mount is a good idea, both to persist the game world and to allow for the manual configuration which is sometimes needed. + +For instance, imagine a scenario when the initial launch has completed, but you now want to change the worldmap for your server. + +Assuming you have a shared directory to your container, you can then (after first launch) drag and drop your premade maps or worlds into the `\worlds\` directory. **Note:** each world should be placed in its own folder under the `\worlds\` directory. + +Once your maps are in the proper path, you can then specify which map the server uses by changing the `level-name` value in `server.properties` to match the name of your map. + +If you add mods or make changes to `server.properties` while the container is running, you'll need to restart it to pick those up: docker stop mc @@ -291,6 +302,8 @@ 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 in either persistent volumes or a downloadable archive. + + ### Replacing variables inside configs Sometimes you have mods or plugins that require configuration information that is only available at runtime. @@ -390,7 +403,7 @@ secrets: The content of `db_password`: ug23u3bg39o-ogADSs - + ## Running a Bukkit/Spigot server Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT` or `-e TYPE=SPIGOT` to your command-line. diff --git a/files/autopause/autopause-daemon.sh b/files/autopause/autopause-daemon.sh index 3150740c..e46fdffa 100644 --- a/files/autopause/autopause-daemon.sh +++ b/files/autopause/autopause-daemon.sh @@ -4,7 +4,7 @@ . /start-utils -sudo /usr/sbin/knockd -c /autopause/knockd-config.cfg -d +sudo /usr/sbin/knockd -c /tmp/knockd-config.cfg -d if [ $? -ne 0 ] ; then while : do diff --git a/start b/start index f6d467e7..43aff1e5 100644 --- a/start +++ b/start @@ -36,11 +36,6 @@ if [ $(id -u) = 0 ]; then chown -R ${runAsUser}:${runAsGroup} /data fi - if [[ $(stat -c "%u" /autopause) != $UID ]]; then - log "Changing ownership of /autopause to $UID ..." - chown -R ${runAsUser}:${runAsGroup} /autopause - fi - if [[ ${SKIP_NSSWITCH_CONF^^} != TRUE ]]; then echo 'hosts: files dns' > /etc/nsswitch.conf fi diff --git a/start-autopause b/start-autopause index 32c5e64a..51acfc5e 100755 --- a/start-autopause +++ b/start-autopause @@ -4,18 +4,20 @@ log "Autopause functionality enabled" +cp /autopause/knockd-config.cfg /tmp/knockd-config.cfg + # update server port to listen to regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$" -linenum=$(grep -nm1 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1) -if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then - sed -i "${linenum}s/sequence.*/sequence = $SERVER_PORT/" /autopause/knockd-config.cfg +linenum=$(grep -nm1 sequence /tmp/knockd-config.cfg | cut -d : -f 1 | tail -n1) +if ! [[ $(awk "NR==$linenum" /tmp/knockd-config.cfg) =~ $regseq ]]; then + sed -i "${linenum}s/sequence.*/sequence = $SERVER_PORT/" /tmp/knockd-config.cfg log "Updated server port in knockd config" fi # update rcon port to listen to regseq="^\s*sequence\s*=\s*$RCON_PORT\s*$" -linenum=$(grep -nm2 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1) -if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then - sed -i "${linenum}s/sequence.*/sequence = $RCON_PORT/" /autopause/knockd-config.cfg +linenum=$(grep -nm2 sequence /tmp/knockd-config.cfg | cut -d : -f 1 | tail -n1) +if ! [[ $(awk "NR==$linenum" /tmp/knockd-config.cfg) =~ $regseq ]]; then + sed -i "${linenum}s/sequence.*/sequence = $RCON_PORT/" /tmp/knockd-config.cfg log "Updated rcon port in knockd config" fi diff --git a/start-configuration b/start-configuration index efb837aa..57a48b67 100644 --- a/start-configuration +++ b/start-configuration @@ -8,8 +8,7 @@ shopt -s nullglob export HOME=/data if [ ! -e /data/eula.txt ]; then - EULA="${EULA,,}" - if [ "$EULA" != "true" ]; then + if ! isTrue "$EULA"; then log "" log "Please accept the Minecraft EULA at" log " https://account.mojang.com/documents/minecraft_eula" @@ -19,12 +18,7 @@ if [ ! -e /data/eula.txt ]; then exit 1 fi - echo "# Generated via Docker on $(date)" > /data/eula.txt - - if ! echo "eula=$EULA" >> /data/eula.txt; then - log "ERROR: unable to write eula to /data. Please make sure attached directory is writable by uid=${UID}" - exit 2 - fi + writeEula fi @@ -109,7 +103,7 @@ case "${TYPE^^}" in ;; FTB|CURSEFORGE) - exec ${SCRIPTS:-/}start-deployFTB "$@" + exec ${SCRIPTS:-/}start-deployCF "$@" ;; VANILLA) diff --git a/start-deployFTB b/start-deployCF similarity index 100% rename from start-deployFTB rename to start-deployCF diff --git a/start-finalSetupModpack b/start-finalSetupModpack index 40962733..e21340cc 100644 --- a/start-finalSetupModpack +++ b/start-finalSetupModpack @@ -18,42 +18,60 @@ fi # If supplied with a URL for a modpack (simple zip of jars), download it and unpack if [[ "$MODPACK" ]]; then -EFFECTIVE_MODPACK_URL=$(curl -Ls -o /dev/null -w %{url_effective} $MODPACK) -case "X$EFFECTIVE_MODPACK_URL" in - X[Hh][Tt][Tt][Pp]*.zip) + if isURL "${MODPACK}"; then + if [[ "${MODPACK}" == *.zip ]]; then + downloadUrl="${MODPACK}" + else + downloadUrl=$(curl -Ls -o /dev/null -w %{url_effective} $MODPACK) + if ! [[ $downloadUrl == *.zip ]]; then + log "ERROR Invalid URL given for MODPACK: $downloadUrl resolved from $MODPACK" + log " Must be HTTP or HTTPS and a ZIP file" + exit 1 + fi + fi + log "Downloading mod/plugin pack via HTTP" - log " from $EFFECTIVE_MODPACK_URL ..." - if ! curl -sSL -o /tmp/modpack.zip "$EFFECTIVE_MODPACK_URL"; then - log "ERROR: failed to download from $EFFECTIVE_MODPACK_URL" + log " from $downloadUrl ..." + if ! curl -sSL -o /tmp/modpack.zip "$downloadUrl"; then + log "ERROR: failed to download from $downloadUrl" exit 2 fi if [ "$TYPE" = "SPIGOT" ]; then mkdir -p /data/plugins if ! unzip -o -d /data/plugins /tmp/modpack.zip; then - log "ERROR: failed to unzip the modpack from $EFFECTIVE_MODPACK_URL" + log "ERROR: failed to unzip the modpack from $downloadUrl" fi else mkdir -p /data/mods if ! unzip -o -d /data/mods /tmp/modpack.zip; then - log "ERROR: failed to unzip the modpack from $EFFECTIVE_MODPACK_URL" + log "ERROR: failed to unzip the modpack from $downloadUrl" fi fi rm -f /tmp/modpack.zip - ;; - *) - log "Invalid URL given for modpack: Must be HTTP or HTTPS and a ZIP file" - ;; -esac + + else + log "ERROR Invalid URL given for MODPACK: $MODPACK" + exit 1 + fi fi # If supplied with a URL for a plugin download it. if [[ "$MODS" ]]; then -for i in ${MODS//,/ } -do - EFFECTIVE_MOD_URL=$(curl -Ls -o /dev/null -w %{url_effective} $i) - case "X$EFFECTIVE_MOD_URL" in - X[Hh][Tt][Tt][Pp]*.jar) + for i in ${MODS//,/ } + do + if isURL $i; then + if [[ $i == *.jar ]]; then + EFFECTIVE_MOD_URL=$i + else + EFFECTIVE_MOD_URL=$(curl -Ls -o /dev/null -w %{url_effective} $i) + if ! [[ $EFFECTIVE_MOD_URL == *.jar ]]; then + log "ERROR Invalid URL given in MODS: $EFFECTIVE_MOD_URL resolved from $i" + log " Must be HTTP or HTTPS and a JAR file" + exit 1 + fi + fi + log "Downloading mod/plugin via HTTP" log " from $EFFECTIVE_MOD_URL ..." if ! curl -sSL -o /tmp/${EFFECTIVE_MOD_URL##*/} $EFFECTIVE_MOD_URL; then @@ -69,12 +87,12 @@ do mv /tmp/${EFFECTIVE_MOD_URL##*/} /data/mods/${EFFECTIVE_MOD_URL##*/} fi rm -f /tmp/${EFFECTIVE_MOD_URL##*/} - ;; - *) - log "Invalid URL given for modpack: Must be HTTP or HTTPS and a JAR file" - ;; - esac -done + + else + log "ERROR Invalid URL given in MODS: $i" + exit 1 + fi + done fi if [[ "$MANIFEST" ]]; then diff --git a/start-utils b/start-utils index ffbdec29..a46d1a28 100644 --- a/start-utils +++ b/start-utils @@ -113,3 +113,12 @@ requireVar() { exit 1 fi } + +function writeEula() { +if ! echo "# Generated via Docker on $(date) +eula=${EULA,,} +" > /data/eula.txt; then + log "ERROR: unable to write eula to /data. Please make sure attached directory is writable by uid=${UID}" + exit 2 +fi +}