Compare commits

...

114 Commits

Author SHA1 Message Date
Geoff Bourne
9690832247 Auto-merging via docker-versions-create 2021-04-01 16:39:46 -05:00
Geoff Bourne
60a68963a8 Added git
#819
2021-04-01 16:28:50 -05:00
Geoff Bourne
7aa47e2a60 Remove existing world data when FORCE_WORLD_COPY (#816) 2021-03-29 21:14:21 -05:00
Geoff Bourne
327538a98f docs: shifted timezone info later 2021-03-27 18:49:58 -05:00
Geoff Bourne
f6c71e27d8 docs: described converting anonymous data volume 2021-03-27 18:47:42 -05:00
Geoff Bourne
4628da7ea2 docs: Fixed alternate exposed port example 2021-03-27 18:39:22 -05:00
Geoff Bourne
02ba96c421 docs: Added -it to initial examples 2021-03-27 18:38:43 -05:00
Geoff Bourne
87f6fe6b20 Fixed $LEVEL path in directory structure diagram 2021-03-26 19:11:38 -05:00
Geoff Bourne
8049bd5b80 docs: Lots of cleanup about /data path and management of mods and plugins related to that 2021-03-21 15:35:12 -05:00
Geoff Bourne
5225ba06c8 Added support for spiget to download Spigot/Bukkit/Paper plugins
#808
2021-03-21 11:43:21 -05:00
Geoff Bourne
d695fc3fbc Disable whitelist server property when WHITELIST empty and overriding
#806
2021-03-21 10:12:35 -05:00
Geoff Bourne
a2132292ac Separated OVERRIDE_OPS|WHITELIST from OPS|WHITELIST logic
#806
2021-03-18 20:00:30 -05:00
Geoff Bourne
c31b191b96 Removed "dot output" when running forge installer for CF modpacks
#800
2021-03-18 19:56:40 -05:00
Geoff Bourne
c4b573f608 docs: Clarified disabling of max tick watchdog for autopause
#555
2021-03-14 16:18:43 -05:00
Geoff Bourne
28810fcba3 Added support for CF modpacks using settings.cfg
#772 #800
2021-03-14 15:03:27 -05:00
Geoff Bourne
8d1989a595 docs: Added more info about getbukkit's weird 1.8 file naming
#103
2021-03-13 16:55:50 -06:00
miki164
d022956e24 Fix typo in example docker-compose (#803) 2021-03-13 06:52:14 -06:00
Geoff Bourne
2bdaa4dc4e Updated java8 warning message for ClassCastException
#775
2021-03-12 17:22:54 -06:00
Geoff Bourne
46bfbaada1 Upgraded mc-monitor to 0.7.1 to fix ProtocolSupport response
#796
2021-03-12 09:27:44 -06:00
Geoff Bourne
e659343821 Improved locating of forge server jar created by installer
#799
2021-03-11 19:40:11 -06:00
Geoff Bourne
44138564b0 Added debug output for deployCustom
#799
2021-03-11 16:29:21 -06:00
Geoff Bourne
3c77abbbab Added debug output for deployForge and minecraftFinalSetup
#799
2021-03-11 16:21:59 -06:00
Geoff Bourne
209c6e6dab Added explicit -dir for Fabric installer
#797
2021-03-11 15:36:34 -06:00
Geoff Bourne
6fa827e9a1 Fixed usage of EXTRA_ARGS
#798
2021-03-11 15:08:26 -06:00
Geoff Bourne
cd3ea7fd2e Upgraded mc-monitor to 0.7.0
#795
2021-03-09 22:13:33 -06:00
Geoff Bourne
d3bd697cb2 Fixed warning reported when no paper jars to remove 2021-03-09 22:05:21 -06:00
Geoff Bourne
6c6bf030c5 docs: Added troubleshooting info for rpi
#795
2021-03-07 13:06:45 -06:00
Geoff Bourne
6e2b3ae0c7 docs: Added java15-openj9 2021-03-06 17:31:16 -06:00
Geoff Bourne
9915929340 ci: Added java15-openj9 2021-03-06 16:53:46 -06:00
Geoff Bourne
6ae431b2f0 Merge branch 'master' into java15 2021-03-06 16:25:21 -06:00
Geoff Bourne
ebabfeb669 Shifted PATH-fix earlier in startup 2021-03-06 16:05:01 -06:00
Geoff Bourne
5c1f176848 Shifted PATH-fix earlier in startup 2021-03-06 16:03:37 -06:00
Geoff Bourne
457e9b53c7 Auto-merging via docker-versions-create 2021-02-27 20:55:30 -06:00
Geoff Bourne
861aec6bd6 Added option for MOHIST_BUILD
#781
2021-02-27 20:37:59 -06:00
Geoff Bourne
21572d3547 Ensure FTBA version.json is readable
#784
2021-02-27 17:03:37 -06:00
Geoff Bourne
53f5fbb77f docs: Fixed examples of quoting SEED and MOTD
#782
2021-02-27 11:05:16 -06:00
Geoff Bourne
9299f00d20 Pre-process special characters in REPLACE_ENV_VARIABLES
#718
2021-02-25 19:07:16 -06:00
Geoff Bourne
e5e97a3560 Use file to speed up removal of old PaperMC server jars
#779
2021-02-23 20:04:34 -06:00
Geoff Bourne
32bc0382d6 Only show skipped properties when debugging 2021-02-21 14:36:03 -06:00
Geoff Bourne
fa53abdfb7 Add missing server.properties when needed
#776
2021-02-21 14:32:41 -06:00
Geoff Bourne
0cbfb81b4c misc: Removed debug 2021-02-20 17:35:26 -06:00
Geoff Bourne
d47c801b18 Separated JMX_BINDING from JMX_HOST in ENABLE_JMX usage 2021-02-20 17:34:00 -06:00
Geoff Bourne
c056b9d2dd Improved handling of ENV_VARIABLE_PREFIX
#718
2021-02-20 17:30:50 -06:00
Geoff Bourne
92a15ea85d Updated forge examples to use java8 image
#770
2021-02-15 10:21:42 -06:00
Fersandi Pratama
6fe022ccc8 Fix README: volume should be in list (#767) 2021-02-13 12:24:58 -06:00
Geoff Bourne
b71eb666a7 Fix PATH to include java when needed
#749
2021-02-10 15:11:07 -06:00
Geoff Bourne
b176be942d Fix PATH to include java when needed 2021-02-10 14:52:16 -06:00
Geoff Bourne
a2ab0d75ed Fix PATH to include java when needed 2021-02-10 14:46:09 -06:00
Geoff Bourne
51c5902db0 Merge from master
CONFLICT (content): Merge conflict in start-configuration
2021-02-10 14:06:10 -06:00
Geoff Bourne
c48f6c31ce Missing EULA failed without proper log message
#749
2021-02-10 13:57:14 -06:00
Geoff Bourne
b2d23edf6d ci: Added pull:true to multiarch build 2021-02-08 21:27:25 -06:00
Geoff Bourne
31f25cfd1b Added java8 recommendation to CURSEFORGE / FTB 2021-02-08 21:15:28 -06:00
Geoff Bourne
7d4e4c167e Added support for Yatopia
#704
2021-02-08 20:42:54 -06:00
Geoff Bourne
090e624ebc Auto-merging via docker-versions-create
CONFLICT (content): Merge conflict in Dockerfile
2021-02-07 18:20:35 -06:00
LichLord91
eb12030975 Update Invalid Server Type Logging Message (#758)
Includes Tuinity and Purpur

Co-authored-by: lichlord91 <lichlord91@users.noreply.github.com>
2021-02-07 18:00:53 -06:00
Geoff Bourne
e46af9d54c Fixed vanilla version lookup to fail early
#756
2021-02-07 17:58:50 -06:00
Geoff Bourne
861faaa285 Trimmed back some ENV defaults from Dockerfile 2021-02-07 17:52:42 -06:00
Geoff Bourne
8312233a93 Added support for Purpur servers
#746
2021-02-07 11:22:08 -06:00
Geoff Bourne
959bf73485 Limit depth when finding old PaperMC server jars
Fixes #750
2021-02-07 09:26:37 -06:00
Geoff Bourne
c8dc751b82 Auto-merging docker-versions-create.sh
CONFLICT (content): Merge conflict in Dockerfile
2021-02-07 09:15:01 -06:00
Geoff Bourne
beeaf1a996 ci: Added java8-multiarch to build and docs 2021-02-06 15:48:27 -06:00
Geoff Bourne
96aa1054dc Upgraded mainline/latest to Java 11 2021-02-06 15:21:20 -06:00
Geoff Bourne
7c862df92a Merge branch 'master' into java15 2021-02-06 15:12:45 -06:00
Geoff Bourne
e7937206af ci: Added java15 to multiarch build 2021-02-06 15:12:34 -06:00
Geoff Bourne
e49c1c2f01 Merge branch 'master' into java15 2021-02-06 15:11:34 -06:00
Geoff Bourne
081b2c11e4 ci: Introduced java15 branch
ci: Deprecated adopt13, adopt14, openj9-nightly
2021-02-06 15:11:03 -06:00
Geoff Bourne
f342f4aa98 ci: Introduced java15 branch
ci: Deprecated adopt13, adopt14, openj9-nightly
2021-02-06 15:07:42 -06:00
Geoff Bourne
57390b02ca Merge branch 'master' into java15 2021-02-06 14:53:02 -06:00
Geoff Bourne
4e73e69342 ci: Added build-multiarch.yml to align merges 2021-02-06 14:52:20 -06:00
Geoff Bourne
a698248dff ci: Based on adoptopenjdk:15-jre 2021-02-06 14:50:43 -06:00
Geoff Bourne
c6ff80b71c docs: Clarify MEMORY limits vs overall container memory
Related to #691
2021-02-01 21:15:33 -06:00
M*C*O
37cad3f255 docs: Document LEVEL_TYPE: BIOMESOP (#741) 2021-02-01 12:39:55 -06:00
Geoff Bourne
5700f36a6f Renamed forge branch to java8 2021-01-30 18:49:46 -06:00
Geoff Bourne
34f800d815 ci: Added forge branch to builds 2021-01-30 16:02:15 -06:00
Geoff Bourne
b8ef6eba3f Auto-merging via docker-versions-create 2021-01-29 21:07:29 -06:00
Geoff Bourne
ffec50141a Fixed MODS provides from github release URLs
For #731
2021-01-28 20:55:08 -06:00
Geoff Bourne
54027049d3 docs: Added compose example to data attaching section 2021-01-24 12:31:56 -06:00
Geoff Bourne
4c2829e3d2 docs: Added a simple docker compose example 2021-01-21 13:36:41 -06:00
Geoff Bourne
69e308d420 Split eula header into two lines of comments
#728
- Found that https://github.com/Yoosk/ServerStarter hard coded expectation that eula property was on third line
2021-01-19 21:36:21 -06:00
Geoff Bourne
ad46f10b55 Added option to override whitelist and ops files
#726
2021-01-17 10:09:41 -06:00
Eugene
cd0fdfc95b Add an option to override the icon which already has been set. (#723) 2021-01-13 16:47:15 -06:00
Geoff Bourne
d95abfce82 ci: Added openj9-11 tags pattern 2021-01-12 17:33:03 -06:00
Geoff Bourne
942a125e04 ci: Added non-versioned cache as restore-key fallback 2021-01-12 17:30:58 -06:00
Geoff Bourne
cc5fe0859a Auto-merging via docker-versions-create 2021-01-12 17:28:33 -06:00
Geoff Bourne
a3677d5aa8 ci: Enabled pull in build step 2021-01-12 17:20:57 -06:00
Geoff Bourne
f927933c46 Added openj9 JDK11 variant
For #721
2021-01-12 17:18:08 -06:00
Geoff Bourne
8f15aac6fc Merge branch 'multiarch' into multiarch-latest 2021-01-12 17:06:00 -06:00
Michael Kirsch
b519c43e16 fix multiarch autopause daemon (#722) 2021-01-12 16:05:12 -06:00
Geoff Bourne
5ab83bcb21 ci: Switched build to docker/build-push-action@v2 2021-01-09 14:13:18 -06:00
Geoff Bourne
84ce3b4b47 Merge branch 'multiarch' into multiarch-latest 2021-01-09 14:07:31 -06:00
Geoff Bourne
02c8393bc6 ci: Added opencontainers labels 2021-01-09 14:07:05 -06:00
Geoff Bourne
b07c43a32f Merge branch 'multiarch' into multiarch-latest 2021-01-09 12:31:20 -06:00
Geoff Bourne
9469291731 ci: Switched multiarch build caching to github actions 2021-01-09 12:28:27 -06:00
Geoff Bourne
ce1b337f7f Auto-merging via docker-versions-create 2021-01-09 11:25:38 -06:00
Geoff Bourne
c29baf446d Auto-merging via docker-versions-create 2021-01-09 11:24:53 -06:00
Dubhar
fdf5fb46bc fix/681 (#719)
* [shellcheck] prevent globbing

* fix/681 remove old PaperMC before downloading new

Fixes #681 

Co-authored-by: Dubhar <thorsten.jerosch@gmail.com>
2021-01-09 11:03:21 -06:00
Geoff Bourne
8c6ca5e999 Restored the ability for PAPERBUILD to be used with TYPE=PAPER
For #715
2021-01-07 20:03:42 -06:00
Geoff Bourne
bb2b9eeea9 docs: Changed FORGEVERSION example to use a valid combination
For #716
2021-01-07 11:02:19 -06:00
Geoff Bourne
d1cbce3f89 docs: Clarified usage of VERSION with FORGE type
For #716
2021-01-06 22:49:22 -06:00
Geoff Bourne
55b5f6821f Fixed ops and white-list setup for CurseForge modpacks named with spaces
For #717
2021-01-06 22:38:18 -06:00
Geoff Bourne
ee8e1b9322 Merged latest from master 2021-01-06 22:16:40 -06:00
Geoff Bourne
20bd5c4c36 Merge branch 'multiarch' into multiarch-latest 2020-12-31 13:19:34 -06:00
Geoff Bourne
de082d0fb2 Merge branch 'multiarch' into multiarch-latest 2020-12-28 11:44:41 -06:00
Geoff Bourne
3cc5cdbc06 Auto-merging via docker-versions-create 2020-12-27 22:08:29 -06:00
Geoff Bourne
b69ec47b18 Auto-merging via docker-versions-create 2020-12-19 08:26:49 -06:00
Geoff Bourne
51fc8e824d Auto-merging via docker-versions-create 2020-12-15 14:00:33 -06:00
Geoff Bourne
aff9031284 Merge branch 'multiarch' into multiarch-latest 2020-11-26 08:46:26 -06:00
Geoff Bourne
397d080da2 Merge branch 'multiarch' into multiarch-latest 2020-11-25 21:36:48 -06:00
Geoff Bourne
cb5d052829 Merge branch 'multiarch' into multiarch-latest
# Conflicts:
#	.github/workflows/build-multiarch.yml
2020-11-25 16:09:23 -06:00
Geoff Bourne
0908d21bed Merged from master 2020-11-25 16:01:42 -06:00
Marc Doughty
4d878985d4 Remove distro-provided JRE (#659)
We don't need Java 8 from Ubuntu, we have 15 from AdoptOpenJDK.
2020-11-03 06:33:19 -06:00
Geoff Bourne
72d7d4a65e Switched to latest Docker buildx github action 2020-10-31 14:48:51 -05:00
Geoff Bourne
cb0add3b90 Added github action match for multiarch-latest branch 2020-10-31 13:38:44 -05:00
Marc Doughty
71a48ce10f Convert to AdoptOpenJDK (#658) 2020-10-31 13:36:47 -05:00
34 changed files with 830 additions and 401 deletions

View File

@@ -3,15 +3,19 @@ on:
push:
branches:
- multiarch
- java8-multiarch
- multiarch-latest
- "test-multiarch-.*"
- java15
- java15-openj9
- test/multiarch/*
tags:
- "[0-9]+.[0-9]+.[0-9]+-multiarch"
- "[0-9]+.[0-9]+.[0-9]+-multiarch-latest"
- "[0-9]+.[0-9]+.[0-9]+-java15"
jobs:
docker-buildx:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2.2.0
@@ -30,13 +34,23 @@ jobs:
VERSION=latest
fi
fi
TAGS="${DOCKER_IMAGE}:${VERSION}"
TAGS="${DOCKER_IMAGE}:${VERSION//\//-}"
echo ::set-output name=tags::${TAGS}
echo ::set-output name=cache_from::${TAGS}
echo ::set-output name=version::${VERSION//\//-}
echo ::set-output name=cache_version::${VERSION//\//-}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ steps.prep.outputs.cache_version }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-${{ steps.prep.outputs.cache_version }}-
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
@@ -55,8 +69,15 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
cache-from: type=registry,ref=${{ steps.prep.outputs.cache_from }}
cache-to: type=inline
# ensure latest base image is used
pull: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
labels: |
org.opencontainers.image.documentation=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.source=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

View File

@@ -4,24 +4,22 @@ on:
push:
branches:
- master
- java8
- openj9
- openj9-nightly
- openj9-11
- adopt11
- adopt13
- adopt14
- adopt15
- test/*
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-java8"
- "[0-9]+.[0-9]+.[0-9]+-openj9"
- "[0-9]+.[0-9]+.[0-9]+-openj9-11"
- "[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"
- "[0-9]+.[0-9]+.[0-9]+-adopt15"
jobs:
test:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
@@ -32,20 +30,68 @@ jobs:
build:
needs:
- test
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Build and push Docker images
uses: docker/build-push-action@v1.1.0
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=itzg/minecraft-server
VERSION=edge
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
fi
if [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=${GITHUB_REF#refs/heads/}
if [[ $VERSION == master ]]; then
VERSION=latest
fi
fi
TAGS="${DOCKER_IMAGE}:${VERSION//\//-}"
echo ::set-output name=tags::${TAGS}
echo ::set-output name=cache_from::${TAGS}
echo ::set-output name=version::${VERSION//\//-}
echo ::set-output name=cache_version::${VERSION//\//-}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ steps.prep.outputs.cache_version }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-${{ steps.prep.outputs.cache_version }}-
${{ runner.os }}-buildx-
- name: Login to DockerHub
uses: docker/login-action@v1
with:
repository: itzg/minecraft-server
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
tag_with_ref: true
tag_with_sha: false
cache_froms: itzg/minecraft-server:latest
add_git_labels: true
labels: org.opencontainers.image.url=https://github.com/itzg/docker-minecraft-server,org.opencontainers.image.documentation=https://github.com/itzg/docker-minecraft-server
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
# ensure latest base image is used
pull: true
# publish
push: true
# tags determined by prep step
tags: ${{ steps.prep.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
labels: |
org.opencontainers.image.documentation=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
org.opencontainers.image.source=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.revision=${{ github.sha }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

View File

@@ -1,16 +1,16 @@
FROM ubuntu:18.04
FROM adoptopenjdk:15-jre
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
openjdk-8-jre-headless \
imagemagick \
gosu \
sudo \
net-tools \
curl wget \
git \
jq \
dos2unix \
mysql-client \
@@ -48,7 +48,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=0.1.7 --var app=mc-monitor --file {{.app}} \
--var version=0.7.1 --var app=mc-monitor --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} \
@@ -68,9 +68,9 @@ WORKDIR /data
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 \
LEVEL_TYPE=DEFAULT SERVER_PORT=25565 ONLINE_MODE=TRUE SERVER_NAME="Dedicated Server" \
TYPE=VANILLA VERSION=LATEST \
ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \
SERVER_PORT=25565 ONLINE_MODE=TRUE SERVER_NAME="Dedicated Server" \
ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 \
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0

581
README.md
View File

@@ -11,21 +11,21 @@ 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 -e EULA=TRUE itzg/minecraft-server
docker run -d -it -p 25565:25565 -e EULA=TRUE itzg/minecraft-server
where the standard server port, 25565, will be exposed on your host machine.
If you want to serve up multiple Minecraft servers or just use an alternate port,
change the host-side port mapping such as
docker run -p 25566:25565 ...
... -p 25566:25565 ...
will serve your Minecraft server on your host's port 25566 since the `-p` syntax is
`host-port`:`container-port`.
Speaking of multiple servers, it's handy to give your containers explicit names using `--name`, such as
Speaking of multiple servers, it's handy to give your containers explicit names using `--name`, such as naming this one "mc"
docker run -d -p 25565:25565 --name mc itzg/minecraft-server
... --name mc itzg/minecraft-server
With that you can easily view the logs, stop, or re-start the container:
@@ -35,7 +35,8 @@ 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.*
> Be sure to always include `-e EULA=TRUE` in your commands, as Mojang/Microsoft requires EULA acceptance.
## Looking for a Bedrock Dedicated Server
@@ -81,43 +82,59 @@ and attach from another machine:
Unless you're on a home/private LAN, you should [enable TLS access](https://docs.docker.com/articles/https/).
## EULA Support
## Data Directory
Mojang now requires accepting the [Minecraft EULA](https://account.mojang.com/documents/minecraft_eula). To accept add
Everything the container manages is located under the **container's** `/data` path, as shown here:
-e EULA=TRUE
![](docs/level-vs-world.drawio.png)
such as
> NOTE: The container path `/data` is pre-declared as a volume, so if you do nothing then it will be allocated as an anonymous volume. As such, it is subject to removal when the container is removed.
docker run -d -it -e EULA=TRUE -p 25565:25565 --name mc itzg/minecraft-server
### Attaching data directory to host filesystem
## Timezone Configuration
In most cases the easier way to persist and work with the minecraft data files is to use the `-v` argument to map a directory on your host machine to the container's `/data` directory, such as the following where `/home/user/minecraft-data` would be a directory of your choosing on your host machine:
You can configure the timezone to match yours by setting the `TZ` environment variable:
docker run -d -v /home/user/minecraft-data:/data ...
-e TZ=Europe/London
When attached in this way you can stop the server, edit the configuration under your attached directory and start the server again to pick up the new configuration.
such as:
With Docker Compose, setting up a host attached directory is even easier since relative paths can be configured. For example, with the following `docker-compose.yml` Docker will automatically create/attach the relative directory `minecraft-data` to the container.
docker run -d -it -e TZ=Europe/London -p 25565:25565 --name mc itzg/minecraft-server
```yaml
version: "3"
Or mounting `/etc/timezone` as readonly (not supported on Windows):
services:
mc:
image: itzg/minecraft-server
ports:
- 25565:25565
environment:
EULA: "TRUE"
volumes:
# attach a directory relative to the directory containing this compose file
- ./minecraft-data:/data
```
-v /etc/timezone:/etc/timezone:ro
### Converting anonymous `/data` volume to named volume
such as:
If you had used the commands in the first section, without the `-v` volume attachment, then an anonymous data volume was created by Docker. You can later bring over that content to a named or host attached volume using the following procedure.
docker run -d -it -v /etc/timezone:/etc/timezone:ro -p 25565:25565 --name mc itzg/minecraft-server
> In this example, it is assumed the original container was given a `--name` of "mc", so change the container identifier accordingly.
## Attaching data directory to host filesystem
First, stop the existing container:
```shell
docker stop mc
```
In order to readily access the Minecraft data, use the `-v` argument
to map a directory on your host machine to the container's `/data` directory, such as:
Use a temporary container to copy over the anonymous volume's content into a named volume, "mc" in this case:
```shell
docker run --rm --volumes-from mc -v mc:/new alpine cp -avT /data /new
```
docker run -d -v /path/on/host:/data ...
When attached in this way you can stop the server, edit the configuration under your attached `/path/on/host`
and start the server again with `docker start CONTAINERID` to pick up the new configuration.
Now you can recreate the container with any environment variable changes, etc by attaching the named volume created from the previous step:
```shell
docker run -d -it --name mc-new -v mc:/data -p 25565:25565 -e EULA=TRUE -e MEMORY=2G itzg/minecraft-server
```
## Versions
@@ -144,23 +161,32 @@ the server jar remain in the `/data` directory. It is safe to remove those._
To use a different version of Java, please use a docker tag to run your Minecraft server.
| Tag name | Description | Linux |
| -------------- | ------------------------------------------- | ------------ |
| latest | **Default**. Uses Java version 8 | Alpine Linux |
| adopt15 | Uses Java version 15 from AdoptOpenJDK | Alpine Linux |
| adopt14 | Uses Java version 14 from AdoptOpenJDK | Alpine Linux |
| adopt13 | Uses Java version 13 from AdoptOpenJDK | Alpine Linux |
| adopt11 | Uses Java version 11 from AdoptOpenJDK | Alpine Linux |
| openj9 | Uses Eclipse OpenJ9 JVM | Alpine Linux |
| openj9-nightly | Uses Eclipse OpenJ9 JVM testing builds | Alpine Linux |
| multiarch | Uses Java version 8 latest update | Debian Linux |
| multiarch-latest | Uses Java version 15 latest update | Debian Linux |
| Tag name | Java version | Linux | JVM Type | Architecture |
| -------------- | -------------|--------|----------|-------------------|
| latest | 11 | Alpine | Hotspot | amd64 |
| java8 | 8 | Alpine | Hotspot | amd64 |
| java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 |
| java15 | 15 | Debian | Hotspot | amd64,arm64,armv7 |
| java15-openj9 | 15 | Debian | OpenJ9 | amd64,arm64 |
| adopt11 | 11 | Alpine | Hotspot | amd64 |
| openj9 | 8 | Alpine | OpenJ9 | amd64 |
| openj9-11 | 11 | Alpine | OpenJ9 | amd64 |
| multiarch | 11 | Debian | Hotspot | amd64,arm64,armv7 |
| multiarch-latest | 15+ | Debian | Hotspot | amd64,arm64,armv7 |
For example, to use a Java version 13:
For example, to use Java version 15 on any supported architecture:
docker run --name mc itzg/minecraft-server:adopt13
docker run --name mc itzg/minecraft-server:java15
Keep in mind that some versions of Minecraft server can't work on the newest versions of Java. Also, FORGE doesn't support openj9 JVM implementation.
> Keep in mind that some versions of Minecraft server can't work on the newest versions of Java. Also, FORGE doesn't support openj9 JVM implementation.
### Deprecated Image Tags
The following image tags have been deprecated and are no longer receiving updates:
- adopt13
- adopt14
- adopt15
- openj9-nightly
## Healthcheck
@@ -182,44 +208,6 @@ healthy
Some orchestration systems, such as Portainer, don't allow for disabling the default `HEALTHCHECK` declared by this image. In those cases you can approximate the disabling of healthchecks by setting the environment variable `DISABLE_HEALTHCHECK` to `true`.
## Autopause
### Description
There are various bug reports on [Mojang](https://bugs.mojang.com) about high CPU usage of servers with newer versions, even with few or no clients connected (e.g. [this one](https://bugs.mojang.com/browse/MC-149018), in fact the functionality is based on [this comment in the thread](https://bugs.mojang.com/browse/MC-149018?focusedCommentId=593606&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-593606)).
An autopause functionality has been added to this image to monitor whether clients are connected to the server. If for a specified time no client is connected, the Java process is stopped. When knocking on the server port (e.g. by the ingame Multiplayer server overview), the process is resumed. The experience for the client does not change.
Of course, even loaded chunks are not ticked when the process is stopped.
From the server's point of view, the pausing causes a single tick to take as long as the process is stopped, so the server watchdog might intervene after the process is continued, possibly forcing a container restart. To prevent this, ensure that the `max-tick-time` in the `server.properties` file is set correctly. Non-vanilla versions might have their own configuration file, you might have to disable their watchdogs separately (e.g. PAPER Servers).
On startup the `server.properties` file is checked and, if applicable, a warning is printed to the terminal. When the server is created (no data available in the persistent directory), the properties file is created with the Watchdog disabled.
The utility used to wake the server (`knock(d)`) works at network interface level. So the correct interface has to be set using the `AUTOPAUSE_KNOCK_INTERFACE` variable when using non-default networking environments (e.g. host-networking, Portainer oder NAS solutions). See the description of the variable below.
A starting, example compose file has been provided in [examples/docker-compose-autopause.yml](examples/docker-compose-autopause.yml).
### Enabling Autopause
Enable the Autopause functionality by setting:
```
-e ENABLE_AUTOPAUSE=TRUE
```
The following environment variables define the behaviour of auto-pausing:
* `AUTOPAUSE_TIMEOUT_EST`, default `3600` (seconds)
describes the time between the last client disconnect and the pausing of the process (read as timeout established)
* `AUTOPAUSE_TIMEOUT_INIT`, default `600` (seconds)
describes the time between server start and the pausing of the process, when no client connects inbetween (read as timeout initialized)
* `AUTOPAUSE_TIMEOUT_KN`, default `120` (seconds)
describes the time between knocking of the port (e.g. by the main menu ping) and the pausing of the process, when no client connects inbetween (read as timeout knocked)
* `AUTOPAUSE_PERIOD`, default `10` (seconds)
describes period of the daemonized state machine, that handles the pausing of the process (resuming is done independently)
* `AUTOPAUSE_KNOCK_INTERFACE`, default `eth0`
<br>Describes the interface passed to the `knockd` daemon. If the default interface does not work, run the `ifconfig` command inside the container and derive the interface receiving the incoming connection from its output. The passed interface must exist inside the container. Using the loopback interface (`lo`) does likely not yield the desired results.
## Deployment Templates and Examples
### Helm Charts
@@ -237,12 +225,13 @@ If you're looking for a simple way to deploy this to the Amazon Web Services Clo
## Running a Forge Server
Enable Forge server mode by adding a `-e TYPE=FORGE` to your command-line.
By default the container will run the `RECOMMENDED` version of [Forge server](http://www.minecraftforge.net/wiki/)
but you can also choose to run a specific version with `-e FORGEVERSION=10.13.4.1448`.
Enable [Forge server](http://www.minecraftforge.net/wiki/) mode by adding a `-e TYPE=FORGE` to your command-line.
The overall version is specified by `VERSION`, [as described in the section above](#versions) and will run the recommended Forge version by default. You can also choose to run a specific Forge version with `FORGEVERSION`, such as `-e FORGEVERSION=14.23.5.2854`.
$ docker run -d -v /path/on/host:/data \
-e TYPE=FORGE -e FORGEVERSION=10.13.4.1448 \
-e TYPE=FORGE \
-e VERSION=1.12.2 -e FORGEVERSION=14.23.5.2854 \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
To use a pre-downloaded Forge installer, place it in the attached `/data` directory and
@@ -259,163 +248,23 @@ the URL with `FORGE_INSTALLER_URL`, such as:
In both of the cases above, there is no need for the `VERSION` or `FORGEVERSION` variables.
In order to add mods, you have two options.
### Managing mods
### Using the /data volume
In order to manage mods, you have two options:
This is the easiest way if you are using a persistent `/data` mount.
1. [Attach a host directory to the /data path](#attaching-data-directory-to-host-filesystem) and manage the contents of the `mods` subdirectory
To do this, you will need to attach the container's `/data` directory
(see "Attaching data directory to host filesystem”).
Then, you can add mods to the `/path/on/host/mods` folder you chose. From the example above,
the `/path/on/host` folder contents look like:
2. Using a mods-mount
```
/path/on/host
├── mods
│   └── ... INSTALL MODS HERE ...
├── config
│   └── ... CONFIGURE MODS HERE ...
├── ops.json
├── server.properties
├── whitelist.json
├── worlds
│   └── ... PLACE MAPS IN THEIR OWN FOLDERS HERE ...
└── ...
```
If the container paths `/mods` and/or `/config` exist, such as by attaching a docker volume or host path, then any files in either of these directories will be copied over to the respective `/data` subdirectory before starting Minecraft.
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 want old mods to be removed as the `/mods` content is updated, then add `-e REMOVE_OLD_MODS=TRUE`. You can fine tune the removal process by specifying the `REMOVE_OLD_MODS_INCLUDE` and `REMOVE_OLD_MODS_EXCLUDE` variables. By default, everything will be removed. You can also specify the `REMOVE_OLD_MODS_DEPTH` (default is 16) variable to only delete files up to a certain level.
For instance, imagine a scenario when the initial launch has completed, but you now want to change the worldmap for your server.
For example: `-e REMOVE_OLD_MODS=TRUE -e REMOVE_OLD_MODS_INCLUDE="*.jar" -e REMOVE_OLD_MODS_DEPTH=1` will remove all old jar files that are directly inside the `plugins/` or `mods/` directory.
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.
You can specify the destination of the files that are copied from `/config` by setting the `COPY_CONFIG_DEST` variable, where the default is `/data/config`. For example, `-v ./config:/config -e COPY_CONFIG_DEST=/data` will allow you to copy over files like `bukkit.yml` and so on directly into the server 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
docker start mc
### Using separate mounts
This is the easiest way if you are using an ephemeral `/data` filesystem,
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. If you want old mods to be removed as the `/mods` content is updated, then add `-e REMOVE_OLD_MODS=TRUE`. If you are running a `BUKKIT` distribution this will affect all files inside the `plugins/` directory. You can fine tune the removal process by specifing the `REMOVE_OLD_MODS_INCLUDE` and `REMOVE_OLD_MODS_EXCLUDE` variables. By default everything will be removed. You can also specify the `REMOVE_OLD_MODS_DEPTH` (default 16) variable to only delete files up to a certain level.
> For example: `-e REMOVE_OLD_MODS=TRUE -e REMOVE_OLD_MODS_INCLUDE="*.jar" -e REMOVE_OLD_MODS_DEPTH=1` will remove all old jar files that are directly inside the `plugins/` or `mods/` directory.
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.
You can specify the destination of the configs that are located inside the `/config` mount by setting the `COPY_CONFIG_DEST` variable. The configs are copied recursivly to the `/data/config` directory by default. If a file was updated directly inside the `/data/*` directoy and is newer than the file in the `/config/*` mount it will not be overriden.
> For example: `-v ./config:/config -e COPY_CONFIG_DEST=/data` will allow you to copy over your `bukkit.yml` and so on directly into the server directory.
### Replacing variables inside configs
Sometimes you have mods or plugins that require configuration information that is only available at runtime.
For example if you need to configure a plugin to connect to a database,
you don't want to include this information in your Git repository or Docker image.
Or maybe you have some runtime information like the server name that needs to be set
in your config files after the container starts.
For those cases there is the option to replace defined variables inside your configs
with environment variables defined at container runtime.
If you set the enviroment variable `REPLACE_ENV_VARIABLES` to `TRUE` the startup script
will go thru all files inside your `/data` volume and replace variables that match your
defined environment variables. Variables that you want to replace need to be wrapped
inside `${YOUR_VARIABLE}` curly brackets and prefixed with a dollar sign. This is the regular
syntax for enviromment variables inside strings or config files.
Optionally you can also define a prefix to only match predefined environment variables.
`ENV_VARIABLE_PREFIX="CFG_"` <-- this is the default prefix
If you want use file for value (like when use secrets) you can add suffix `_FILE` to your variable name (in run command).
There are some limitations to what characters you can use.
| Type | Allowed Characters |
| ----- | ------------------- |
| 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`.
Specific files can be excluded by listing their name (without path) in the variable `REPLACE_ENV_VARIABLES_EXCLUDES`.
Paths can be excluded by listing them in the variable `REPLACE_ENV_VARIABLES_EXCLUDE_PATHS`. Path
excludes are recursive. Here is an example:
```
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`.
```yml
---
database:
host: ${CFG_DB_HOST}
name: ${CFG_DB_NAME}
password: ${CFG_DB_PASSWORD}
```
This is how your `docker-compose.yml` file could look like:
```yml
version: "3"
# Other docker-compose examples in /examples
services:
minecraft:
image: itzg/minecraft-server
ports:
- "25565:25565"
volumes:
- "mc:/data"
environment:
EULA: "TRUE"
ENABLE_RCON: "true"
RCON_PASSWORD: "testing"
RCON_PORT: 28016
# enable env variable replacement
REPLACE_ENV_VARIABLES: "TRUE"
# define an optional prefix for your env variables you want to replace
ENV_VARIABLE_PREFIX: "CFG_"
# and here are the actual variables
CFG_DB_HOST: "http://localhost:3306"
CFG_DB_NAME: "minecraft"
CFG_DB_PASSWORD_FILE: "/run/secrets/db_password"
restart: always
rcon:
image: itzg/rcon
ports:
- "4326:4326"
- "4327:4327"
volumes:
- "rcon:/opt/rcon-web-admin/db"
volumes:
mc:
rcon:
secrets:
db_password:
file: ./db_password
```
The content of `db_password`:
ug23u3bg39o-ogADSs
> NOTE: If a file was updated in the destination path and is newer than the source file from `/config`, then it will not be overwritten.
## Running a Bukkit/Spigot server
@@ -432,7 +281,11 @@ If you are hosting your own copy of Bukkit/Spigot you can override the download
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.
Plugins can either be managed within the `plugins` subdirectory of the [data directory](#data-directory) or 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.
[You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins)
> NOTE some of the `VERSION` values are not as intuitive as you would think, so make sure to click into the version entry to find the **exact** version needed for the download. For example, "1.8" is not sufficient since their download naming expects `1.8-R0.1-SNAPSHOT-latest` exactly.
## Running a Paper server
@@ -454,6 +307,8 @@ An example compose file is provided at
If you have attached a host directory to the `/data` volume, then you can install plugins via 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.
[You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins)
## Running a Tuinity server
A [Tuinity](https://github.com/Spottedleaf/Tuinity) server, which is a fork of Paper aimed at improving server performance at high playercounts.
@@ -462,6 +317,30 @@ A [Tuinity](https://github.com/Spottedleaf/Tuinity) server, which is a fork of P
> **NOTE** only `VERSION=LATEST` is supported
## Running a Purpur server
A [Purpur](https://purpur.pl3x.net/) server, which is "a fork of Paper and Tuinity with the goal of providing new and interesting configuration options".
-e TYPE=PURPUR
> NOTE: the `VERSION` variable is used to lookup a build of Purpur to download
Extra variables:
- `PURPUR_BUILD=LATEST` : set a specific Purpur build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
## Running a Yatopia server
A [Yatopia](https://github.com/YatopiaMC/Yatopia) server, which is a "blazing fast Tuinity fork with best in class performance".
-e TYPE=YATOPIA
> NOTE: the `VERSION` variable is used to locate the Yatopia version to download
Extra variables:
- `RELEASE=stable` : set to `stable` or `latest`
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
## Running a Magma server
A [Magma](https://magmafoundation.org/) server, which is a combination of Forge and PaperMC, can be used with
@@ -479,6 +358,9 @@ A [Mohist](https://github.com/Mohist-Community/Mohist) server can be used with
> **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2"
By default the latest build will be used; however, a specific build number can be selected by setting `MOHIST_BUILD`, such as
-e VERSION=1.16.5 -e MOHIST_BUILD=374
## Running a Catserver type server
@@ -490,7 +372,7 @@ A [Catserver](http://catserver.moe/) type server can be used with
## Running a server with a Feed the Beast modpack
> **NOTE** requires `itzg/minecraft-server:multiarch` image
> **NOTE** requires one of the Debian based images listed in [the Java versions section](#running-minecraft-server-on-different-java-version).
[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.
@@ -644,10 +526,125 @@ in either persistent volumes or a downloadable archive.
## Deploying plugins from attached volume
There is one additional volume that can be mounted; `/plugins`. Any files in this filesystem will be copied over to the main `/data/plugins` filesystem before starting Minecraft. Set `PLUGINS_SYNC_UPDATE=false` if you want files from `/plugins` to take precedence over newer files in `/data/plugins`.
If the `/plugins` directory exists in the container, such as from an attached volume, any files in this directory will be copied over to `/data/plugins` before starting Minecraft. Set `PLUGINS_SYNC_UPDATE=false` if you want files from `/plugins` to take precedence over newer files in `/data/plugins`.
This works well if you want to have a common set of plugins in a separate location, but still have multiple worlds with different server requirements in either persistent volumes or a downloadable archive.
## Auto-downloading SpigotMC/Bukkit/PaperMC plugins
The `SPIGET_RESOURCES` variable can be set with a comma-separated list of SpigotMC resource IDs to automatically download [SpigotMC resources/plugins](https://www.spigotmc.org/resources/) using [the spiget API](https://spiget.org/). Resources that are zip files will be expanded into the plugins directory and resources that are simply jar files will be moved there.
> NOTE: the variable is purposely spelled SPIG**E**T with an "E"
The **resource ID** can be located from the numerical part of the URL after the shortname and a dot. For example, the ID is **9089** from
https://www.spigotmc.org/resources/essentialsx.9089/
====
For example, the following will auto-download the [EssentialsX](https://www.spigotmc.org/resources/essentialsx.9089/) and [Vault](https://www.spigotmc.org/resources/vault.34315/) plugins:
-e SPIGET_RESOURCES=9089,34315
## Replacing variables inside configs
Sometimes you have mods or plugins that require configuration information that is only available at runtime.
For example if you need to configure a plugin to connect to a database,
you don't want to include this information in your Git repository or Docker image.
Or maybe you have some runtime information like the server name that needs to be set
in your config files after the container starts.
For those cases there is the option to replace defined variables inside your configs
with environment variables defined at container runtime.
If you set the enviroment variable `REPLACE_ENV_VARIABLES` to `TRUE` the startup script
will go thru all files inside your `/data` volume and replace variables that match your
defined environment variables. Variables that you want to replace need to be wrapped
inside `${YOUR_VARIABLE}` curly brackets and prefixed with a dollar sign. This is the regular
syntax for enviromment variables inside strings or config files.
Optionally you can also define a prefix to only match predefined environment variables.
`ENV_VARIABLE_PREFIX="CFG_"` <-- this is the default prefix
If you want use file for value (like when use secrets) you can add suffix `_FILE` to your variable name (in run command).
There are some limitations to what characters you can use.
| Type | Allowed Characters |
| ----- | ------------------- |
| 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`.
Specific files can be excluded by listing their name (without path) in the variable `REPLACE_ENV_VARIABLES_EXCLUDES`.
Paths can be excluded by listing them in the variable `REPLACE_ENV_VARIABLES_EXCLUDE_PATHS`. Path
excludes are recursive. Here is an example:
```
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`.
```yml
---
database:
host: ${CFG_DB_HOST}
name: ${CFG_DB_NAME}
password: ${CFG_DB_PASSWORD}
```
This is how your `docker-compose.yml` file could look like:
```yml
version: "3"
# Other docker-compose examples in /examples
services:
minecraft:
image: itzg/minecraft-server
ports:
- "25565:25565"
volumes:
- "mc:/data"
environment:
EULA: "TRUE"
ENABLE_RCON: "true"
RCON_PASSWORD: "testing"
RCON_PORT: 28016
# enable env variable replacement
REPLACE_ENV_VARIABLES: "TRUE"
# define an optional prefix for your env variables you want to replace
ENV_VARIABLE_PREFIX: "CFG_"
# and here are the actual variables
CFG_DB_HOST: "http://localhost:3306"
CFG_DB_NAME: "minecraft"
CFG_DB_PASSWORD_FILE: "/run/secrets/db_password"
restart: always
rcon:
image: itzg/rcon
ports:
- "4326:4326"
- "4327:4327"
volumes:
- "rcon:/opt/rcon-web-admin/db"
volumes:
mc:
rcon:
secrets:
db_password:
file: ./db_password
```
The content of `db_password`:
ug23u3bg39o-ogADSs
## Running with a custom server JAR
If you would like to run a custom server JAR, set `-e TYPE=CUSTOM` and pass the custom server
@@ -680,16 +677,14 @@ every time you want to create new Minecraft server, you can now use
```
minecraft-server:
image: itzg/minecraft-server
ports:
- "25565:25565"
environment:
EULA: "TRUE"
image: itzg/minecraft-server
container_name: mc
tty: true
stdin_open: true
restart: always
@@ -751,12 +746,18 @@ To whitelist players for your Minecraft server, pass the Minecraft usernames sep
If the `WHITELIST` environment variable is not used, any user can join your Minecraft server if it's publicly accessible.
> NOTE: When `WHITELIST` is used the server property `white-list` will automatically get set to `true`.
> By default, the players in `WHITELIST` are **added** to the final `whitelist.json` file by the Minecraft server. If you set `OVERRIDE_WHITELIST` to "true" then the `whitelist.json` file will be recreated on each server startup.
### Op/Administrator Players
To add more "op" (aka adminstrator) users to your Minecraft server, pass the Minecraft usernames separated by commas via the `OPS` environment variable, such as
docker run -d -e OPS=user1,user2 ...
> By default, the players in `OPS` are **added** to the final `ops.json` file by the Minecraft server. If you set `OVERRIDE_OPS` to "true" then the `ops.json` file will be recreated on each server startup.
### Server icon
A server icon can be configured using the `ICON` variable. The image will be automatically
@@ -764,6 +765,10 @@ downloaded, scaled, and converted from any other image format:
docker run -d -e ICON=http://..../some/image.png ...
The server icon which has been set doesn't get overridden by default. It can be changed and overridden by setting `OVERRIDE_ICON` to `TRUE`.
docker run -d -e ICON=http://..../some/other/image.png -e OVERRIDE_ICON=TRUE...
### Rcon
To use rcon use the `ENABLE_RCON` and `RCON_PASSORD` variables.
@@ -887,7 +892,11 @@ It determines the server-side viewing distance.
If you want to create the Minecraft level with a specific seed, use `SEED`, such as
docker run -d -e SEED=1785852800490497919 ...
-e SEED=1785852800490497919
If using a negative value for the seed, make sure to quote the value such as:
-e SEED="-1785852800490497919"
### Game Mode
@@ -909,16 +918,13 @@ For example:
The message of the day, shown below each server entry in the UI, can be changed with the `MOTD` environment variable, such as
docker run -d -e 'MOTD=My Server' ...
-e MOTD="My Server"
If you leave it off, a default is computed from the server type and version, such as
A Paper Minecraft Server powered by Docker
when `TYPE` is `PAPER`. That way you can easily differentiate between several servers you may have started.
_The example shows how to specify a server message of the day that contains spaces by putting quotes
around the whole thing._
That way you can easily differentiate between several servers you may have started.
### PVP Mode
@@ -930,7 +936,7 @@ environment variable set to `false`, such as
### Level Type and Generator Settings
By default, a standard world is generated with hills, valleys, water, etc. A different level type can
be configured by setting `LEVEL_TYPE` to an expected type, such as
be configured by setting `LEVEL_TYPE` to an expected type, for example
- DEFAULT
- FLAT
@@ -938,6 +944,8 @@ be configured by setting `LEVEL_TYPE` to an expected type, such as
- AMPLIFIED
- CUSTOMIZED
- BUFFET
- BIOMESOP (Biomes O' Plenty for 1.12 and older)
- BIOMESOPLENTY (Biomes O' Plenty for 1.15 and above)
Descriptions are available at the [gamepedia](http://minecraft.gamepedia.com/Server.properties).
@@ -1068,19 +1076,18 @@ is passed to `docker run`.
### Memory Limit
By default, the image declares a Java initial and maximum memory limit of 1 GB. There are several
ways to adjust the memory settings:
By default, the image declares an initial and maximum Java memory-heap limit of 1 GB. There are several ways to adjust the memory settings:
- `MEMORY`, "1G" by default, can be used to adjust both initial (`Xms`) and max (`Xmx`)
memory settings of the JVM
- `INIT_MEMORY`, independently sets the initial heap size
- `MAX_MEMORY`, independently sets the max heap size
- `MEMORY`: "1G" by default, can be used to adjust both initial (`Xms`) and max (`Xmx`) memory heap settings of the JVM
- `INIT_MEMORY`: independently sets the initial heap size
- `MAX_MEMORY`: independently sets the max heap size
The values of all three are passed directly to the JVM and support format/units as
`<size>[g|G|m|M|k|K]`. For example:
The values of all three are passed directly to the JVM and support format/units as `<size>[g|G|m|M|k|K]`. For example:
-e MEMORY=2G
> NOTE: the settings above only set the Java **heap** limits. Memory resource requests and limits on the overall container should also account for non-heap memory usage. An extra 25% is [a general best practice](https://dzone.com/articles/best-practices-java-memory-arguments-for-container).
### JVM Options
General JVM options can be passed to the Minecraft Server invocation by passing a `JVM_OPTS`
@@ -1090,11 +1097,31 @@ 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:
`JVM_DD_OPTS=fml.queryResult:confirm`, and will be converted to `-Dfml.queryResult=confirm`.
## Timezone Configuration
You can configure the timezone to match yours by setting the `TZ` environment variable:
-e TZ=Europe/London
such as:
docker run -d -it -e TZ=Europe/London -p 25565:25565 --name mc itzg/minecraft-server
Or mounting `/etc/timezone` as readonly (not supported on Windows):
-v /etc/timezone:/etc/timezone:ro
such as:
docker run -d -it -v /etc/timezone:/etc/timezone:ro -p 25565:25565 --name mc itzg/minecraft-server
### 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`, set `JMX_HOST` to the IP/host running the Docker container, and add a port forwarding of TCP port 7091, such as:
-e ENABLE_JMX=true -p 7091:7091
```
-e ENABLE_JMX=true -e JMX_HOST=$HOSTNAME -p 7091:7091
```
### Enable Aikar's Flags
@@ -1129,10 +1156,52 @@ disable that by passing `-e GUI=FALSE`.
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.
## Autopause
### Description
There are various bug reports on [Mojang](https://bugs.mojang.com) about high CPU usage of servers with newer versions, even with few or no clients connected (e.g. [this one](https://bugs.mojang.com/browse/MC-149018), in fact the functionality is based on [this comment in the thread](https://bugs.mojang.com/browse/MC-149018?focusedCommentId=593606&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-593606)).
An autopause functionality has been added to this image to monitor whether clients are connected to the server. If for a specified time no client is connected, the Java process is stopped. When knocking on the server port (e.g. by the ingame Multiplayer server overview), the process is resumed. The experience for the client does not change.
Of course, even loaded chunks are not ticked when the process is stopped.
**You must greatly increase or disable max-tick-time watchdog functionality.** From the server's point of view, the pausing causes a single tick to take as long as the process is stopped, so the server watchdog might intervene after the process is continued, possibly forcing a container restart. To prevent this, ensure that the `max-tick-time` in the `server.properties` file is set to a very large value or -1 to disable it entirely, which is highly recommended. That can be set with `MAX_TICK_TIME` as described in [the section below](#max-tick-time).
> **NOTE:** Non-vanilla versions might have their own configuration file, you might have to disable their watchdogs separately (e.g. PAPER Servers).
On startup the `server.properties` file is checked and, if applicable, a warning is printed to the terminal. When the server is created (no data available in the persistent directory), the properties file is created with the Watchdog disabled.
The utility used to wake the server (`knock(d)`) works at network interface level. So the correct interface has to be set using the `AUTOPAUSE_KNOCK_INTERFACE` variable when using non-default networking environments (e.g. host-networking, Portainer oder NAS solutions). See the description of the variable below.
A starting, example compose file has been provided in [examples/docker-compose-autopause.yml](examples/docker-compose-autopause.yml).
### Enabling Autopause
Enable the Autopause functionality by setting:
```
-e ENABLE_AUTOPAUSE=TRUE
```
The following environment variables define the behaviour of auto-pausing:
* `AUTOPAUSE_TIMEOUT_EST`, default `3600` (seconds)
describes the time between the last client disconnect and the pausing of the process (read as timeout established)
* `AUTOPAUSE_TIMEOUT_INIT`, default `600` (seconds)
describes the time between server start and the pausing of the process, when no client connects inbetween (read as timeout initialized)
* `AUTOPAUSE_TIMEOUT_KN`, default `120` (seconds)
describes the time between knocking of the port (e.g. by the main menu ping) and the pausing of the process, when no client connects inbetween (read as timeout knocked)
* `AUTOPAUSE_PERIOD`, default `10` (seconds)
describes period of the daemonized state machine, that handles the pausing of the process (resuming is done independently)
* `AUTOPAUSE_KNOCK_INTERFACE`, default `eth0`
<br>Describes the interface passed to the `knockd` daemon. If the default interface does not work, run the `ifconfig` command inside the container and derive the interface receiving the incoming connection from its output. The passed interface must exist inside the container. Using the loopback interface (`lo`) does likely not yield the desired results.
## Running on RaspberryPi
To run this image on a RaspberryPi 3 B+, 4, or newer, use the image tag
To run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags [list in the Java version section](#running-minecraft-server-on-different-java-version) that specify `armv7` for the architecture, such as
itzg/minecraft-server:multiarch
> NOTE: you may need to lower the memory allocation, such as `-e MEMORY=750m`
> If experiencing issues such as "sleep: cannot read realtime clock: Operation not permitted", ensure `libseccomp` is up to date on your host. In some cases adding `:Z` flag to the `/data` mount may be needed, [but use cautiously](https://docs.docker.com/storage/bind-mounts/#configure-the-selinux-label).

View File

@@ -1,7 +1,17 @@
#!/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' 'adopt14' 'adopt15' 'multiarch' 'multiarch-latest')
branches_list=(
'java8'
'java8-multiarch'
'openj9'
'openj9-11'
'adopt11'
'java15'
'java15-openj9'
'multiarch'
'multiarch-latest'
)
function TrapExit {
echo "Checking out back in master"

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -2,7 +2,7 @@ version: '3.2'
services:
mc:
image: itzg/minecraft-server
image: itzg/minecraft-server:java8
volumes:
- ./modpacks:/modpacks:ro
environment:

View File

@@ -1,20 +0,0 @@
version: "3.7"
services:
mc:
image: itzg/minecraft-server
ports:
- 25565:25565
volumes:
# Attach .../Curse/Minecraft/Instances for use at /instances
- ./Instances:/instances:ro
# Attach /data as usual
- ./ServerData:/data
environment:
EULA: "TRUE"
# Modpacks generally need more memory, so let's give at 2 GB
MEMORY: 2G
# Use new CURSE_INSTANCE type
TYPE: CURSE_INSTANCE
# Reference directory of or full path to minecraftinstance.json
CURSE_INSTANCE_JSON: /instances/FTB Presents SkyFactory 3

View File

@@ -2,7 +2,7 @@ version: "3.7"
services:
mc:
image: itzg/minecraft-server
image: itzg/minecraft-server:java8
ports:
# expose the Minecraft server port outside of container
- 25565:25565

View File

@@ -2,8 +2,8 @@ version: "3.7"
services:
mc:
# FTBA support is only available in multiarch image tag
image: itzg/minecraft-server:multiarch
# FTBA support is only available in non-Alpine images
image: itzg/minecraft-server:java8-multiarch
ports:
# expose the Minecraft server port outside of container
- 25565:25565

View File

@@ -0,0 +1,12 @@
version: "3"
services:
mc:
image: itzg/minecraft-server
ports:
- 25565:25565
environment:
EULA: "TRUE"
volumes:
# attach the relative directory 'data' to the container's /data path
- ./data:/data

View File

@@ -5,7 +5,7 @@ version: '3'
services:
minecraft:
image: itzg/minecraft-server
image: itzg/minecraft-server:java8
ports:
- "25565:25565"
volumes:

View File

@@ -15,17 +15,35 @@ autopause_error_loop() {
logAutopause "Autopause failed to initialize. This log entry will be printed every 30 minutes."
while :
do
if [[ -n $(ps -ax -o comm | grep java) ]] ; then
break
fi
sleep 0.1
sleep 1800
logAutopause "Autopause failed to initialize."
done
}
# wait for java process to be started
while :
do
if java_process_exists ; then
break
fi
sleep 0.1
done
# check for interface existence
if [[ -z "$AUTOPAUSE_KNOCK_INTERFACE" ]] ; then
logAutopause "AUTOPAUSE_KNOCK_INTERFACE variable must not be empty!"
autopause_error_loop
fi
if ! [[ -d "/sys/class/net/$AUTOPAUSE_KNOCK_INTERFACE" ]] ; then
logAutopause "Selected interface \"$AUTOPAUSE_KNOCK_INTERFACE\" does not exist!"
autopause_error_loop
fi
sudo /usr/sbin/knockd -c /tmp/knockd-config.cfg -d -i "$AUTOPAUSE_KNOCK_INTERFACE"
if [ $? -ne 0 ] ; then
logAutopause "Failed to start knockd daemon."
logAutopause "Possible cause: docker's host network mode."
logAutopause "Recreate without host mode or disable autopause functionality."
logAutopause "Stopping server."
pkill -SIGTERM java
exit 1
logAutopause "Probable cause: Unable to attach to interface \"$AUTOPAUSE_KNOCK_INTERFACE\"."
autopause_error_loop
fi
STATE=INIT

View File

@@ -9,7 +9,7 @@ java_running() {
}
java_process_exists() {
[[ -n "$(ps -a -o comm | grep 'java')" ]]
[[ -n "$(ps -ax -o comm | grep 'java')" ]]
}
rcon_client_exists() {

View File

@@ -1,7 +1,13 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
: ${EULA:=}
: ${PROXY:=}
: ${RCON_PASSWORD_FILE:=}
shopt -s nullglob
#umask 002
@@ -48,7 +54,11 @@ if [[ $RCON_PASSWORD_FILE ]]; then
log ""
fi
export SERVER_PROPERTIES=/data/server.properties
if ! which java > /dev/null; then
log "Fixing PATH to include java"
PATH="${PATH}:/opt/java/openjdk/bin"
fi
export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json
case "X$VERSION" in
@@ -88,6 +98,12 @@ case "${TYPE^^}" in
;;
FORGE)
log "**********************************************************************"
log "WARNING: The image tag itzg/minecraft-server:java8 is recommended"
log " since some mods require Java 8"
log " Exception traces reporting ClassCastException: class jdk.internal.loader.ClassLoaders\$AppClassLoader"
log " can be fixed with java8"
log "**********************************************************************"
exec ${SCRIPTS:-/}start-deployForge "$@"
;;
@@ -99,7 +115,13 @@ case "${TYPE^^}" in
exec ${SCRIPTS:-/}start-deployFTBA "$@"
;;
CURSEFORGE|FTB)
FTB|CURSEFORGE)
log "**********************************************************************"
log "WARNING: The image tag itzg/minecraft-server:java8 is recommended"
log " since some mods require Java 8"
log " Exception traces reporting ClassCastException: class jdk.internal.loader.ClassLoaders\$AppClassLoader"
log " can be fixed with java8"
log "**********************************************************************"
exec ${SCRIPTS:-/}start-deployCF "$@"
;;
@@ -131,11 +153,19 @@ case "${TYPE^^}" in
exec ${SCRIPTS:-/}start-deployCatserver "$@"
;;
PURPUR)
exec ${SCRIPTS:-/}start-deployPurpur "$@"
;;
YATOPIA)
exec ${SCRIPTS:-/}start-deployYatopia "$@"
;;
*)
log "Invalid type: '$TYPE'"
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
log " CURSE_INSTANCE, CURSEFORGE, SPONGEVANILLA,"
log " CUSTOM, MAGMA, MOHIST, CATSERVER"
log " CURSE_INSTANCE, CURSEFORGE, SPONGEVANILLA, TUINITY, PURPUR"
log " CUSTOM, MAGMA, MOHIST, CATSERVER, YATOPIA"
exit 1
;;

View File

@@ -82,7 +82,9 @@ function downloadSpigot {
ERROR: failed to download from $downloadUrl
Visit https://getbukkit.org/download/${getbukkitFlavor} to lookup the
exact version, such as 1.4.6-R0.4-SNAPSHOT or 1.8-R0.1-SNAPSHOT-LATEST
exact version, such as 1.4.6-R0.4-SNAPSHOT or 1.8-R0.1-SNAPSHOT-latest.
Click into the version entry to find the **exact** version, because something
like "1.8" is not sufficient according to their download naming.
EOF
@@ -123,5 +125,4 @@ fi
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -3,6 +3,24 @@
set -e
. ${SCRIPTS:-/}start-utils
loadForgeVars() {
cfgFile=${1?}
pat='^([^#;][^=]+)=[:space:]*([^;]*)'
while read -r line || [[ -n "$line" ]] ; do
if [[ $line =~ $pat ]]; then
#echo "MATCHED $line"
k=${BASH_REMATCH[1]}
v=${BASH_REMATCH[2]}
case $k in
FORGEURL)
forgeInstallerUrl="$v"
;;
esac
fi
done < "$cfgFile"
}
isDebugging && set -x
: ${FTB_BASE_DIR:=${CF_BASE_DIR:-/data/FeedTheBeast}}
@@ -44,15 +62,30 @@ if ! isTrue ${USE_MODPACK_START_SCRIPT:-true}; then
serverJar=$(find ${FTB_BASE_DIR} -path "*/libraries/*" -prune -type f -o -not -name "forge*installer.jar" -name "forge*.jar")
if [[ -z "$serverJar" ]]; then
forgeInstallerJar=$(find ${FTB_BASE_DIR} -name "forge*installer.jar")
if [ -f "${FTB_BASE_DIR}/settings.cfg" ]; then
loadForgeVars "${FTB_BASE_DIR}/settings.cfg"
if [[ $forgeInstallerUrl ]]; then
forgeInstallerJar="${FTB_BASE_DIR}/forge-installer.jar"
if ! curl -fsSL -o "$forgeInstallerJar" "$forgeInstallerUrl" ; then
log "ERROR failed to download Forge installer from $forgeInstallerUrl"
exit 2
fi
fi
else
forgeInstallerJar=$(find "${FTB_BASE_DIR}" -name "forge*installer.jar")
fi
if [[ -z "${forgeInstallerJar}" ]]; then
log "ERROR Unable to find forge installer in modpack."
log "ERROR Unable to find forge installer in modpack"
log " or download using modpack config."
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 ""}'
(cd $(dirname "${forgeInstallerJar}"); java -jar $(basename "${forgeInstallerJar}") --installServer)
fi
echo "${FTB_SERVER_MOD}" > $installMarker

View File

@@ -1,6 +1,7 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
if isURL ${CUSTOM_SERVER}; then
filename=$(basename ${CUSTOM_SERVER})

View File

@@ -43,6 +43,9 @@ if ! [ -f "${ftbInstallMarker}" ] || [ $(cat "${ftbInstallMarker}") != "${FTB_MO
echo "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" > ${ftbInstallMarker}
writeEula
# some modpacks result in --w----r-- permissions
chmod a+r version.json
else
log "FTB modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID} is ready to go"
fi

View File

@@ -54,7 +54,10 @@ if [[ ! -e $installMarker ]]; then
tries=3
set +e
while ((--tries >= 0)); do
java -jar $FABRIC_INSTALLER server -mcversion $VANILLA_VERSION -downloadMinecraft
java -jar $FABRIC_INSTALLER server \
-mcversion $VANILLA_VERSION \
-downloadMinecraft \
-dir /data
if [[ $? == 0 ]]; then
break
fi

View File

@@ -1,8 +1,9 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
export TYPE=FORGE
: ${FORGEVERSION:=RECOMMENDED}
isDebugging && set -x
if [[ -z $FORGE_INSTALLER && -z $FORGE_INSTALLER_URL ]]; then
norm=$VANILLA_VERSION
@@ -45,6 +46,8 @@ elif [[ -z $FORGE_INSTALLER ]]; then
elif [[ ! -e $FORGE_INSTALLER ]]; then
log "ERROR: the given Forge installer doesn't exist : $FORGE_INSTALLER"
exit 2
else
shortForgeVersion=$VANILLA_VERSION-custom
fi
installMarker="/data/.forge-installed-$shortForgeVersion"
@@ -97,7 +100,11 @@ if [ ! -e $installMarker ]; then
log "Finding installed server jar..."
unset -v latest
for file in *forge*.jar; do
[[ $file =~ installer ]] || [[ $file -nt $latest ]] && latest=$file
if ! [[ $file =~ installer ]]; then
if [[ -z $latest ]] || [[ $file -nt $latest ]]; then
latest=$file
fi
fi
done
if [[ -z $latest ]]; then
log "Unable to derive server jar for Forge"

View File

@@ -6,6 +6,7 @@ set -e
isDebugging && set -x
requireVar VANILLA_VERSION
: ${MOHIST_BUILD:=lastSuccessfulBuild}
mohistJobs=https://ci.codemc.io/job/Mohist-Community/job/
mohistJob=${mohistJobs}Mohist-${VANILLA_VERSION}/
@@ -17,12 +18,12 @@ if ! curl -X HEAD -o /dev/null -fsSL "${mohistJob}"; then
exit 1
fi
latestBuildRelPath=$(
curl -fsSL "${mohistJob}lastSuccessfulBuild/api/json" |
buildRelPath=$(
curl -fsSL "${mohistJob}${MOHIST_BUILD}/api/json" |
jq -r '.artifacts[0].relativePath'
)
baseName=$(basename "${latestBuildRelPath}")
baseName=$(basename "${buildRelPath}")
if [[ ${baseName} != *-server.jar* ]]; then
log "ERROR: mohist build for ${VANILLA_VERSION} is not a valid server jar, found ${baseName}"
log " check https://ci.codemc.io/job/Mohist-Community/ for available versions"
@@ -34,7 +35,7 @@ export SERVER="/data/${baseName}"
if [ ! -f ${SERVER} ]; then
log "Downloading ${baseName}"
curl -o "${SERVER}" -fsSL "${mohistJob}lastSuccessfulBuild/artifact/${latestBuildRelPath}"
curl -o "${SERVER}" -fsSL "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}"
fi
export SKIP_LOG4J_CONFIG=true

View File

@@ -17,8 +17,8 @@ if [[ $PAPER_DOWNLOAD_URL ]]; then
else
# PaperMC API v2 docs : https://papermc.io/api/docs/swagger-ui/index.html?configUrl=/api/openapi/swagger-config
build=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}" -H "accept: application/json" \
| jq '.builds[-1]')
build=${PAPERBUILD:=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}" -H "accept: application/json" \
| jq '.builds[-1]')}
case $? in
0)
;;
@@ -28,7 +28,7 @@ else
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 "$@"
exec "$0" "$@"
fi
log "ERROR: ${VANILLA_VERSION} is not published by PaperMC"
log " Set VERSION to one of the following: "
@@ -56,6 +56,12 @@ else
zarg=(-z "$SERVER")
fi
log "Removing old PaperMC versions ..."
shopt -s nullglob
for f in paper-*.jar; do
[[ $f != $SERVER ]] && rm $f
done
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}" \
@@ -70,5 +76,4 @@ fi
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@
exec ${SCRIPTS:-/}start-spiget "$@"

38
start-deployPurpur Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
: ${VANILLA_VERSION:?}
: ${PURPUR_BUILD:=LATEST}
: ${FORCE_REDOWNLOAD:=false}
if [[ ${PURPUR_BUILD} == LATEST ]]; then
PURPUR_BUILD=$(curl -fsSL "https://purpur.pl3x.net/api/v1/purpur/${VANILLA_VERSION}" |
jq -r '.builds.latest' || echo "")
if [[ -z ${PURPUR_BUILD} ]]; then
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}."
log " Please check if a download is available at https://purpur.pl3x.net/downloads/"
exit 3
fi
fi
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar"
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="https://purpur.pl3x.net/api/v1/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
log "Downloading Purpur from $downloadUrl ..."
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -3,6 +3,8 @@
. ${SCRIPTS:-/}start-utils
export TYPE=spongevanilla
: ${SPONGEBRANCH:=STABLE}
: ${SPONGEVERSION:=}
# Parse branch
log "Choosing branch for Sponge"

View File

@@ -20,7 +20,7 @@ if [ ! -f "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
fi
fi
# Normalize on Spigot for operations below
# Normalize on Spigot for later operations
export TYPE=SPIGOT
# Continue to Final Setup

30
start-deployYatopia Normal file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
: ${VANILLA_VERSION:?}
: ${RELEASE:=stable}
: ${FORCE_REDOWNLOAD:=false}
requireEnum RELEASE stable latest
export SERVER="yatopia-${RELEASE}-${VANILLA_VERSION}.jar"
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="https://api.yatopiamc.org/v2/${RELEASE}Build/download?branch=ver/${VANILLA_VERSION}"
log "Downloading Yatopia from $downloadUrl ..."
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -5,7 +5,7 @@
: ${ENV_VARIABLE_PREFIX:=CFG_}
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 ..."
# File excludes
fileExcludes=
@@ -22,28 +22,30 @@ if isTrue "${REPLACE_ENV_VARIABLES}"; then
isDebugging && echo "Using find file exclusions: $fileExcludes"
isDebugging && echo "Using find directory exclusions: $dirExcludes"
while IFS='=' read -r name value ; do
for name in $(compgen -v $ENV_VARIABLE_PREFIX); 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
# Read content from file environment
if [[ $name = *"_FILE" ]] && [[ -f $value ]]; then
name="${name/_FILE/}"
value=$(<$value)
fi
log "Replacing $name with $value ..."
find /data/ \
$dirExcludes \
-type f \
\( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" \
-or -name "*.conf" -or -name "*.properties" \) \
$fileExcludes \
-exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \;
# Read content from file environment
if [[ $name = *"_FILE" ]]; then
value=$(<${!name})
name="${name%_FILE}"
else
value=${!name}
fi
done < <(env)
log "Replacing $name with $value ..."
value=${value//\\/\\\\}
value=${value//#/\\#}
find /data/ \
$dirExcludes \
-type f \
\( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" \
-or -name "*.conf" -or -name "*.properties" \) \
$fileExcludes \
-exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \;
done
fi
exec ${SCRIPTS:-/}start-minecraftFinalSetup $@

View File

@@ -81,16 +81,23 @@ if [[ "$MODS" ]]; then
do
if isURL $i; then
log "Downloading mod/plugin $i ..."
effective_url=$(resolveEffectiveUrl "$i")
if isValidFileURL jar "${effective_url}"; then
out_file=$(getFilenameFromUrl "${effective_url}")
if ! curl -fsSL -o "${out_dir}/$out_file" "${effective_url}"; then
if isValidFileURL jar "$i"; then
if ! curl -fsSL -o "${out_dir}/$(getFilenameFromUrl "${i}")" "${i}"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
else
log "ERROR: $effective_url resolved from $i is not a valid jar URL"
exit 2
effective_url=$(resolveEffectiveUrl "$i")
if isValidFileURL jar "${effective_url}"; then
out_file=$(getFilenameFromUrl "${effective_url}")
if ! curl -fsSL -o "${out_dir}/$out_file" "${effective_url}"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
else
log "ERROR: $effective_url resolved from $i is not a valid jar URL"
exit 2
fi
fi
else
log "ERROR Invalid URL given in MODS: $i"

View File

@@ -2,6 +2,8 @@
. ${SCRIPTS:-/}start-utils
: ${SERVER_PROPERTIES:=/data/server.properties}
# FUNCTIONS
function setServerProp {
local prop=$1
@@ -12,10 +14,15 @@ function setServerProp {
TRUE|FALSE)
var=${var,,} ;;
esac
log "Setting ${prop} to '${var}' in ${SERVER_PROPERTIES}"
sed -i "/^${prop}\s*=/ c ${prop}=${var//\\/\\\\}" "$SERVER_PROPERTIES"
if grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then
log "Setting ${prop} to '${var}' in ${SERVER_PROPERTIES}"
sed -i "/^${prop}\s*=/ c ${prop}=${var//\\/\\\\}" "$SERVER_PROPERTIES"
else
log "Adding ${prop} with '${var}' in ${SERVER_PROPERTIES}"
echo "${prop}=${var//\\/\\\\}" >> "$SERVER_PROPERTIES"
fi
else
log "Skip setting ${prop}"
isDebugging && log "Skip setting ${prop}"
fi
}
@@ -24,6 +31,10 @@ function customizeServerProps {
log "Creating whitelist"
setServerProp "whitelist" "true"
setServerProp "white-list" "true"
else
log "Disabling whitelist"
setServerProp "whitelist" "false"
setServerProp "white-list" "false"
fi
# If not provided, generate a reasonable default message-of-the-day,
@@ -69,7 +80,7 @@ function customizeServerProps {
setServerProp "max-world-size" "$MAX_WORLD_SIZE"
setServerProp "level-name" "$LEVEL"
setServerProp "level-seed" "$SEED"
setServerProp "pvp" "$PVP"
setServerProp "pvp" "${PVP}"
setServerProp "generator-settings" "$GENERATOR_SETTINGS"
setServerProp "online-mode" "$ONLINE_MODE"
setServerProp "allow-flight" "$ALLOW_FLIGHT"

View File

@@ -4,6 +4,9 @@
set -e
isDebugging && set -x
: ${LEVEL:=world}
export LEVEL
if [ $TYPE = "FEED-THE-BEAST" ]; then
worldDest=$FTB_DIR/$LEVEL
else
@@ -11,6 +14,13 @@ else
fi
if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); then
if isTrue "${FORCE_WORLD_COPY}"; then
log "Removing existing world data in $worldDest ${worldDest}_nether ${worldDest}_the_end"
rm -rf "$worldDest" \
"${worldDest}_nether" \
"${worldDest}_the_end"
fi
if isURL $WORLD; then
curl -fsSL "$WORLD" -o /tmp/world.zip
zipSrc=/tmp/world.zip
@@ -56,8 +66,8 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
if [ "$TYPE" = "SPIGOT" ]; then
# Reorganise if a Spigot server
log "Moving End and Nether maps to Spigot location"
[ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "/data/${LEVEL}_the_end"
[ -d "$worldDest/DIM-1" ] && mv -f "$worldDest/DIM-1" "/data/${LEVEL}_nether"
[ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "${worldDest}_the_end"
[ -d "$worldDest/DIM-1" ] && mv -f "$worldDest/DIM-1" "${worldDest}_nether"
fi
fi

View File

@@ -1,30 +1,41 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
if [ -n "$OPS" ]; then
log "Setting/adding ops"
rm -rf /data/ops.txt.converted
log "Updating ops"
rm -f /data/ops.txt.converted
echo $OPS | awk -v RS=, '{print}' > /data/ops.txt
fi
if isTrue "${OVERRIDE_OPS}"; then
log "Recreating ops.json file at server startup"
rm -f /data/ops.json
fi
if [ -n "$WHITELIST" ]; then
log "Setting whitelist"
rm -rf /data/white-list.txt.converted
log "Updating whitelist"
rm -f /data/white-list.txt.converted
echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt
fi
if isTrue "${OVERRIDE_WHITELIST}"; then
log "Recreating whitelist.json file at server startup"
rm -f /data/whitelist.json
fi
if [ -n "$ICON" -a ! -e server-icon.png ]; then
log "Using server icon from $ICON..."
# Not sure what it is yet...call it "img"
curl -sSL -o /tmp/icon.img $ICON
specs=$(identify /tmp/icon.img | awk '{print $2,$3}')
if [ "$specs" = "PNG 64x64" ]; then
mv /tmp/icon.img /data/server-icon.png
else
log "Converting image to 64x64 PNG..."
convert /tmp/icon.img -resize 64x64! /data/server-icon.png
fi
if [ -n "$ICON" ]; then
if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then
log "Using server icon from $ICON..."
# Not sure what it is yet...call it "img"
curl -sSL -o /tmp/icon.img $ICON
specs=$(identify /tmp/icon.img | awk '{print $2,$3}')
if [ "$specs" = "PNG 64x64" ]; then
mv /tmp/icon.img /data/server-icon.png
else
log "Converting image to 64x64 PNG..."
convert /tmp/icon.img -resize 64x64! /data/server-icon.png
fi
fi
fi
if ! isTrue ${SKIP_LOG4J_CONFIG}; then
@@ -49,15 +60,14 @@ for j in $JSON_FILES; do
fi
done
EXTRA_ARGS=""
# Optional disable console
if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then
EXTRA_ARGS+="--noconsole"
EXTRA_ARGS+=" --noconsole"
fi
# Optional disable GUI for headless servers
if [[ ${GUI} = false || ${GUI} = FALSE ]]; then
EXTRA_ARGS="${EXTRA_ARGS} nogui"
EXTRA_ARGS+=" nogui"
fi
# put these prior JVM_OPTS at the end to give any memory settings there higher precedence
@@ -72,7 +82,6 @@ if [ -n "$JVM_DD_OPTS" ]; then
fi
if isTrue ${ENABLE_JMX}; then
: ${JMX_HOST:=0.0.0.0}
: ${JMX_PORT:=7091}
JVM_OPTS="${JVM_OPTS}
-Dcom.sun.management.jmxremote.local.only=false
@@ -80,8 +89,8 @@ if isTrue ${ENABLE_JMX}; then
-Dcom.sun.management.jmxremote.rmi.port=${JMX_PORT}
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.host=${JMX_HOST}
-Djava.rmi.server.hostname=${JMX_HOST}"
-Dcom.sun.management.jmxremote.host=${JMX_BINDING:-0.0.0.0}
-Djava.rmi.server.hostname=${JMX_HOST:-localhost}"
log "JMX is enabled. Make sure you have port forwarding for ${JMX_PORT}"
fi
@@ -146,11 +155,11 @@ 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}/
[ -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}/
cp -f /data/server-icon.png "${FTB_DIR}/"
fi
cp -f /data/eula.txt "${FTB_DIR}/"

58
start-spiget Normal file
View File

@@ -0,0 +1,58 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
handleDebugMode
: ${SPIGET_RESOURCES:=}
containsJars() {
file=${1?}
pat='\.jar$'
while read -r line; do
if [[ $line =~ $pat ]]; then
return 0
fi
done <<< $(unzip -l "$file")
return 1
}
getResourceFromSpiget() {
resource=${1?}
log "Downloading resource ${resource} ..."
tmpfile="/tmp/${resource}.zip"
url="https://api.spiget.org/v2/resources/${resource}/download"
if ! curl -o "${tmpfile}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${url}"; then
log "ERROR failed to download resource '${resource}' from ${url}"
exit 2
fi
mkdir -p /data/plugins
if containsJars "${tmpfile}"; then
log "Extracting contents of resource ${resource} into plugins"
unzip -o -q -d /data/plugins "${tmpfile}"
rm "${tmpfile}"
else
log "Moving resource ${resource} into plugins"
mv "${tmpfile}" "/data/plugins/${resource}.jar"
fi
}
if [[ ${SPIGET_RESOURCES} ]]; then
log "Getting plugins via Spiget"
IFS=',' read -r -a resources <<< "${SPIGET_RESOURCES}"
for resource in "${resources[@]}"
do
getResourceFromSpiget "${resource}"
done
fi
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -57,13 +57,20 @@ function isTrue() {
}
function isDebugging() {
if [[ -v DEBUG ]] && [[ ${DEBUG^^} == TRUE ]]; then
if isTrue "${DEBUG:-false}"; then
return 0
else
return 1
fi
}
function handleDebugMode() {
if isDebugging; then
set -x
extraCurlArgs=(-v)
fi
}
function debug() {
if isDebugging; then
log "DEBUG: $*"
@@ -144,8 +151,23 @@ requireVar() {
fi
}
requireEnum() {
var=${1?}
shift
for allowed in $*; do
if [[ ${!var} = $allowed ]]; then
return 0
fi
done
log "ERROR: $var must be set to one of $@"
# exit 1
}
function writeEula() {
if ! echo "# Generated via Docker on $(date)
if ! echo "# Generated via Docker
# $(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}"