mirror of
https://github.com/itzg/docker-minecraft-server.git
synced 2026-07-06 16:45:11 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 81e1cd8cfd | |||
| 8387e9bd26 | |||
| 4afdb289c0 | |||
| fe637353d8 | |||
| 9160501f0a | |||
| 6eba5062ec | |||
| fc96723db1 | |||
| 8d3e461b4c | |||
| fd73417411 | |||
| 1207b9a685 | |||
| e6259bfd9d | |||
| b5e7b952e4 | |||
| ac5b960182 | |||
| 3299dec733 | |||
| 578f06087f | |||
| fb364e8301 |
@@ -1,25 +0,0 @@
|
|||||||
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,5 +1,4 @@
|
|||||||
data
|
data
|
||||||
testdata
|
|
||||||
examples
|
examples
|
||||||
k8s-examples
|
k8s-examples
|
||||||
.idea
|
.idea
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
name: Build and publish multiarch
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- multiarch
|
|
||||||
tags:
|
|
||||||
- "[0-9]+.[0-9]+.[0-9]+-multiarch"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
docker-buildx:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2.2.0
|
|
||||||
- name: Get branch name
|
|
||||||
uses: nelonoel/branch-name@v1
|
|
||||||
- name: Docker Buildx
|
|
||||||
uses: ilteoood/docker_buildx@1.0.4
|
|
||||||
with:
|
|
||||||
publish: true
|
|
||||||
imageName: itzg/minecraft-server
|
|
||||||
tag: ${{ env.BRANCH_NAME }}
|
|
||||||
dockerHubUser: ${{ secrets.DOCKER_USER }}
|
|
||||||
dockerHubPassword: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
FROM adoptopenjdk/openjdk8-openj9:alpine
|
FROM adoptopenjdk/openjdk13:alpine-jre
|
||||||
|
|
||||||
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
|
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -1069,14 +1056,6 @@ 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
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -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
|
||||||
|
|
||||||
|
|
||||||
@@ -103,7 +109,7 @@ case "${TYPE^^}" in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
FTB|CURSEFORGE)
|
FTB|CURSEFORGE)
|
||||||
exec ${SCRIPTS:-/}start-deployCF "$@"
|
exec ${SCRIPTS:-/}start-deployFTB "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
VANILLA)
|
VANILLA)
|
||||||
|
|||||||
+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
|
||||||
|
|||||||
@@ -88,23 +88,6 @@ 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}
|
||||||
|
|||||||
@@ -113,12 +113,3 @@ requireVar() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
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