mirror of
https://github.com/itzg/docker-minecraft-server.git
synced 2026-05-23 04:05:26 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a324c30de | |||
| e0cdf9e2ce | |||
| 57740cb749 | |||
| 966c74cd08 | |||
| d84b58dfd0 | |||
| 7aaf106ffe | |||
| 5f77902441 | |||
| c200efc9c9 | |||
| e924126a56 | |||
| bbd3d3cfc1 | |||
| d77c19c69b | |||
| 7ee77e4f47 | |||
| 84d0cff4c8 | |||
| 70519b9764 | |||
| 4683ea496d | |||
| 0e3a82f9d3 | |||
| d2554f2271 | |||
| 55e62371ac | |||
| c9a5fcfac8 | |||
| a1f8154d05 | |||
| e5d0a9362a | |||
| ca9c280b0b | |||
| 6ef4e984c7 | |||
| ea4f78346a | |||
| 007f9426bf |
@@ -0,0 +1,25 @@
|
|||||||
|
version: 2
|
||||||
|
jobs:
|
||||||
|
minecraft_server:
|
||||||
|
docker:
|
||||||
|
- image: circleci/buildpack-deps:stable
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- setup_remote_docker
|
||||||
|
- run:
|
||||||
|
name: Build image
|
||||||
|
command: docker build -t itzg/minecraft-server:${CIRCLE_BRANCH} .
|
||||||
|
# - run:
|
||||||
|
# name: Build arm v7 image
|
||||||
|
# command: docker build -t itzg/minecraft-server:${CIRCLE_BRANCH}-arm-v7 --platform linux/arm/v7 --build-arg ARCH=armv7 .
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
version: 2
|
||||||
|
build:
|
||||||
|
jobs:
|
||||||
|
- minecraft_server:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore:
|
||||||
|
- armv7
|
||||||
|
- multiarch
|
||||||
+1
-2
@@ -1,6 +1,5 @@
|
|||||||
data
|
data
|
||||||
testdata
|
|
||||||
examples
|
examples
|
||||||
k8s-examples
|
k8s-examples
|
||||||
.idea
|
.idea
|
||||||
.git
|
.git
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
FROM openjdk:8u212-jre-alpine
|
FROM adoptopenjdk/openjdk8-openj9:alpine
|
||||||
|
|
||||||
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
|
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ COPY log4j2.xml /tmp/log4j2.xml
|
|||||||
WORKDIR /data
|
WORKDIR /data
|
||||||
|
|
||||||
ENV UID=1000 GID=1000 \
|
ENV UID=1000 GID=1000 \
|
||||||
JVM_XX_OPTS="-XX:+UseG1GC" MEMORY="1G" \
|
MEMORY="1G" \
|
||||||
TYPE=VANILLA VERSION=LATEST FORGEVERSION=RECOMMENDED SPONGEBRANCH=STABLE SPONGEVERSION= FABRICVERSION=LATEST LEVEL=world \
|
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 \
|
PVP=true DIFFICULTY=easy ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \
|
||||||
LEVEL_TYPE=DEFAULT SERVER_PORT=25565 ONLINE_MODE=TRUE SERVER_NAME="Dedicated Server" \
|
LEVEL_TYPE=DEFAULT SERVER_PORT=25565 ONLINE_MODE=TRUE SERVER_NAME="Dedicated Server" \
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ latest snapshot. See the _Versions_ section below for more information.
|
|||||||
|
|
||||||
To simply use the latest stable version, run
|
To simply use the latest stable version, run
|
||||||
|
|
||||||
docker run -d -p 25565:25565 --name mc -e EULA=TRUE itzg/minecraft-server
|
docker run -d -p 25565:25565 --name mc itzg/minecraft-server
|
||||||
|
|
||||||
where the standard server port, 25565, will be exposed on your host machine.
|
where the standard server port, 25565, will be exposed on your host machine.
|
||||||
|
|
||||||
@@ -35,7 +35,6 @@ With that you can easily view the logs, stop, or re-start the container:
|
|||||||
docker stop mc
|
docker stop mc
|
||||||
|
|
||||||
docker start 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
|
## Looking for a Bedrock Dedicated Server
|
||||||
|
|
||||||
@@ -270,20 +269,10 @@ the `/path/on/host` folder contents look like:
|
|||||||
├── ops.json
|
├── ops.json
|
||||||
├── server.properties
|
├── server.properties
|
||||||
├── whitelist.json
|
├── whitelist.json
|
||||||
├── worlds
|
|
||||||
│ └── ... PLACE MAPS IN THEIR OWN FOLDERS HERE ...
|
|
||||||
└── ...
|
└── ...
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
If you add mods while the container is running, you'll need to restart it to pick those
|
||||||
|
|
||||||
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:
|
up:
|
||||||
|
|
||||||
docker stop mc
|
docker stop mc
|
||||||
@@ -302,8 +291,6 @@ 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
|
location, but still have multiple worlds with different server requirements
|
||||||
in either persistent volumes or a downloadable archive.
|
in either persistent volumes or a downloadable archive.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Replacing variables inside configs
|
### Replacing variables inside configs
|
||||||
|
|
||||||
Sometimes you have mods or plugins that require configuration information that is only available at runtime.
|
Sometimes you have mods or plugins that require configuration information that is only available at runtime.
|
||||||
@@ -342,7 +329,7 @@ Specific files can be excluded by listing their name (without path) in the varia
|
|||||||
Paths can be excluded by listing them in the variable `REPLACE_ENV_VARIABLES_EXCLUDE_PATHS`. Path
|
Paths can be excluded by listing them in the variable `REPLACE_ENV_VARIABLES_EXCLUDE_PATHS`. Path
|
||||||
excludes are recursive. Here is an example:
|
excludes are recursive. Here is an example:
|
||||||
```
|
```
|
||||||
REPLACE_ENV_VARIABLES_EXCLUDE_PATHS="/data/plugins/Essentials/userdata /data/plugins/MyPlugin"
|
REPLACE_ENV_VARIABLES_EXCLUDE_PATHS="/data/plugins/Essentials/userdata/ /data/plugins/MyPlugin/"
|
||||||
```
|
```
|
||||||
|
|
||||||
Here is a full example where we want to replace values inside a `database.yml`.
|
Here is a full example where we want to replace values inside a `database.yml`.
|
||||||
@@ -403,7 +390,7 @@ secrets:
|
|||||||
The content of `db_password`:
|
The content of `db_password`:
|
||||||
|
|
||||||
ug23u3bg39o-ogADSs
|
ug23u3bg39o-ogADSs
|
||||||
|
|
||||||
## Running a Bukkit/Spigot server
|
## Running a Bukkit/Spigot server
|
||||||
|
|
||||||
Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT` or `-e TYPE=SPIGOT` to your command-line.
|
Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT` or `-e TYPE=SPIGOT` to your command-line.
|
||||||
@@ -526,10 +513,6 @@ The following example uses `/modpacks` as the container path as the pre-download
|
|||||||
-e CF_SERVER_MOD=/modpacks/SkyFactory_4_Server_4.1.0.zip \
|
-e CF_SERVER_MOD=/modpacks/SkyFactory_4_Server_4.1.0.zip \
|
||||||
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
|
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
|
||||||
|
|
||||||
#### Buggy start scripts
|
|
||||||
|
|
||||||
Some modpacks have buggy or overly complex start scripts. You can avoid using the bundled start script and use this image's standard server-starting logic by adding `-e USE_MODPACK_START_SCRIPT=false`.
|
|
||||||
|
|
||||||
### Fixing "unable to launch forgemodloader"
|
### Fixing "unable to launch forgemodloader"
|
||||||
|
|
||||||
If your server's modpack fails to load with an error [like this](https://support.feed-the-beast.com/t/cant-start-crashlanding-server-unable-to-launch-forgemodloader/6028/2):
|
If your server's modpack fails to load with an error [like this](https://support.feed-the-beast.com/t/cant-start-crashlanding-server-unable-to-launch-forgemodloader/6028/2):
|
||||||
@@ -1069,6 +1052,14 @@ via a `JVM_XX_OPTS` environment variable.
|
|||||||
For some cases, if e.g. after removing mods, it could be necessary to startup minecraft with an additional `-D` parameter like `-Dfml.queryResult=confirm`. To address this you can use the environment variable `JVM_DD_OPTS`, which builds the params from a given list of values separated by space, but without the `-D` prefix. To make things running under systems (e.g. Plesk), which doesn't allow `=` inside values, a `:` (colon) could be used instead. The upper example would look like this:
|
For some cases, if e.g. after removing mods, it could be necessary to startup minecraft with an additional `-D` parameter like `-Dfml.queryResult=confirm`. To address this you can use the environment variable `JVM_DD_OPTS`, which builds the params from a given list of values separated by space, but without the `-D` prefix. To make things running under systems (e.g. Plesk), which doesn't allow `=` inside values, a `:` (colon) could be used instead. The upper example would look like this:
|
||||||
`JVM_DD_OPTS=fml.queryResult:confirm`, and will be converted to `-Dfml.queryResult=confirm`.
|
`JVM_DD_OPTS=fml.queryResult:confirm`, and will be converted to `-Dfml.queryResult=confirm`.
|
||||||
|
|
||||||
|
The container uses [OpenJ9](https://www.eclipse.org/openj9/docs) and a couple of J9 options are
|
||||||
|
simplified by environment variables:
|
||||||
|
|
||||||
|
- `-e TUNE_VIRTUALIZED=TRUE` : enables the option to
|
||||||
|
[optimize for virtualized environments](https://www.eclipse.org/openj9/docs/xtunevirtualized/)
|
||||||
|
- `-e TUNE_NURSERY_SIZES=TRUE` : configures nursery sizes where the initial size is 50%
|
||||||
|
of the `MAX_MEMORY` and the max size is 80%.
|
||||||
|
|
||||||
### Enable Remote JMX for Profiling
|
### Enable Remote JMX for Profiling
|
||||||
|
|
||||||
To enable remote JMX, such as for profiling with VisualVM or JMC, add the environment variable `ENABLE_JMX=true` and add a port forwarding of TCP port 7091, such as:
|
To enable remote JMX, such as for profiling with VisualVM or JMC, add the environment variable `ENABLE_JMX=true` and add a port forwarding of TCP port 7091, such as:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
. /start-utils
|
. /start-utils
|
||||||
|
|
||||||
sudo /usr/sbin/knockd -c /tmp/knockd-config.cfg -d
|
sudo /usr/sbin/knockd -c /autopause/knockd-config.cfg -d
|
||||||
if [ $? -ne 0 ] ; then
|
if [ $? -ne 0 ] ; then
|
||||||
while :
|
while :
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ if [ $(id -u) = 0 ]; then
|
|||||||
chown -R ${runAsUser}:${runAsGroup} /data
|
chown -R ${runAsUser}:${runAsGroup} /data
|
||||||
fi
|
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
|
if [[ ${SKIP_NSSWITCH_CONF^^} != TRUE ]]; then
|
||||||
echo 'hosts: files dns' > /etc/nsswitch.conf
|
echo 'hosts: files dns' > /etc/nsswitch.conf
|
||||||
fi
|
fi
|
||||||
|
|||||||
+6
-8
@@ -4,20 +4,18 @@
|
|||||||
|
|
||||||
log "Autopause functionality enabled"
|
log "Autopause functionality enabled"
|
||||||
|
|
||||||
cp /autopause/knockd-config.cfg /tmp/knockd-config.cfg
|
|
||||||
|
|
||||||
# update server port to listen to
|
# update server port to listen to
|
||||||
regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$"
|
regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$"
|
||||||
linenum=$(grep -nm1 sequence /tmp/knockd-config.cfg | cut -d : -f 1 | tail -n1)
|
linenum=$(grep -nm1 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1)
|
||||||
if ! [[ $(awk "NR==$linenum" /tmp/knockd-config.cfg) =~ $regseq ]]; then
|
if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then
|
||||||
sed -i "${linenum}s/sequence.*/sequence = $SERVER_PORT/" /tmp/knockd-config.cfg
|
sed -i "${linenum}s/sequence.*/sequence = $SERVER_PORT/" /autopause/knockd-config.cfg
|
||||||
log "Updated server port in knockd config"
|
log "Updated server port in knockd config"
|
||||||
fi
|
fi
|
||||||
# update rcon port to listen to
|
# update rcon port to listen to
|
||||||
regseq="^\s*sequence\s*=\s*$RCON_PORT\s*$"
|
regseq="^\s*sequence\s*=\s*$RCON_PORT\s*$"
|
||||||
linenum=$(grep -nm2 sequence /tmp/knockd-config.cfg | cut -d : -f 1 | tail -n1)
|
linenum=$(grep -nm2 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1)
|
||||||
if ! [[ $(awk "NR==$linenum" /tmp/knockd-config.cfg) =~ $regseq ]]; then
|
if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then
|
||||||
sed -i "${linenum}s/sequence.*/sequence = $RCON_PORT/" /tmp/knockd-config.cfg
|
sed -i "${linenum}s/sequence.*/sequence = $RCON_PORT/" /autopause/knockd-config.cfg
|
||||||
log "Updated rcon port in knockd config"
|
log "Updated rcon port in knockd config"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+13
-4
@@ -8,7 +8,8 @@ shopt -s nullglob
|
|||||||
export HOME=/data
|
export HOME=/data
|
||||||
|
|
||||||
if [ ! -e /data/eula.txt ]; then
|
if [ ! -e /data/eula.txt ]; then
|
||||||
if ! isTrue "$EULA"; then
|
EULA="${EULA,,}"
|
||||||
|
if [ "$EULA" != "true" ]; then
|
||||||
log ""
|
log ""
|
||||||
log "Please accept the Minecraft EULA at"
|
log "Please accept the Minecraft EULA at"
|
||||||
log " https://account.mojang.com/documents/minecraft_eula"
|
log " https://account.mojang.com/documents/minecraft_eula"
|
||||||
@@ -18,7 +19,12 @@ if [ ! -e /data/eula.txt ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
writeEula
|
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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -65,9 +71,12 @@ case "X$VERSION" in
|
|||||||
XSNAPSHOT|Xsnapshot)
|
XSNAPSHOT|Xsnapshot)
|
||||||
VANILLA_VERSION=$(curl -fsSL $VERSIONS_JSON | jq -r '.latest.snapshot')
|
VANILLA_VERSION=$(curl -fsSL $VERSIONS_JSON | jq -r '.latest.snapshot')
|
||||||
;;
|
;;
|
||||||
*)
|
X[1-9]*)
|
||||||
VANILLA_VERSION=$VERSION
|
VANILLA_VERSION=$VERSION
|
||||||
;;
|
;;
|
||||||
|
*)
|
||||||
|
VANILLA_VERSION=$(curl -fsSL $VERSIONS_JSON | jq -r '.latest.release')
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
export VANILLA_VERSION
|
export VANILLA_VERSION
|
||||||
log "Resolved version given ${VERSION} into ${VANILLA_VERSION}"
|
log "Resolved version given ${VERSION} into ${VANILLA_VERSION}"
|
||||||
@@ -103,7 +112,7 @@ case "${TYPE^^}" in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
FTB|CURSEFORGE)
|
FTB|CURSEFORGE)
|
||||||
exec ${SCRIPTS:-/}start-deployCF "$@"
|
exec ${SCRIPTS:-/}start-deployFTB "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
VANILLA)
|
VANILLA)
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
. ${SCRIPTS:-/}start-utils
|
||||||
|
|
||||||
export FTB_BASE_DIR=/data/FeedTheBeast
|
export FTB_BASE_DIR=/data/FeedTheBeast
|
||||||
@@ -11,67 +9,18 @@ export TYPE=FEED-THE-BEAST
|
|||||||
FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
|
FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
|
||||||
|
|
||||||
log "Looking for Feed-The-Beast / CurseForge server modpack."
|
log "Looking for Feed-The-Beast / CurseForge server modpack."
|
||||||
requireVar FTB_SERVER_MOD
|
if [[ -z $FTB_SERVER_MOD ]]; then
|
||||||
|
log "Environment variable FTB_SERVER_MOD not set."
|
||||||
if ! isTrue ${USE_MODPACK_START_SCRIPT:-true}; then
|
log "Set FTB_SERVER_MOD to the file name of the FTB server modpack."
|
||||||
if ! [ -f ${FTB_SERVER_MOD} ]; then
|
log "(And place the modpack in the /data directory.)"
|
||||||
log "ERROR unable to find requested modpack file ${FTB_SERVER_MOD}"
|
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
|
||||||
|
|
||||||
needsInstall=true
|
|
||||||
installMarker=/data/.curseforge-installed
|
|
||||||
if [ -f $installMarker ]; then
|
|
||||||
if [ "$(cat $installMarker)" != "${FTB_SERVER_MOD}" ]; then
|
|
||||||
log "Upgrading modpack"
|
|
||||||
|
|
||||||
serverJar=$(find ${FTB_BASE_DIR} -not -name "forge*installer.jar" -name "forge*.jar")
|
|
||||||
if [[ "${serverJar}" ]]; then
|
|
||||||
rm -rf $(dirname "${serverJar}")/{mods,*.jar,libraries,resources,scripts}
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
needsInstall=false
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $needsInstall; then
|
|
||||||
log "Unpacking FTB server modpack ${FTB_SERVER_MOD} ..."
|
|
||||||
mkdir -p ${FTB_BASE_DIR}
|
|
||||||
unzip -o ${FTB_SERVER_MOD} -d ${FTB_BASE_DIR} | awk '{printf "."} END {print ""}'
|
|
||||||
|
|
||||||
forgeInstallerJar=$(find ${FTB_BASE_DIR} -name "forge*installer.jar")
|
|
||||||
if [[ -z "${forgeInstallerJar}" ]]; then
|
|
||||||
log "ERROR Unable to find forge installer in modpack."
|
|
||||||
log " Make sure you downloaded the server files."
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Installing forge server"
|
|
||||||
(cd $(dirname "${forgeInstallerJar}"); java -jar $(basename ${forgeInstallerJar}) --installServer) | awk '{printf "."} END {print ""}'
|
|
||||||
|
|
||||||
echo "${FTB_SERVER_MOD}" > $installMarker
|
|
||||||
fi
|
|
||||||
|
|
||||||
export SERVER=$(find ${FTB_BASE_DIR} -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"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
export FTB_DIR=$(dirname "${SERVER}")
|
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
entryScriptExpr="
|
entryScriptExpr="
|
||||||
-name ServerStart.sh
|
-name ServerStart.sh
|
||||||
-o -name serverstart.sh
|
|
||||||
-o -name ServerStartLinux.sh
|
-o -name ServerStartLinux.sh
|
||||||
-o -name LaunchServer.sh
|
-o -name LaunchServer.sh
|
||||||
-o -name server-start.sh
|
-o -name server-start.sh
|
||||||
-o -name startserver.sh
|
|
||||||
-o -name StartServer.sh
|
|
||||||
"
|
"
|
||||||
|
|
||||||
if [[ -d ${FTB_BASE_DIR} ]]; then
|
if [[ -d ${FTB_BASE_DIR} ]]; then
|
||||||
@@ -26,9 +26,6 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
|
|||||||
if [ $result != 0 ]; then
|
if [ $result != 0 ]; then
|
||||||
log "ERROR failed to obtain version manifest from $versionManifestUrl ($result)"
|
log "ERROR failed to obtain version manifest from $versionManifestUrl ($result)"
|
||||||
exit 1
|
exit 1
|
||||||
elif [ $serverDownloadUrl = null ]; then
|
|
||||||
log "ERROR version $VANILLA_VERSION does not provide a server download"
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
debug "Downloading server from $serverDownloadUrl"
|
debug "Downloading server from $serverDownloadUrl"
|
||||||
|
|||||||
@@ -6,21 +6,20 @@
|
|||||||
|
|
||||||
if isTrue "${REPLACE_ENV_VARIABLES}"; then
|
if isTrue "${REPLACE_ENV_VARIABLES}"; then
|
||||||
log "Replacing env variables in configs that match the prefix $ENV_VARIABLE_PREFIX..."
|
log "Replacing env variables in configs that match the prefix $ENV_VARIABLE_PREFIX..."
|
||||||
|
findExcludes=
|
||||||
|
|
||||||
# File excludes
|
# File excludes
|
||||||
fileExcludes=
|
|
||||||
for f in ${REPLACE_ENV_VARIABLES_EXCLUDES}; do
|
for f in ${REPLACE_ENV_VARIABLES_EXCLUDES}; do
|
||||||
fileExcludes="${fileExcludes} -not -name $f"
|
findExcludes="${findExcludes} -not -name $f"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Directory excludes (recursive)
|
# Directory excludes (recursive)
|
||||||
dirExcludes=$(join_by " -o -path " ${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS})
|
dirExcludes=$(join_by " -o -path " ${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS})
|
||||||
if [[ $dirExcludes ]]; then
|
if [[ $dirExcludes ]]; then
|
||||||
dirExcludes=" -type d ( -path ${dirExcludes} ) -prune -o"
|
findExcludes+=" -type d ( -path ${dirExcludes} ) -prune"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
isDebugging && echo "Using find file exclusions: $fileExcludes"
|
isDebugging && echo "Using find exclusions: $findExcludes"
|
||||||
isDebugging && echo "Using find directory exclusions: $dirExcludes"
|
|
||||||
|
|
||||||
while IFS='=' read -r name value ; do
|
while IFS='=' read -r name value ; do
|
||||||
# check if name of env variable matches the prefix
|
# check if name of env variable matches the prefix
|
||||||
@@ -35,12 +34,10 @@ if isTrue "${REPLACE_ENV_VARIABLES}"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
log "Replacing $name with $value ..."
|
log "Replacing $name with $value ..."
|
||||||
find /data/ \
|
find /data/ -type f \
|
||||||
$dirExcludes \
|
|
||||||
-type f \
|
|
||||||
\( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" \
|
\( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" \
|
||||||
-or -name "*.conf" -or -name "*.properties" \) \
|
-or -name "*.conf" -or -name "*.properties" \) \
|
||||||
$fileExcludes \
|
$findExcludes \
|
||||||
-exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \;
|
-exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \;
|
||||||
fi
|
fi
|
||||||
done < <(env)
|
done < <(env)
|
||||||
|
|||||||
+24
-42
@@ -18,60 +18,42 @@ fi
|
|||||||
|
|
||||||
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
|
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
|
||||||
if [[ "$MODPACK" ]]; then
|
if [[ "$MODPACK" ]]; then
|
||||||
if isURL "${MODPACK}"; then
|
EFFECTIVE_MODPACK_URL=$(curl -Ls -o /dev/null -w %{url_effective} $MODPACK)
|
||||||
if [[ "${MODPACK}" == *.zip ]]; then
|
case "X$EFFECTIVE_MODPACK_URL" in
|
||||||
downloadUrl="${MODPACK}"
|
X[Hh][Tt][Tt][Pp]*.zip)
|
||||||
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 "Downloading mod/plugin pack via HTTP"
|
||||||
log " from $downloadUrl ..."
|
log " from $EFFECTIVE_MODPACK_URL ..."
|
||||||
if ! curl -sSL -o /tmp/modpack.zip "$downloadUrl"; then
|
if ! curl -sSL -o /tmp/modpack.zip "$EFFECTIVE_MODPACK_URL"; then
|
||||||
log "ERROR: failed to download from $downloadUrl"
|
log "ERROR: failed to download from $EFFECTIVE_MODPACK_URL"
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$TYPE" = "SPIGOT" ]; then
|
if [ "$TYPE" = "SPIGOT" ]; then
|
||||||
mkdir -p /data/plugins
|
mkdir -p /data/plugins
|
||||||
if ! unzip -o -d /data/plugins /tmp/modpack.zip; then
|
if ! unzip -o -d /data/plugins /tmp/modpack.zip; then
|
||||||
log "ERROR: failed to unzip the modpack from $downloadUrl"
|
log "ERROR: failed to unzip the modpack from $EFFECTIVE_MODPACK_URL"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
mkdir -p /data/mods
|
mkdir -p /data/mods
|
||||||
if ! unzip -o -d /data/mods /tmp/modpack.zip; then
|
if ! unzip -o -d /data/mods /tmp/modpack.zip; then
|
||||||
log "ERROR: failed to unzip the modpack from $downloadUrl"
|
log "ERROR: failed to unzip the modpack from $EFFECTIVE_MODPACK_URL"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
rm -f /tmp/modpack.zip
|
rm -f /tmp/modpack.zip
|
||||||
|
;;
|
||||||
else
|
*)
|
||||||
log "ERROR Invalid URL given for MODPACK: $MODPACK"
|
log "Invalid URL given for modpack: Must be HTTP or HTTPS and a ZIP file"
|
||||||
exit 1
|
;;
|
||||||
fi
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If supplied with a URL for a plugin download it.
|
# If supplied with a URL for a plugin download it.
|
||||||
if [[ "$MODS" ]]; then
|
if [[ "$MODS" ]]; then
|
||||||
for i in ${MODS//,/ }
|
for i in ${MODS//,/ }
|
||||||
do
|
do
|
||||||
if isURL $i; then
|
EFFECTIVE_MOD_URL=$(curl -Ls -o /dev/null -w %{url_effective} $i)
|
||||||
if [[ $i == *.jar ]]; then
|
case "X$EFFECTIVE_MOD_URL" in
|
||||||
EFFECTIVE_MOD_URL=$i
|
X[Hh][Tt][Tt][Pp]*.jar)
|
||||||
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 "Downloading mod/plugin via HTTP"
|
||||||
log " from $EFFECTIVE_MOD_URL ..."
|
log " from $EFFECTIVE_MOD_URL ..."
|
||||||
if ! curl -sSL -o /tmp/${EFFECTIVE_MOD_URL##*/} $EFFECTIVE_MOD_URL; then
|
if ! curl -sSL -o /tmp/${EFFECTIVE_MOD_URL##*/} $EFFECTIVE_MOD_URL; then
|
||||||
@@ -87,12 +69,12 @@ if [[ "$MODS" ]]; then
|
|||||||
mv /tmp/${EFFECTIVE_MOD_URL##*/} /data/mods/${EFFECTIVE_MOD_URL##*/}
|
mv /tmp/${EFFECTIVE_MOD_URL##*/} /data/mods/${EFFECTIVE_MOD_URL##*/}
|
||||||
fi
|
fi
|
||||||
rm -f /tmp/${EFFECTIVE_MOD_URL##*/}
|
rm -f /tmp/${EFFECTIVE_MOD_URL##*/}
|
||||||
|
;;
|
||||||
else
|
*)
|
||||||
log "ERROR Invalid URL given in MODS: $i"
|
log "Invalid URL given for modpack: Must be HTTP or HTTPS and a JAR file"
|
||||||
exit 1
|
;;
|
||||||
fi
|
esac
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$MANIFEST" ]]; then
|
if [[ "$MANIFEST" ]]; then
|
||||||
|
|||||||
+41
-37
@@ -88,6 +88,23 @@ if [ -n "$JVM_DD_OPTS" ]; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if isTrue ${TUNE_VIRTUALIZED}; then
|
||||||
|
JVM_XX_OPTS="${JVM_XX_OPTS} -Xtune:virtualized"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isTrue ${TUNE_NURSERY_SIZES}; then
|
||||||
|
case ${MAX_MEMORY^^} in
|
||||||
|
*G)
|
||||||
|
MAX_MEMORY_MB=$(( ${MAX_MEMORY%?} * 1024 )) ;;
|
||||||
|
*M)
|
||||||
|
MAX_MEMORY_MB=${MAX_MEMORY%?} ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
NURSERY_MINIMUM=$(( ${MAX_MEMORY_MB} / 2 ))
|
||||||
|
NURSERY_MAXIMUM=$(( ${MAX_MEMORY_MB} * 4/5 ))
|
||||||
|
JVM_XX_OPTS="${JVM_XX_OPTS} -Xmns${NURSERY_MINIMUM}M -Xmnx${NURSERY_MAXIMUM}M"
|
||||||
|
fi
|
||||||
|
|
||||||
if isTrue ${ENABLE_JMX}; then
|
if isTrue ${ENABLE_JMX}; then
|
||||||
: ${JMX_HOST:=0.0.0.0}
|
: ${JMX_HOST:=0.0.0.0}
|
||||||
: ${JMX_PORT:=7091}
|
: ${JMX_PORT:=7091}
|
||||||
@@ -158,60 +175,46 @@ if isTrue "${DEBUG_MEMORY}"; then
|
|||||||
free -m
|
free -m
|
||||||
fi
|
fi
|
||||||
|
|
||||||
JVM_OPTS="-Xms${INIT_MEMORY} -Xmx${MAX_MEMORY} ${JVM_OPTS}"
|
|
||||||
|
|
||||||
function copyFilesForCurseForge() {
|
|
||||||
# copy player modification files unconditionally since their
|
|
||||||
# processing into json is additive anyway
|
|
||||||
[ -f /data/ops.txt ] && cp -f /data/ops.txt ${FTB_DIR}/
|
|
||||||
[ -f /data/white-list.txt ] && cp -f /data/white-list.txt ${FTB_DIR}/
|
|
||||||
|
|
||||||
if [ ! -e "${FTB_DIR}/server-icon.png" -a -e /data/server-icon.png ]; then
|
|
||||||
cp -f /data/server-icon.png ${FTB_DIR}/
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp -f /data/eula.txt "${FTB_DIR}/"
|
|
||||||
}
|
|
||||||
|
|
||||||
mcServerRunnerArgs="--stop-duration 60s"
|
mcServerRunnerArgs="--stop-duration 60s"
|
||||||
if [[ ${TYPE} == "CURSE_INSTANCE" ]]; then
|
if [[ ${TYPE} == "CURSE_INSTANCE" ]]; then
|
||||||
|
JVM_OPTS="-Xms${INIT_MEMORY} -Xmx${MAX_MEMORY} ${JVM_OPTS}"
|
||||||
if isTrue ${DEBUG_EXEC}; then
|
if isTrue ${DEBUG_EXEC}; then
|
||||||
set -x
|
set -x
|
||||||
fi
|
fi
|
||||||
exec mc-server-runner ${mcServerRunnerArgs} \
|
exec mc-server-runner ${mcServerRunnerArgs} \
|
||||||
--cf-instance-file "${CURSE_INSTANCE_JSON}" \
|
--cf-instance-file "${CURSE_INSTANCE_JSON}" \
|
||||||
java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar _SERVERJAR_ "$@" $EXTRA_ARGS
|
java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar _SERVERJAR_ "$@" $EXTRA_ARGS
|
||||||
elif [[ ${TYPE} == "FEED-THE-BEAST" && "${SERVER}" ]]; then
|
|
||||||
copyFilesForCurseForge
|
|
||||||
|
|
||||||
cd "${FTB_DIR}"
|
|
||||||
log "Starting CurseForge server in ${FTB_DIR}..."
|
|
||||||
if isTrue ${DEBUG_EXEC}; then
|
|
||||||
set -x
|
|
||||||
fi
|
|
||||||
exec mc-server-runner ${bootstrapArgs} ${mcServerRunnerArgs} java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar $(basename "${SERVER}") "$@" $EXTRA_ARGS
|
|
||||||
elif [[ ${TYPE} == "FEED-THE-BEAST" ]]; then
|
elif [[ ${TYPE} == "FEED-THE-BEAST" ]]; then
|
||||||
mcServerRunnerArgs="${mcServerRunnerArgs} --shell bash"
|
mcServerRunnerArgs="${mcServerRunnerArgs} --shell bash"
|
||||||
|
|
||||||
copyFilesForCurseForge
|
# copy player modification files unconditionally since their
|
||||||
|
# processing into json is additive anyway
|
||||||
|
[ -f /data/ops.txt ] && cp -f /data/ops.txt ${FTB_DIR}/
|
||||||
|
[ -f /data/white-list.txt ] && cp -f /data/white-list.txt ${FTB_DIR}/
|
||||||
|
|
||||||
cat > "${FTB_DIR}/settings-local.sh" <<EOF
|
if [ ! -e "${FTB_DIR}/server-icon.png" -a -e /data/server-icon.png ]; then
|
||||||
|
cp -f /data/server-icon.png ${FTB_DIR}/
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp -f /data/eula.txt "${FTB_DIR}/"
|
||||||
|
|
||||||
|
cat > "${FTB_DIR}/settings-local.sh" <<EOF
|
||||||
export MIN_RAM="${INIT_MEMORY}"
|
export MIN_RAM="${INIT_MEMORY}"
|
||||||
export MAX_RAM="${MAX_MEMORY}"
|
export MAX_RAM="${MAX_MEMORY}"
|
||||||
export JAVA_PARAMETERS="${JVM_XX_OPTS} -Xms${INIT_MEMORY} ${JVM_OPTS} $expandedDOpts"
|
export JAVA_PARAMETERS="${JVM_XX_OPTS} -Xms${INIT_MEMORY} ${JVM_OPTS} $expandedDOpts"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# patch CurseForge cfg file, if present
|
# patch CurseForge cfg file, if present
|
||||||
if [ -f "${FTB_DIR}/settings.cfg" ]; then
|
if [ -f "${FTB_DIR}/settings.cfg" ]; then
|
||||||
sed -i "s/MAX_RAM=[^;]*/MAX_RAM=${MAX_MEMORY}/" "${FTB_DIR}/settings.cfg"
|
sed -i "s/MAX_RAM=[^;]*/MAX_RAM=${MAX_MEMORY}/" "${FTB_DIR}/settings.cfg"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd "${FTB_DIR}"
|
cd "${FTB_DIR}"
|
||||||
log "Running FTB ${FTB_SERVER_START} in ${FTB_DIR} ..."
|
log "Running FTB ${FTB_SERVER_START} in ${FTB_DIR} ..."
|
||||||
if isTrue ${DEBUG_EXEC}; then
|
if isTrue ${DEBUG_EXEC}; then
|
||||||
set -x
|
set -x
|
||||||
fi
|
fi
|
||||||
exec mc-server-runner ${mcServerRunnerArgs} "${FTB_SERVER_START}"
|
exec mc-server-runner ${mcServerRunnerArgs} "${FTB_SERVER_START}"
|
||||||
else
|
else
|
||||||
# If we have a bootstrap.txt file... feed that in to the server stdin
|
# If we have a bootstrap.txt file... feed that in to the server stdin
|
||||||
if [ -f /data/bootstrap.txt ]; then
|
if [ -f /data/bootstrap.txt ]; then
|
||||||
@@ -219,6 +222,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
log "Starting the Minecraft server..."
|
log "Starting the Minecraft server..."
|
||||||
|
JVM_OPTS="-Xms${INIT_MEMORY} -Xmx${MAX_MEMORY} ${JVM_OPTS}"
|
||||||
if isTrue ${DEBUG_EXEC}; then
|
if isTrue ${DEBUG_EXEC}; then
|
||||||
set -x
|
set -x
|
||||||
fi
|
fi
|
||||||
|
|||||||
-13
@@ -108,17 +108,4 @@ requireVar() {
|
|||||||
log "ERROR: $1 is required to be set"
|
log "ERROR: $1 is required to be set"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ -z "${!1}" ]; then
|
|
||||||
log "ERROR: $1 is required to be set"
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user