Compare commits

...

82 Commits

Author SHA1 Message Date
Geoff Bourne
8387e9bd26 Auto-merging via docker-versions-create 2020-07-18 18:40:48 -05:00
Paul Zühlcke
747c188824 Use -prune for "REPLACE_ENV_VARIABLES_EXCLUDE_PATHS" feature. (#588) 2020-07-18 18:31:29 -05:00
Geoff Bourne
692087dd25 Ensured ops.txt and white-list.txt are always provided for CURSEFORGE/FTB type (#584) 2020-07-18 13:49:40 -05:00
Geoff Bourne
6fe13e8654 Clarified "invalid type" message for FTBA on multiarch 2020-07-18 13:09:58 -05:00
Geoff Bourne
3b2b98b9fe Upgrade base image packages
For #586
2020-07-14 21:07:57 -05:00
Code Monad
796f2fe14a Add support for rcon password from file (#585) 2020-07-13 21:00:46 -05:00
Geoff Bourne
4fef391b64 misc: Switched maintainer label to opencontainers schema 2020-07-12 11:36:31 -05:00
Geoff Bourne
83f6cebd0b Merge pull request #581 from itzg/dev/add-ci-tests
Added CI tests
2020-07-11 14:29:59 -05:00
Geoff Bourne
90183ae823 ci: Don't restart failed container during test 2020-07-11 14:26:47 -05:00
Geoff Bourne
3c9df03584 ci: Only output server logs when failed 2020-07-11 14:13:51 -05:00
Geoff Bourne
367c6cfd92 ci: Added testing step to github actions 2020-07-11 14:09:08 -05:00
Geoff Bourne
5e75410e7c Confirm latest Paper jar is always downloaded 2020-07-11 13:30:39 -05:00
Geoff Bourne
38028f7d0c Confirm latest Spigot jar is always downloaded 2020-07-11 13:17:28 -05:00
Geoff Bourne
4afdb289c0 Auto-merging via docker-versions-create 2020-07-11 13:13:48 -05:00
Geoff Bourne
a07ae685e2 Fixed attempted rsync when WORLD not set 2020-07-11 13:09:48 -05:00
Geoff Bourne
fe637353d8 Auto-merging via docker-versions-create 2020-07-10 17:11:51 -05:00
Paul Zühlcke
092b530537 Added 'FORCE_WORLD_COPY' environment variable (#580) 2020-07-10 17:06:47 -05:00
Geoff Bourne
cf691499a1 docs: Moved section for DISABLE_HEALTHCHECK to existing healthcheck section 2020-07-09 21:07:26 -05:00
Geoff Bourne
0bb9cccdc6 Added REPLACE_ENV_VARIABLES_EXCLUDE_PATHS
For #575
2020-07-09 21:05:17 -05:00
Geoff Bourne
4cb12f6cae Added DISABLE_HEALTHCHECK 2020-07-09 20:54:34 -05:00
Geoff Bourne
ecbdeb2096 Added option to disable PLUGINS_SYNC_UPDATE
For #576
2020-07-08 19:07:53 -05:00
Geoff Bourne
9a7a532f7b Changed order of /plugins rsync to be before processing env vars
For #577
2020-07-06 17:16:51 -05:00
Geoff Bourne
825833c859 Added REPLACE_ENV_VARIABLES_EXCLUDES
for #575
2020-07-06 16:41:56 -05:00
Geoff Bourne
c4c3613874 misc: added docs to release notes exclusion 2020-07-04 15:02:32 -05:00
Geoff Bourne
9160501f0a Auto-merging via docker-versions-create 2020-07-04 14:58:15 -05:00
Geoff Bourne
3a03156cb3 ci: Adjust pr workflow name 2020-07-04 14:55:45 -05:00
orblazer
b3780186f8 Add some missing properties in env variables (#574) 2020-07-04 14:52:35 -05:00
Kamaroth92
c4654e44d8 Move server-icon.png to FTB_DIR if exists (#573)
Co-authored-by: Tane Barriball <tanebarriball@gmail.com>
2020-07-04 09:08:37 -05:00
Kamaroth92
9c6047e3fc Updated worldDest to use FTB_DIR in order to deal with nested FTB modpacks (#571)
Co-authored-by: Tane Barriball <tanebarriball@gmail.com>
2020-07-01 18:48:41 -05:00
Geoff Bourne
260cc7d180 docs: added recommendation against using SERVER_PORT 2020-06-30 08:40:33 -05:00
Geoff Bourne
bbe930e552 ci: changed gh actions to avoid image push on PR 2020-06-28 12:22:00 -05:00
Geoff Bourne
a655fe860e docs: removed github readme link since Docker Hub docs are manual now 2020-06-28 12:17:07 -05:00
Geoff Bourne
ddf36aa879 docs: updated example compose file for paper to use proper CONSOLE setting 2020-06-28 09:37:55 -05:00
Geoff Bourne
34c31c561d docs: removed most mentions of noconsole since it only applies pre-1.14 2020-06-28 09:36:31 -05:00
Geoff Bourne
3cc7d00d71 docs: added example compose file for autopause
For #569
2020-06-28 09:34:26 -05:00
Geoff Bourne
ed214b1382 docs: updated image tag for running on RaspberryPi 2020-06-28 09:19:38 -05:00
Geoff Bourne
f8405e298c ci: removed tagging image with git SHA since it seemed like too many 2020-06-26 17:17:41 -05:00
Geoff Bourne
539159ba50 docs: simplified top-level example compose file
related to #518
2020-06-25 14:10:21 -05:00
Geoff Bourne
f2c9d2f905 Updated TYPE feedback when invalid choice given
For #561
2020-06-23 17:27:21 -05:00
Geoff Bourne
1b11331881 misc: added github action badge 2020-06-20 16:06:28 -05:00
Geoff Bourne
b71afff29f misc: removed unused multiarch scripts 2020-06-20 16:05:46 -05:00
Geoff Bourne
b4c6950f95 ci: simplified main github action name 2020-06-20 16:01:27 -05:00
Geoff Bourne
6eba5062ec Auto-merging via docker-versions-create 2020-06-20 15:45:09 -05:00
Geoff Bourne
ec0329efb1 ci: added option to sign git tags 2020-06-20 15:42:45 -05:00
Geoff Bourne
477caa12c3 ci: switched image push to use Gitub Actions 2020-06-20 15:35:37 -05:00
Geoff Bourne
8f82ff9b1d Added support for Catserver type 2020-06-20 15:28:30 -05:00
Geoff Bourne
7d97fdcbec Clarified setting VERSION for unavailable Mohist builds 2020-06-20 09:07:38 -05:00
Geoff Bourne
5ee0150154 docs: added development note about generating release notes 2020-06-19 16:09:09 -05:00
Geoff Bourne
1bcacfc474 docs: added a bunch more development notes 2020-06-19 15:34:56 -05:00
Geoff Bourne
34603184a4 Activated useSystemProxies java property when proxy config set
Fixes #415
2020-06-19 15:33:33 -05:00
Geoff Bourne
fc96723db1 Auto-merging via docker-versions-create 2020-06-19 13:27:05 -05:00
Geoff Bourne
2ee5a25c91 ci: adjusted main github action name 2020-06-19 13:23:05 -05:00
Geoff Bourne
60ef1b8867 ci: fixed github action tags matching 2020-06-19 13:15:23 -05:00
Geoff Bourne
3eaf756aa2 ci: adjusted github actions to build non-multiarch branches/tags 2020-06-19 11:41:53 -05:00
Geoff Bourne
bc318fa185 Added support for Mohist servers 2020-06-19 11:31:56 -05:00
Geoff Bourne
f93c42a23f Added support for tagging during docker-versions-create.sh 2020-06-19 11:31:41 -05:00
Geoff Bourne
f5dde77efe Enabled iterative development with SCRIPTS var 2020-06-19 11:05:32 -05:00
Toboshii Nakama
2b7f923865 Add ttf-dejavu to package list (#556) 2020-06-14 11:20:37 -05:00
Geoff Bourne
80099ad63d Added debug option to dump managed server.properties 2020-06-14 11:14:11 -05:00
Geoff Bourne
b273bf2947 Removed cirleci config 2020-06-10 18:50:40 -05:00
Geoff Bourne
2241ba8819 Added build image action 2020-06-10 18:43:07 -05:00
Luis Marroquin
3cf58e3caf Fixed docker-compose-proxied.yml link (#554) 2020-06-10 06:56:07 -05:00
Geoff Bourne
450442a916 Enhanced WORLD to support path to zip file 2020-06-06 20:41:09 -05:00
Geoff Bourne
8c866bd17d Un-flipped forge and FTBA examples compose files 2020-05-31 18:46:17 -05:00
Geoff Bourne
8deaf1850b Fixed TYPE=FTBA in example compose file 2020-05-31 18:43:40 -05:00
Geoff Bourne
6da2aca975 Updated examples for FTBA support 2020-05-31 18:40:13 -05:00
Geoff Bourne
11989d17e3 Updated README for FTBA server type support
For #524
2020-05-31 18:34:21 -05:00
Geoff Bourne
5aa6e5c2a9 Refactored autopause setup into its own start-file (#545) 2020-05-25 10:20:14 -05:00
Kevin Klinemeier
825398f4d4 removed version entries except for the version section (#541)
Co-authored-by: BuildTools <unconfigured@null.spigotmc.org>
2020-05-23 17:57:11 -05:00
Geoff Bourne
ccac249c01 Added server-start.sh support for CF modpacks
Fixes #540
2020-05-23 09:55:38 -05:00
Michael Kirsch
f2806d9335 Autopause logs (#539) 2020-05-23 09:15:10 -05:00
Geoff Bourne
b11806e341 Consolidated armv7 branch into multiarch 2020-05-21 20:59:13 -05:00
Michael Kirsch
71a7afab17 Autopause functionality (#531) 2020-05-20 08:17:58 -05:00
Geoff Bourne
8d3e461b4c Auto-merging via docker-versions-create 2020-05-20 08:15:12 -05:00
Geoff Bourne
fd73417411 Auto-merging via docker-versions-create 2020-05-02 09:34:30 -05:00
Geoff Bourne
1207b9a685 Auto-merging via docker-versions-create 2020-04-25 12:11:09 -05:00
Geoff Bourne
e6259bfd9d Auto-merging via docker-versions-create 2020-04-17 21:29:12 -05:00
Geoff Bourne
b5e7b952e4 Auto-merging via docker-versions-create 2020-04-11 08:51:52 -05:00
Geoff Bourne
ac5b960182 Auto-merging via docker-versions-create 2020-04-10 11:08:59 -05:00
Geoff Bourne
3299dec733 Auto-merging via docker-versions-create 2020-04-03 13:31:44 -05:00
Geoff Bourne
578f06087f Changed JVM_XX_OPTS to use default GC 2020-03-13 10:55:19 -05:00
Geoff Bourne
fb364e8301 Prepared adopt13 branch 2020-03-02 21:08:22 -06:00
53 changed files with 1049 additions and 435 deletions

View File

@@ -1,22 +0,0 @@
version: 2
jobs:
minecraft_server:
docker:
- image: circleci/buildpack-deps:19.10
steps:
- checkout
- setup_remote_docker
- run:
name: Build image
command: docker build -t mc:$CIRCLE_BUILD_NUM .
workflows:
version: 2
build:
jobs:
- minecraft_server:
filters:
branches:
ignore:
- armv7
- multiarch

47
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: Build and Publish
on:
push:
branches:
- master
- openj9
- openj9-nightly
- adopt11
- adopt13
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-openj9"
- "[0-9]+.[0-9]+.[0-9]+-openj9-nightly"
- "[0-9]+.[0-9]+.[0-9]+-adopt11"
- "[0-9]+.[0-9]+.[0-9]+-adopt13"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: |
tests/test.sh
build:
needs:
- test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build and push Docker images
uses: docker/build-push-action@v1.1.0
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
push: true

16
.github/workflows/pr.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Validate PR
on:
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: |
tests/test.sh

74
DEVELOPMENT.md Normal file
View File

@@ -0,0 +1,74 @@
## Adding a server type
Adding a new server `TYPE` can vary due to the complexity of obtaining and configuring each type; however, the addition of any server type includes at least the following steps:
1. Copy an existing "start-deploy*" script, such as [start-deployMohist](start-deployMohist) and rename it accordingly making sure to retain the "start-deploy" prefix
2. Modify the type-specific behavior between the "start-utils" preamble and the hand-off to `start-finalSetupWorld` at the end of the script
3. Develop and test the changes using the [iterative process described below](#iterative-script-development)
4. Add a case-entry to the `case "${TYPE^^}"` in [start-configuration](start-configuration)
5. Add a section to the [README](README.md). It is recommended to copy-modify an existing section to retain a similar wording and level of detail
6. [Submit a pull request](https://github.com/itzg/docker-minecraft-server/pulls)
## Iterative script development
Individual scripts can be iteratively developed, debugged, and tested using the following procedure.
First, build a baseline of the image to include the packages needed by existing or new scripts:
```shell script
docker build -t mc-dev .
```
Using the baseline image, an interactive container can be started to iteratively run the scripts to be developed. By attaching the current workspace directory, you can use the local editor of your choice to iteratively modify scripts while using the container to run them.
```shell script
docker run -it --rm -v ${PWD}:/scripts -e SCRIPTS=/scripts/ --entrypoint bash mc-dev
```
From within the container you can run individual scripts via the attached `/scripts/` path; however, be sure to set any environment variables expected by the scripts by either `export`ing them manually:
```shell script
export VANILLA_VERSION=1.12.2
/scripts/start-magma
```
...or pre-pending script execution:
```shell script
VANILLA_VERSION=1.12.2 /scripts/start-magma
```
> NOTE: You may want to temporarily add an `exit` statement near the end of your script to isolate execution to just the script you're developing.
## Multi-base-image variants
Several base-image variants are maintained in order to offer choices in JDK provider and version. The variants are maintained in their respective branches:
- openj9
- openj9-nightly
- adopt11
- adopt13
- multiarch
The [docker-versions-create.sh](docker-versions-create.sh) script is configured with the branches to maintain and is used to merge changes from the master branch into the mulit-base variant branches. The script also manages git tagging the master branch along with the merged branches. So a typical use of the script would be like:
```shell script
./docker-versions-create.sh -s -t 1.2.0
```
> Most often the major version will be bumped unless a bug or hotfix needs to be published in which case the patch version should be incremented.
> The build and publishing of those branches and their tags is currently performed within Docker Hub.
## multiarch support
The [multiarch branch](https://github.com/itzg/docker-minecraft-server/tree/multiarch) supports running the image on amd64, arm64, and armv7 (aka RaspberryPi). Unlike the mainline branches, it is based on Ubuntu 18.04 since the openjdk package provided by Ubuntu includes full JIT support on all of the processor types.
The multiarch images are built and published by [a Github action](https://github.com/itzg/docker-minecraft-server/actions?query=workflow%3A%22Build+and+publish+multiarch%22), which [is configured in that branch](https://github.com/itzg/docker-minecraft-server/blob/multiarch/.github/workflows/build-multiarch.yml).
## Generating release notes
The following git command can be used to provide the bulk of release notes content:
```shell script
git log --invert-grep --grep "^ci:" --grep "^misc:" --grep "^docs:" --pretty="- %s" 1.1.0..1.2.0
```

View File

@@ -1,6 +1,9 @@
FROM openjdk:8u212-jre-alpine
FROM adoptopenjdk/openjdk13:alpine-jre
LABEL maintainer "itzg"
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
# upgrade all packages since alpine jre8 base image tops out at 8u212
RUN apk -U --no-cache upgrade
RUN apk add --no-cache -U \
openssl \
@@ -15,15 +18,18 @@ RUN apk add --no-cache -U \
mysql-client \
tzdata \
rsync \
nano
HEALTHCHECK --start-period=1m CMD mc-monitor status --host localhost --port $SERVER_PORT
nano \
sudo \
knock \
ttf-dejavu
RUN addgroup -g 1000 minecraft \
&& adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft \
&& mkdir -m 777 /data \
&& chown minecraft:minecraft /data /home/minecraft
COPY files/sudoers* /etc/sudoers.d
EXPOSE 25565 25575
# hook into docker BuildKit --platform support
@@ -63,14 +69,20 @@ COPY server.properties /tmp/server.properties
COPY log4j2.xml /tmp/log4j2.xml
WORKDIR /data
ENTRYPOINT [ "/start" ]
ENV UID=1000 GID=1000 \
JVM_XX_OPTS="-XX:+UseG1GC" MEMORY="1G" \
MEMORY="1G" \
TYPE=VANILLA VERSION=LATEST FORGEVERSION=RECOMMENDED SPONGEBRANCH=STABLE SPONGEVERSION= FABRICVERSION=LATEST LEVEL=world \
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" \
REPLACE_ENV_VARIABLES="FALSE" ENV_VARIABLE_PREFIX="CFG_"
ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 AUTOPAUSE_PERIOD=10
COPY start* /
COPY health.sh /
ADD files/autopause /autopause
RUN dos2unix /start* && chmod +x /start*
RUN dos2unix /health.sh && chmod +x /health.sh
RUN dos2unix /autopause/* && chmod +x /autopause/*.sh
ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD /health.sh

328
README.md
View File

@@ -2,16 +2,13 @@
[![Docker Stars](https://img.shields.io/docker/stars/itzg/minecraft-server.svg?maxAge=2592000)](https://hub.docker.com/r/itzg/minecraft-server/)
[![GitHub Issues](https://img.shields.io/github/issues-raw/itzg/docker-minecraft-server.svg)](https://github.com/itzg/docker-minecraft-server/issues)
[![Discord](https://img.shields.io/discord/660567679458869252)](https://discord.gg/DXfKpjB)
[![Build and Publish](https://github.com/itzg/docker-minecraft-server/workflows/Build%20and%20Publish/badge.svg)](https://github.com/itzg/docker-minecraft-server/actions)
[![](https://img.shields.io/badge/Donate-Buy%20me%20a%20coffee-orange.svg)](https://www.buymeacoffee.com/itzg)
This docker image provides a Minecraft Server that will automatically download the latest stable
version at startup. You can also run/upgrade to any specific version or the
latest snapshot. See the _Versions_ section below for more information.
[![Click for more docs](https://i.imgur.com/jS02ebD.png)](https://github.com/itzg/docker-minecraft-server/blob/master/README.md)
[Full docs available in Github](https://github.com/itzg/docker-minecraft-server/blob/master/README.md)
To simply use the latest stable version, run
docker run -d -p 25565:25565 --name mc itzg/minecraft-server
@@ -179,6 +176,44 @@ You can also query the container's health in a script friendly way:
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 (experimental)
### Description
> EXPERIMENTAL: this feature only works with default bridge networking using official Docker distributions. Host networking and container management software, such as Portainer, and NAS solutions do not seem to provide compatible networking.
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.
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.
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
```
There are 4 more environment variables that define the behaviour:
* `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)
## Deployment Templates and Examples
### Helm Charts
@@ -196,7 +231,7 @@ 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`.
$ docker run -d -v /path/on/host:/data -e VERSION=1.7.10 \
$ docker run -d -v /path/on/host:/data \
-e TYPE=FORGE -e FORGEVERSION=10.13.4.1448 \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
@@ -273,7 +308,7 @@ defined environment variables. Variables that you want to replace need to be wra
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 enviroment variables.
Optionally you can also define a prefix to only match predefined environment variables.
`ENV_VARIABLE_PREFIX="CFG_"` <-- this is the default prefix
@@ -289,6 +324,14 @@ There are some limitations to what characters you can use.
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
@@ -350,10 +393,10 @@ The content of `db_password`:
## Running a Bukkit/Spigot server
Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT -e VERSION=1.8` or `-e TYPE=SPIGOT -e VERSION=1.8` to your command-line.
Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT` or `-e TYPE=SPIGOT` to your command-line.
docker run -d -v /path/on/host:/data \
-e TYPE=SPIGOT -e VERSION=1.8 \
-e TYPE=SPIGOT \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
If you are hosting your own copy of Bukkit/Spigot you can override the download URLs with:
@@ -363,117 +406,27 @@ 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`
**NOTE: to avoid pegging the CPU when running Spigot,** you will need to
pass `--noconsole` at the very end of the command line and not use `-it`. For example,
docker run -d -v /path/on/host:/data \
-e TYPE=SPIGOT -e VERSION=1.8 \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server --noconsole
You can install Bukkit plugins in two ways...
### Using the /data volume
This is the easiest way if you are using a persistent `/data` mount.
To do this, you will need to attach the container's `/data` directory
(see "Attaching data directory to host filesystem”).
Then, you can add plugins to the `/path/on/host/plugins` folder you chose. From the example above,
the `/path/on/host` folder contents look like:
```
/path/on/host
├── plugins
│   └── ... INSTALL PLUGINS HERE ...
├── ops.json
├── server.properties
├── whitelist.json
└── ...
```
If you add plugins 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 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.
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.
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.
## Running a PaperSpigot server
Enable PaperSpigot server mode by adding a `-e TYPE=PAPER -e VERSION=1.9.4` to your command-line.
Enable PaperSpigot server mode by adding a `-e TYPE=PAPER` to your command-line.
By default the container will run the latest build of [Paper server](https://papermc.io/downloads)
but you can also choose to run a specific build with `-e PAPERBUILD=205`.
docker run -d -v /path/on/host:/data \
-e TYPE=PAPER -e VERSION=1.9.4 \
-e TYPE=PAPER \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
**NOTE: to avoid pegging the CPU when running PaperSpigot,** you will need to
pass `--noconsole` at the very end of the command line and not use `-it`. For example,
docker run -d -v /path/on/host:/data \
-e TYPE=PAPER -e VERSION=1.9.4 \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server --noconsole
If you are hosting your own copy of PaperSpigot you can override the download URL with:
- -e PAPER_DOWNLOAD_URL=<url>
You can install Bukkit plugins in two ways...
An example compose file is provided at
[examples/docker-compose-paper.yml](examples/docker-compose-paper.yml).
### Using the /data volume
This is the easiest way if you are using a persistent `/data` mount.
To do this, you will need to attach the container's `/data` directory
(see "Attaching data directory to host filesystem”).
Then, you can add plugins to the `/path/on/host/plugins` folder you chose. From the example above,
the `/path/on/host` folder contents look like:
```
/path/on/host
├── plugins
│   └── ... INSTALL PLUGINS HERE ...
├── ops.json
├── server.properties
├── whitelist.json
└── ...
```
If you add plugins 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 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.
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.
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.
## Running a Tuinity server
@@ -491,20 +444,64 @@ A [Magma](https://magmafoundation.org/) server, which is a combination of Forge
> **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2"
## Running a Server with a Feed-The-Beast (FTB) / CurseForge modpack
Enable this server mode by adding a `-e TYPE=FTB` or `-e TYPE=CURSEFORGE` to your command-line,
## Running a Mohist server
A [Mohist](https://github.com/Mohist-Community/Mohist) server can be used with
-e TYPE=MOHIST
> **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2"
## Running a Catserver type server
A [Catserver](http://catserver.moe/) type server can be used with
-e TYPE=CATSERVER
> **NOTE** Catserver only provides a single release stream, so `VERSION` is ignored
## Running a server with a Feed the Beast modpack
> **NOTE** requires `itzg/minecraft-server:multiarch` image
[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.
### Environment Variables:
- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by finding the modpack at [Neptune FTB](https://ftb.neptunepowered.org/) and using the "Pack ID"
- `FTB_MODPACK_VERSION_ID`: optional, the numerical Id of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by drilling into the Versions tab and clicking a specific version.
### Upgrading
If a specific `FTB_MODPACK_VERSION_ID` was not specified, simply restart the container to pick up the newest modpack version. If using a specific version ID, recreate the container with the new version ID.
### Example
The following example runs the latest version of [FTB Presents Direwolf20 1.12](https://ftb.neptunepowered.org/pack/ftb-presents-direwolf20-1-12/):
```
docker run -d --name mc-ftb -e EULA=TRUE \
-e TYPE=FTBA -e FTB_MODPACK_ID=31 \
-p 25565:25565 \
itzg/minecraft-server:multiarch
```
> Normally you will also add `-v` volume for `/data` since the mods and config are installed there along with world data.
## Running a server with a CurseForge modpack
Enable this server mode by adding `-e TYPE=CURSEFORGE` to your command-line,
but note the following additional steps needed...
You need to specify a modpack to run, using the `FTB_SERVER_MOD` or `CF_SERVER_MOD` environment
variable. An FTB/CurseForge server modpack is available together with its respective
client modpack on <https://www.feed-the-beast.com> under "Additional Files." Similar you can
locate the modpacks for CurseForge at <https://www.curseforge.com/minecraft/modpacks> .
You need to specify a modpack to run, using the `CF_SERVER_MOD` environment
variable. A CurseForge server modpack is available together with its respective
client modpack at <https://www.curseforge.com/minecraft/modpacks> .
Now you can add a `-e FTB_SERVER_MOD=name_of_modpack.zip` to your command-line.
Now you can add a `-e CF_SERVER_MOD=name_of_modpack.zip` to your command-line.
docker run -d -v /path/on/host:/data -e TYPE=FTB \
-e FTB_SERVER_MOD=FTBPresentsSkyfactory3Server_3.0.6.zip \
docker run -d -v /path/on/host:/data -e TYPE=CURSEFORGE \
-e CF_SERVER_MOD=SkyFactory_4_Server_4.1.0.zip \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
If you want to keep the pre-download modpacks separate from your data directory,
@@ -512,8 +509,8 @@ then you can attach another volume at a path of your choosing and reference that
The following example uses `/modpacks` as the container path as the pre-download area:
docker run -d -v /path/on/host:/data -v /path/to/modpacks:/modpacks \
-e TYPE=FTB \
-e FTB_SERVER_MOD=/modpacks/FTBPresentsSkyfactory3Server_3.0.6.zip \
-e TYPE=CURSEFORGE \
-e CF_SERVER_MOD=/modpacks/SkyFactory_4_Server_4.1.0.zip \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
### Fixing "unable to launch forgemodloader"
@@ -526,42 +523,6 @@ then you apply a workaround by adding this to the run invocation:
-e FTB_LEGACYJAVAFIXER=true
### Using a client-made curseforge modpack
If you use something like CurseForge, you may end up creating/using modpacks that do not
contain server mod jars. Instead, the CurseForge setup has `manifest.json` files, which
will show up under `/data/FeedTheBeast/manifest.json`.
To use these packs you will need to:
- Specify the manifest location with env var `MANIFEST=/data/FeedTheBeast/manifest`
- Pick a relevant ServerStart.sh and potentially settings.cfg and put them in `/data/FeedTheBeast`
An example of the latter would be to use <https://github.com/AllTheMods/Server-Scripts>
There, you'll find that all you have to do is put `ServerStart.sh` and `settings.cfg` into
`/data/FeedTheBeast`, taking care to update `settings.cfg` to specify your desired version
of minecraft and forge. You can do this in the cli with something like:
```
$ wget https://raw.githubusercontent.com/AllTheMods/Server-Scripts/master/ServerStart.sh
$ wget https://raw.githubusercontent.com/AllTheMods/Server-Scripts/master/settings.cfg
$ vim settings.cfg #update the forge version to the one you want. Your manifest.json will have it
$ chmod +x ServerStart.sh
$ docker run -itd --name derpcraft \
-e MANIFEST=/data/FeedTheBeast/manifest.json \
-v $PWD/ServerStart.sh:/data/FeedTheBeast/ServerStart.sh \
-v $PWD/settings.cfg:/data/FeedTheBeast/settings.cfg \
-e VERSION=1.12.2\
-e TYPE=CURSEFORGE\
-e CF_SERVER_MOD=https://minecraft.curseforge.com/projects/your_amazing_modpack/files/2670435/download\
-p 25565:25565\
-e EULA=TRUE\
--restart=always\
itzg/minecraft-server
```
Note the `CF_SERVER_MOD` env var should match the server version of the modpack you are targeting.
## Running a SpongeVanilla server
Enable SpongeVanilla server mode by adding a `-e TYPE=SPONGEVANILLA` to your command-line.
@@ -583,7 +544,7 @@ Enable Fabric server mode by adding a `-e TYPE=FABRIC` to your command-line.
By default the container will run the latest version of [Fabric server](http://fabricmc.net/use/)
but you can also choose to run a specific version with `-e FABRICVERSION=0.5.0.32`.
$ docker run -d -v /path/on/host:/data -e VERSION=1.14.3 \
$ docker run -d -v /path/on/host:/data \
-e TYPE=FABRIC -e FABRICVERSION=0.5.0.32 \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
@@ -643,6 +604,12 @@ 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.
## 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`.
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.
## 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
@@ -662,7 +629,7 @@ For example, with PaperSpigot, it would look something like this:
```
docker run -d -v /path/on/host:/data \
-e TYPE=PAPER -e VERSION=1.14.1 -e FORCE_REDOWNLOAD=true \
-e TYPE=PAPER -e FORCE_REDOWNLOAD=true \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
```
@@ -720,9 +687,13 @@ The server name (e.g. for bungeecord) can be set like:
### Server port
The server port can be set like:
> **WARNING:** only change this value if you know what you're doing. It is only needed when using host networking and it is rare that host networking should be used. Use `-p` port mappings instead.
docker run -d -e SERVER_PORT=25565 ...
If you must, the server port can be set like:
docker run -d -e SERVER_PORT=25566 ...
**however**, be sure to change your port mapping accordingly and be prepared for some features to break.
### Difficulty
@@ -944,7 +915,7 @@ For example (just the `-e` bits):
You can set a link to a custom resource pack and set it's checksum using the `RESOURCE_PACK` and `RESOURCE_PACK_SHA1` options respectively, the default is blank:
docker run -d -e 'RESROUCE_PACK=http\://link.com/to/pack.zip?\=1' -e 'RESOURCE_PACK_SHA1=d5db29cd03a2ed055086cef9c31c252b4587d6d0'
docker run -d -e 'RESOURCE_PACK=http\://link.com/to/pack.zip?\=1' -e 'RESOURCE_PACK_SHA1=d5db29cd03a2ed055086cef9c31c252b4587d6d0'
**NOTE:** `:` and `=` must be escaped using `\`. The checksum plain-text hexadecimal.
@@ -960,30 +931,19 @@ where the default is "world":
### Downloadable world
Instead of mounting the `/data` volume, you can instead specify the URL of
a ZIP file containing an archived world. This will be downloaded, and
unpacked in the `/data` directory; if it does not contain a subdirectory
called `world/` then it will be searched for a file `level.dat` and the
containing subdirectory renamed to `world`. This means that most of the
archived Minecraft worlds downloadable from the Internet will already be in
the correct format.
The ZIP file may also contain a `server.properties` file and `modules`
directory, if required.
Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format.
docker run -d -e WORLD=http://www.example.com/worlds/MySave.zip ...
**NOTE:** Unless you also mount `/data` as an external volume, this world
will be deleted when the container is deleted.
**NOTE:** This URL must be accessible from inside the container. Therefore,
you should use an IP address or a globally resolveable FQDN, or else the
you should use an IP address or a globally resolvable FQDN, or else the
name of a linked container.
**NOTE:** If the archive contains more than one `level.dat`, then the one to select can be picked with `WORLD_INDEX`, which defaults to 1.
### Cloning world from a container path
The `WORLD` option can also be used to reference a directory that will be used
as a source to clone the world directory.
The `WORLD` option can also be used to reference a directory or zip file that will be used as a source to clone or unzip the world directory.
For example, the following would initially clone the world's content
from `/worlds/basic`. Also notice in the example that you can use a
@@ -993,6 +953,9 @@ read-only volume attachment to ensure the clone source remains pristine.
docker run ... -v $HOME/worlds:/worlds:ro -e WORLD=/worlds/basic
```
### Overwrite world on start
The world will only be downloaded or copied if it doesn't exist already. Set `FORCE_WORLD_COPY=TRUE` to force overwrite the world on every server start.
### Downloadable mod/plugin pack for Forge, Bukkit, and Spigot Servers
Like the `WORLD` option above, you can specify the URL of a "mod pack"
@@ -1036,9 +999,21 @@ Allows users to use flight on your server while in Survival mode, if they have a
### Other server property mappings
Environment Variable | Server Property
---------------------|-----------------
PLAYER_IDLE_TIMEOUT | player-idle-timeout
| Environment Variable | Server Property |
| --------------------------------- | --------------------------------- |
| PLAYER_IDLE_TIMEOUT | player-idle-timeout |
| BROADCAST_CONSOLE_TO_OPS | broadcast-console-to-ops |
| BROADCAST_RCON_TO_OPS | broadcast-rcon-to-ops |
| ENABLE_JMX | enable-jmx-monitoring |
| SYNC_CHUNK_WRITES | sync-chunk-writes |
| ENABLE_STATUS | enable-status |
| ENTITY_BROADCAST_RANGE_PERCENTAGE | entity-broadcast-range-percentage |
| FUNCTION_PERMISSION_LEVEL | function-permission-level |
| NETWORK_COMPRESSION_THRESHOLD | network-compression-threshold |
| OP_PERMISSION_LEVEL | op-permission-level |
| PREVENT_PROXY_CONNECTIONS | prevent-proxy-connections |
| USE_NATIVE_TRANSPORT | use-native-transport |
| ENFORCE_WHITELIST | enforce-whitelist |
## Miscellaneous Options
@@ -1098,15 +1073,14 @@ Large page support can also be enabled by adding
### HTTP Proxy
You may configure the use of an HTTP/HTTPS proxy by passing the proxy's URL via the `PROXY`
environment variable. In [the example compose file](docker-compose-proxied.yml) it references
environment variable. In [the example compose file](examples/docker-compose-proxied.yml) it references
a companion squid proxy by setting the equivalent of
-e PROXY=proxy:3128
### Using "noconsole" option
Some older versions of Spigot required `--noconsole` to be passed when detaching stdin. You can
pass that at the end of `docker run` after the image name or set `-e CONSOLE=FALSE`.
Some older versions (pre-1.14) of Spigot required `--noconsole` to be passed when detaching stdin, which can be done by setting `-e CONSOLE=FALSE`.
### Explicitly disable GUI
@@ -1117,6 +1091,6 @@ disable that by passing `-e GUI=FALSE`.
To run this image on a RaspberryPi 3 B+, 4, or newer, use the image tag
itzg/minecraft-server:armv7
itzg/minecraft-server:multiarch
> NOTE: you may need to lower the memory allocation, such as `-e MEMORY=750m`

View File

@@ -1,34 +0,0 @@
#!/bin/bash
# manually purge any pre-existing manifest list
# since docker manifest command lacks a "remove" operation
rm -rf ~/.docker/manifests/docker.io_itzg_minecraft-server-multiarch
export DOCKER_BUILDKIT=1
docker build --platform linux/arm64 -t itzg/minecraft-server:arm64 .
docker push itzg/minecraft-server:arm64
armv7tag=armv7-buildkit
armv7workDir=/tmp/armv7-$$
git worktree add $armv7workDir armv7
# sub-shell for build of armv7
(
cd $armv7workDir
docker build --platform linux/arm/v7 -t itzg/minecraft-server:$armv7tag .
docker push itzg/minecraft-server:$armv7tag
)
git worktree remove $armv7workDir
docker pull itzg/minecraft-server
# use the rpi build one for now since armv7-buildkit is giving ABI mismatch on curl
docker pull itzg/minecraft-server:armv7
docker manifest create itzg/minecraft-server:multiarch \
itzg/minecraft-server \
itzg/minecraft-server:armv7 \
itzg/minecraft-server:arm64
docker manifest inspect itzg/minecraft-server:multiarch
docker manifest push -p itzg/minecraft-server:multiarch

View File

@@ -1,18 +0,0 @@
#!/bin/bash
manifest="itzg/minecraft-server:multiarch"
for t in latest rpi3 aarch64; do
docker pull itzg/minecraft-server:$t
done
docker manifest create --amend ${manifest} \
itzg/minecraft-server:aarch64 \
itzg/minecraft-server:latest \
itzg/minecraft-server:rpi3
docker manifest annotate --os linux --arch amd64 ${manifest} itzg/minecraft-server:latest
docker manifest annotate --os linux --arch arm64 ${manifest} itzg/minecraft-server:aarch64
docker manifest annotate --os linux --arch arm --variant v7 ${manifest} itzg/minecraft-server:rpi3
docker manifest push ${manifest}

View File

@@ -10,19 +10,7 @@ services:
- "mc:/data"
environment:
EULA: "TRUE"
CONSOLE: "false"
ENABLE_RCON: "true"
RCON_PASSWORD: "testing"
RCON_PORT: 28016
restart: always
rcon:
image: itzg/rcon
ports:
- "4326:4326"
- "4327:4327"
volumes:
- "rcon:/opt/rcon-web-admin/db"
volumes:
mc:
rcon:
mc: {}

View File

@@ -1,7 +1,7 @@
#!/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' 'multiarch' 'armv7')
branches_list=('openj9' 'openj9-nightly' 'adopt11' 'adopt13' 'multiarch')
function TrapExit {
echo "Checking out back in master"
@@ -10,12 +10,32 @@ function TrapExit {
batchMode=false
while getopts "b" arg
while getopts "hbt:s" arg
do
case $arg in
b)
batchMode=true
;;
t)
tag=${OPTARG}
;;
s)
tagArgs="-s -m 'Signed during docker-versions-create"
;;
h)
echo "
Usage $0 [options]
Options:
-b enable batch mode, which avoids interactive prompts and causes script to fail immediately
when any merge fails
-t TAG tag and push the current revision on master with the given tag
and apply respective tags to each branch
-s enable signed tags
-h display this help and exit
"
exit
;;
*)
echo "Unsupported arg $arg"
exit 2
@@ -34,6 +54,10 @@ test -d ./.git || { echo ".git folder was not found. Please start this script fr
git checkout master
git pull --all || { echo "Can't pull the repo!"; \
exit 1; }
if [[ $tag ]]; then
git tag $tag
git push origin $tag
fi
git_branches=$(git branch -a)
@@ -57,6 +81,10 @@ for branch in "${branches_list[@]}"; do
git commit -m "Auto merge branch with master" -a
# push may fail if remote doesn't have this branch yet. In this case - sending branch
git push || git push -u origin "$branch" || { echo "Can't push changes to the origin."; exit 1; }
if [[ $tag ]]; then
git tag "$tag-$branch"
git push origin "$tag-$branch"
fi
elif ${batchMode}; then
status=$?
echo "Git merge failed in batch mode"

View File

@@ -0,0 +1,18 @@
version: '3.8'
services:
minecraft:
image: itzg/minecraft-server
ports:
- "25565:25565"
volumes:
- "mc:/data"
environment:
EULA: "TRUE"
ENABLE_AUTOPAUSE: "TRUE"
OVERRIDE_SERVER_PROPERTIES: "TRUE"
MAX_TICK_TIME: "-1"
restart: always
volumes:
mc: {}

View File

@@ -3,9 +3,11 @@ version: '3.2'
services:
mc:
image: itzg/minecraft-server
volumes:
- ./modpacks:/modpacks:ro
environment:
EULA: "true"
TYPE: FTB
FTB_SERVER_MOD: https://minecraft.curseforge.com/projects/all-the-mods-expert-remastered/files/2493900/download
TYPE: CURSEFORGE
CF_SERVER_MOD: /modpacks/SkyFactory_4_Server_4.1.0.zip
ports:
- 25565:25565

View File

@@ -1,16 +0,0 @@
version: '3.2'
services:
mc:
image: itzg/minecraft-server
environment:
EULA: "true"
TYPE: FTB
FTB_SERVER_MOD: https://www.feed-the-beast.com/projects/ftb-presents-skyfactory-3/files/2481284
ports:
- 25565:25565
volumes:
- mc-ftb:/data
volumes:
mc-ftb:

View File

@@ -0,0 +1,23 @@
version: "3.7"
services:
mc:
# FTBA support is only available in multiarch image tag
image: itzg/minecraft-server:multiarch
ports:
# expose the Minecraft server port outside of container
- 25565:25565
environment:
# REQUIRED for all types
EULA: "TRUE"
# Set server type (vs the default of vanilla)
TYPE: FTBA
# Use Pack ID from https://ftb.neptunepowered.org/pack/ftb-presents-direwolf20-1-12/
FTB_MODPACK_ID: "31"
volumes:
# use a named, managed volume for data volume
- mc_ftb:/data
volumes:
# declared the named volume, but use default/local storage engine
mc_ftb: {}

View File

@@ -7,11 +7,12 @@ services:
EULA: "true"
TYPE: PAPER
VERSION: 1.9.4
command: --noconsole
# needed for Paper versions before 1.14
CONSOLE: "false"
ports:
- 25565:25565
volumes:
- mc-paper:/data
volumes:
mc-paper:
mc-paper:

View File

@@ -0,0 +1,11 @@
version: "3.7"
services:
mc:
image: itzg/minecraft-server
ports:
- 25565:25565
environment:
EULA: "TRUE"
VERSION: 1.7.2
WORLD: https://www.minecraftmaps.com/survival-maps/cube-survival/download

1
examples/modpacks/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.zip

View File

@@ -0,0 +1,3 @@
Please server [modpacks downloaded from CurseForge](https://www.curseforge.com/minecraft/modpacks) in this directory.
The example [`docker-compose-curseforge.yml`](../docker-compose-curseforge.yml) references a modpack downloaded from <https://www.curseforge.com/minecraft/modpacks/skyfactory-4/files/2787018>.

View File

@@ -0,0 +1,97 @@
#!/bin/bash
. /autopause/autopause-fcns.sh
. /start-utils
sudo /usr/sbin/knockd -c /autopause/knockd-config.cfg -d
if [ $? -ne 0 ] ; then
while :
do
if [[ -n $(ps -o comm | grep java) ]] ; then
break
fi
sleep 0.1
done
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."
killall -SIGTERM java
exit 1
fi
STATE=INIT
while :
do
case X$STATE in
XINIT)
# Server startup
if mc_server_listening ; then
TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_INIT))
logAutopause "MC Server listening for connections - stopping in $AUTOPAUSE_TIMEOUT_INIT seconds"
STATE=K
fi
;;
XK)
# Knocked
if java_clients_connected ; then
logAutopause "Client connected - waiting for disconnect"
STATE=E
else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutopause "No client connected since startup / knocked - stopping"
/autopause/pause.sh
STATE=S
fi
fi
;;
XE)
# Established
if ! java_clients_connected ; then
TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_EST))
logAutopause "All clients disconnected - stopping in $AUTOPAUSE_TIMEOUT_EST seconds"
STATE=I
fi
;;
XI)
# Idle
if java_clients_connected ; then
logAutopause "Client reconnected - waiting for disconnect"
STATE=E
else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutopause "No client reconnected - stopping"
/autopause/pause.sh
STATE=S
fi
fi
;;
XS)
# Stopped
if rcon_client_exists ; then
/autopause/resume.sh
fi
if java_running ; then
if java_clients_connected ; then
logAutopause "Client connected - waiting for disconnect"
STATE=E
else
TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_KN))
logAutopause "Server was knocked - waiting for clients or timeout"
STATE=K
fi
fi
;;
*)
logAutopause "Error: invalid state: $STATE"
;;
esac
if [[ "$STATE" == "S" ]] ; then
# before rcon times out
sleep 2
else
sleep $AUTOPAUSE_PERIOD
fi
done

View File

@@ -0,0 +1,38 @@
#!/bin/bash
current_uptime() {
echo $(awk '{print $1}' /proc/uptime | cut -d . -f 1)
}
java_running() {
[[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]]
}
rcon_client_exists() {
[[ -n "$(ps -a -o comm | grep 'rcon-cli')" ]]
}
mc_server_listening() {
[[ -n $(netstat -tln | grep "0.0.0.0:$SERVER_PORT" | grep LISTEN) ]]
}
java_clients_connected() {
local connections
connections=$(netstat -tn | grep ":$SERVER_PORT" | grep ESTABLISHED)
if [[ -z "$connections" ]] ; then
return 1
fi
IFS=$'\n'
connections=($connections)
unset IFS
# check that at least one external address is not localhost
# remember, that the host network mode does not work with autopause because of the knockd utility
for (( i=0; i<${#connections[@]}; i++ ))
do
if [[ ! $(echo "${connections[$i]}" | awk '{print $5}') =~ ^\s*127\.0\.0\.1:.*$ ]] ; then
# not localhost
return 0
fi
done
return 1
}

View File

@@ -0,0 +1,12 @@
[options]
logfile = /dev/null
[unpauseMCServer-server]
sequence = 25565
seq_timeout = 1
command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh
tcpflags = syn
[unpauseMCServer-rcon]
sequence = 25575
seq_timeout = 1
command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh
tcpflags = syn

21
files/autopause/pause.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
. /start-utils
if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then
# save world
rcon-cli save-all >/dev/null
# wait until mc-monitor is no longer connected to the server
while :
do
if [[ -z "$(netstat -nt | grep "127.0.0.1:$SERVER_PORT" | grep 'ESTABLISHED')" ]]; then
break
fi
sleep 0.1
done
# finally pause the process
logAutopauseAction "Pausing Java process"
killall -q -STOP java
fi

8
files/autopause/resume.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
. /start-utils
if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then
logAutopauseAction "Knocked, resuming Java process"
killall -q -CONT java
fi

2
files/sudoers-mc Normal file
View File

@@ -0,0 +1,2 @@
%minecraft ALL=(ALL) NOPASSWD:/usr/bin/killall
%minecraft ALL=(ALL) NOPASSWD:/usr/sbin/knockd

14
health.sh Normal file
View File

@@ -0,0 +1,14 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
if isTrue "${DISABLE_HEALTHCHECK}"; then
echo "Healthcheck disabled"
exit 0
elif isTrue "${ENABLE_AUTOPAUSE}" && [[ "$( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }')" =~ ^T.*$ ]]; then
echo "Java process suspended by Autopause function"
exit 0
else
mc-monitor status --host localhost --port $SERVER_PORT
exit $?
fi

View File

@@ -37,3 +37,15 @@ motd=A Minecraft Server powered by Docker
generator-settings=
rcon.password=
max-world-size=29999984
broadcast-console-to-ops=true
broadcast-rcon-to-ops=true
enable-jmx-monitoring=false
sync-chunk-writes=true
enable-status=true
entity-broadcast-range-percentage=100
function-permission-level=2
network-compression-threshold=256
op-permission-level=4
prevent-proxy-connections=false
use-native-transport=true
enforce-whitelist=false

11
start
View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
umask 0002
chmod g+w /data
@@ -36,11 +36,16 @@ if [ $(id -u) = 0 ]; then
chown -R ${runAsUser}:${runAsGroup} /data
fi
if [[ $(stat -c "%u" /autopause) != $UID ]]; then
log "Changing ownership of /autopause to $UID ..."
chown -R ${runAsUser}:${runAsGroup} /autopause
fi
if [[ ${SKIP_NSSWITCH_CONF^^} != TRUE ]]; then
echo 'hosts: files dns' > /etc/nsswitch.conf
fi
exec su-exec ${runAsUser}:${runAsGroup} /start-configuration $@
exec su-exec ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration $@
else
exec /start-configuration $@
exec ${SCRIPTS:-/}start-configuration $@
fi

60
start-autopause Executable file
View File

@@ -0,0 +1,60 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
log "Autopause functionality enabled"
# update server port to listen to
regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$"
linenum=$(grep -nm1 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1)
if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then
sed -i "${linenum}s/sequence.*/sequence = $SERVER_PORT/" /autopause/knockd-config.cfg
log "Updated server port in knockd config"
fi
# update rcon port to listen to
regseq="^\s*sequence\s*=\s*$RCON_PORT\s*$"
linenum=$(grep -nm2 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1)
if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then
sed -i "${linenum}s/sequence.*/sequence = $RCON_PORT/" /autopause/knockd-config.cfg
log "Updated rcon port in knockd config"
fi
if ! [[ $AUTOPAUSE_PERIOD =~ ^[0-9]+$ ]]; then
AUTOPAUSE_PERIOD=10
export AUTOPAUSE_PERIOD
log "Warning: AUTOPAUSE_PERIOD is not numeric, set to 10 (seconds)"
fi
if [ "$AUTOPAUSE_PERIOD" -eq "0" ] ; then
AUTOPAUSE_PERIOD=10
export AUTOPAUSE_PERIOD
log "Warning: AUTOPAUSE_PERIOD must not be 0, set to 10 (seconds)"
fi
if ! [[ $AUTOPAUSE_TIMEOUT_KN =~ ^[0-9]+$ ]] ; then
AUTOPAUSE_TIMEOUT_KN=120
export AUTOPAUSE_TIMEOUT_KN
log "Warning: AUTOPAUSE_TIMEOUT_KN is not numeric, set to 120 (seconds)"
fi
if ! [[ $AUTOPAUSE_TIMEOUT_EST =~ ^[0-9]+$ ]] ; then
AUTOPAUSE_TIMEOUT_EST=3600
export AUTOPAUSE_TIMEOUT_EST
log "Warning: AUTOPAUSE_TIMEOUT_EST is not numeric, set to 3600 (seconds)"
fi
if ! [[ $AUTOPAUSE_TIMEOUT_INIT =~ ^[0-9]+$ ]] ; then
AUTOPAUSE_TIMEOUT_INIT=600
export AUTOPAUSE_TIMEOUT_INIT
log "Warning: AUTOPAUSE_TIMEOUT_INIT is not numeric, set to 600 (seconds)"
fi
if [[ -n $MAX_TICK_TIME ]] ; then
log "Warning: MAX_TICK_TIME is non-default, for autopause to work properly, this check should be disabled (-1 for versions >= 1.8.1)"
else
if versionLessThan 1.8.1; then
# 10 years
MAX_TICK_TIME=315360000000
else
MAX_TICK_TIME=-1
fi
export MAX_TICK_TIME
fi
/autopause/autopause-daemon.sh &

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
shopt -s nullglob
@@ -40,10 +40,27 @@ rm /data/.verify_access || true
if [[ $PROXY ]]; then
export http_proxy="$PROXY"
export https_proxy="$PROXY"
export JAVA_TOOL_OPTIONS+="-Djava.net.useSystemProxies=true"
log "INFO: Giving proxy time to startup..."
sleep 5
fi
if [[ $RCON_PASSWORD_FILE ]]; then
log ""
if [ ! -e ${RCON_PASSWORD_FILE} ]; then
log "Initial RCON password file ${RCON_PASSWORD_FILE} does not seems to exist."
log "Please ensure your configuration."
log "If you are using Docker Secrets feature, please check this for further information: "
log " https://docs.docker.com/engine/swarm/secrets"
log ""
exit 1
else
RCON_PASSWORD=$(cat ${RCON_PASSWORD_FILE})
export RCON_PASSWORD
fi
log ""
fi
export SERVER_PROPERTIES=/data/server.properties
export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json
@@ -68,55 +85,69 @@ cd /data || exit 1
export ORIGINAL_TYPE=${TYPE^^}
if isTrue "${ENABLE_AUTOPAUSE}"; then
${SCRIPTS:-/}start-autopause
fi
log "Resolving type given ${TYPE}"
case "${TYPE^^}" in
*BUKKIT|SPIGOT)
exec /start-deployBukkitSpigot "$@"
exec ${SCRIPTS:-/}start-deployBukkitSpigot "$@"
;;
PAPER)
exec /start-deployPaper "$@"
exec ${SCRIPTS:-/}start-deployPaper "$@"
;;
TUINITY)
exec /start-deployTuinity "$@"
exec ${SCRIPTS:-/}start-deployTuinity "$@"
;;
FORGE)
exec /start-deployForge "$@"
exec ${SCRIPTS:-/}start-deployForge "$@"
;;
FABRIC)
exec /start-deployFabric "$@"
exec ${SCRIPTS:-/}start-deployFabric "$@"
;;
FTB|CURSEFORGE)
exec /start-deployFTB "$@"
exec ${SCRIPTS:-/}start-deployFTB "$@"
;;
VANILLA)
exec /start-deployVanilla "$@"
exec ${SCRIPTS:-/}start-deployVanilla "$@"
;;
SPONGEVANILLA)
exec /start-deploySpongeVanilla "$@"
exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@"
;;
CUSTOM)
exec /start-deployCustom "$@"
exec ${SCRIPTS:-/}start-deployCustom "$@"
;;
CURSE_INSTANCE)
exec /start-validateCurseInstance "$@"
exec ${SCRIPTS:-/}start-validateCurseInstance "$@"
;;
MAGMA)
exec /start-magma "$@"
exec ${SCRIPTS:-/}start-deployMagma "$@"
;;
MOHIST)
exec ${SCRIPTS:-/}start-deployMohist "$@"
;;
CATSERVER)
exec ${SCRIPTS:-/}start-deployCatserver "$@"
;;
*)
log "Invalid type: '$TYPE'"
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTB, CURSEFORGE, SPONGEVANILLA"
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
log " CURSE_INSTANCE, CURSEFORGE, SPONGEVANILLA,"
log " CUSTOM, MAGMA, MOHIST, CATSERVER"
exit 1
;;

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
set -e
@@ -62,8 +62,12 @@ function downloadSpigot {
downloadUrl="https://cdn.getbukkit.org/${getbukkitFlavor}/${getbukkitFlavor}-${VANILLA_VERSION}.jar"
fi
if [ -f $SERVER ]; then
# tell curl to only download when newer
zarg="-z $SERVER"
fi
log "Downloading $match from $downloadUrl ..."
curl -fsSL -o $SERVER "$downloadUrl"
curl -fsSL -o $SERVER $zarg "$downloadUrl"
if [[ $? != 0 || $(grep -c "DOCTYPE html" $SERVER) != 0 ]]; then
cat <<EOF
@@ -89,12 +93,12 @@ case "$TYPE" in
;;
esac
if [ ! -f $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
if isTrue "$BUILD_SPIGOT_FROM_SOURCE" || isTrue "$BUILD_FROM_SOURCE"; then
buildSpigotFromSource
else
downloadSpigot
fi
if isTrue "$BUILD_SPIGOT_FROM_SOURCE" || isTrue "$BUILD_FROM_SOURCE"; then
if [ ! -f $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
buildSpigotFromSource
fi
else
downloadSpigot
fi
# Normalize on Spigot for operations below
@@ -102,4 +106,4 @@ export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

32
start-deployCatserver Normal file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
set -o pipefail
set -e
latestAsset=$(
curl -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/latest | \
jq '.assets[] | select(.name | match(".*-universal.jar"))'
)
if [[ -z "${latestAsset}" ]]; then
log "ERROR: latest release of Catserver is missing universal.jar asset"
exit 1
fi
isDebugging && log "Latest asset ${latestAsset}"
latestJarName=$(echo ${latestAsset} | jq --raw-output '.name')
latestJarId=$(echo ${latestAsset} | jq --raw-output '.id')
export SERVER="/data/${latestJarName}"
if [ ! -f ${SERVER} ]; then
log "Downloading ${latestJarName}"
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId}
fi
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld "$@"

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
if isURL ${CUSTOM_SERVER}; then
filename=$(basename ${CUSTOM_SERVER})
@@ -28,4 +28,4 @@ fi
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
export FTB_BASE_DIR=/data/FeedTheBeast
legacyJavaFixerUrl=http://ftb.cursecdn.com/FTB2/maven/net/minecraftforge/lex/legacyjavafixer/1.0/legacyjavafixer-1.0.jar
@@ -16,7 +16,12 @@ if [[ -z $FTB_SERVER_MOD ]]; then
exit 2
fi
entryScriptExpr="-name ServerStart.sh -o -name ServerStartLinux.sh -o -name LaunchServer.sh"
entryScriptExpr="
-name ServerStart.sh
-o -name ServerStartLinux.sh
-o -name LaunchServer.sh
-o -name server-start.sh
"
if [[ -d ${FTB_BASE_DIR} ]]; then
startScriptCount=$(find ${FTB_BASE_DIR} $entryScriptExpr |wc -l)
@@ -130,4 +135,4 @@ elif [ -e "${FTB_DIR}/Install.sh" ]; then
fi
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,7 +1,7 @@
#!/bin/bash
set -eu
. /start-utils
. ${SCRIPTS:-/}start-utils
export TYPE=FABRIC
@@ -75,4 +75,4 @@ else
fi
# Contineut to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
export TYPE=FORGE
@@ -113,4 +113,4 @@ else
fi
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

4
start-magma → start-deployMagma Executable file → Normal file
View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
export SERVER="/data/magma-server-${VANILLA_VERSION}.jar"
@@ -15,4 +15,4 @@ fi
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

43
start-deployMohist Normal file
View File

@@ -0,0 +1,43 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
set -o pipefail
set -e
isDebugging && set -x
requireVar VANILLA_VERSION
mohistJobs=https://ci.codemc.io/job/Mohist-Community/job/
mohistJob=${mohistJobs}Mohist-${VANILLA_VERSION}/
if ! curl -X HEAD -o /dev/null -fsSL "${mohistJob}"; then
log "ERROR: mohist builds do not exist for ${VANILLA_VERSION}"
log " check https://ci.codemc.io/job/Mohist-Community/ for available versions"
log " and set VERSION accordingly"
exit 1
fi
latestBuildRelPath=$(
curl -fsSL "${mohistJob}lastSuccessfulBuild/api/json" |
jq -r '.artifacts[0].relativePath'
)
baseName=$(basename "${latestBuildRelPath}")
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"
log " and set VERSION accordingly"
exit 1
fi
export SERVER="/data/${baseName}"
if [ ! -f ${SERVER} ]; then
log "Downloading ${baseName}"
curl -o "${SERVER}" -fsSL "${mohistJob}lastSuccessfulBuild/artifact/${latestBuildRelPath}"
fi
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld "$@"

View File

@@ -1,23 +1,24 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
: ${PAPERBUILD:=latest}
export SERVER=paper_server-${VANILLA_VERSION}-${PAPERBUILD}.jar
if [ ! -f "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
downloadUrl=${PAPER_DOWNLOAD_URL:-https://papermc.io/api/v1/paper/${VANILLA_VERSION}/${PAPERBUILD}/download}
log "Downloading Paper $VANILLA_VERSION (build $PAPERBUILD) from $downloadUrl ..."
curl -fsSL -o "$SERVER" "$downloadUrl"
if [ ! -f "$SERVER" ]; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
if [ -f "$SERVER" ] && ! isTrue "$FORCE_REDOWNLOAD"; then
zarg="-z '$SERVER'"
fi
# Normalize on Spigot for operations below
downloadUrl=${PAPER_DOWNLOAD_URL:-https://papermc.io/api/v1/paper/${VANILLA_VERSION}/${PAPERBUILD}/download}
log "Downloading Paper $VANILLA_VERSION (build $PAPERBUILD) from $downloadUrl ..."
if ! curl -fsSL -o "$SERVER" $zarg "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
# Normalize on Spigot for downstream operations
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
export TYPE=spongevanilla
@@ -36,4 +36,4 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
fi
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
if [ "${VERSION}" != "LATEST" ]; then
log "ERROR: Tunity server type only supports VERSION=LATEST"
@@ -24,4 +24,4 @@ fi
export TYPE=SPIGOT
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,6 +1,7 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
set -o pipefail
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
@@ -39,5 +40,7 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
fi
fi
isDebugging && ls -l
# Continue to Final Setup
exec /start-finalSetup01World $@
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,53 +0,0 @@
#!/bin/bash
. /start-utils
if [ $TYPE = "FEED-THE-BEAST" ]; then
worldDest=$FTB_BASE_DIR/$LEVEL
else
worldDest=/data/$LEVEL
fi
# If no world exists and a URL for a world is supplied, download it and unpack
if [[ "$WORLD" ]] && [ ! -d "$worldDest" ]; then
case "X$WORLD" in
X[Hh][Tt][Tt][Pp]*)
log "Downloading world from $WORLD"
curl -sSL -o - "$WORLD" > /data/world.zip
log "Unzipping world"
unzip -o -q /data/world.zip
rm -f /data/world.zip
if [ ! -d $worldDest ]; then
log World directory not found
for i in /data/*/level.dat; do
if [ -f "$i" ]; then
d=`dirname "$i"`
log Renaming world directory from $d
mv -f "$d" $worldDest
fi
done
fi
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"
fi
;;
*)
if [[ -d "$WORLD" ]]; then
if [[ ! -d "$worldDest" ]]; then
log "Cloning world directory from $WORLD ..."
cp -r "$WORLD" "$worldDest"
else
log "Skipping clone from $WORLD since $worldDest exists"
fi
else
log "World cloning source '$WORLD' doesn't seem to exist"
exit 1
fi
;;
esac
fi
exec /start-finalSetup02Modpack $@

View File

@@ -1,9 +1,26 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
if [ "${REPLACE_ENV_VARIABLES^^}" = "TRUE" ]; then
: ${ENV_VARIABLE_PREFIX:=CFG_}
if isTrue "${REPLACE_ENV_VARIABLES}"; then
log "Replacing env variables in configs that match the prefix $ENV_VARIABLE_PREFIX..."
findExcludes=
# File excludes
for f in ${REPLACE_ENV_VARIABLES_EXCLUDES}; do
findExcludes="${findExcludes} -not -name $f"
done
# Directory excludes (recursive)
dirExcludes=$(join_by " -o -path " ${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS})
if [[ $dirExcludes ]]; then
findExcludes+=" -type d ( -path ${dirExcludes} ) -prune"
fi
isDebugging && echo "Using find exclusions: $findExcludes"
while IFS='=' read -r name value ; do
# check if name of env variable matches the prefix
# sanity check environment variables to avoid code injections
@@ -20,9 +37,10 @@ if [ "${REPLACE_ENV_VARIABLES^^}" = "TRUE" ]; then
find /data/ -type f \
\( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" \
-or -name "*.conf" -or -name "*.properties" \) \
$findExcludes \
-exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \;
fi
done < <(env)
fi
exec /start-minecraftFinalSetup $@
exec ${SCRIPTS:-/}start-minecraftFinalSetup $@

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
# If supplied with a URL for a config (simple zip of configurations), download it and unpack
if [[ "$MODCONFIG" ]]; then
@@ -24,4 +24,4 @@ case "X$MODCONFIG" in
esac
fi
exec /start-finalSetup04ServerProperties $@
exec ${SCRIPTS:-/}start-finalSetupPlugins $@

View File

@@ -2,7 +2,7 @@
set -e
. /start-utils
. ${SCRIPTS:-/}start-utils
# CURSE_URL_BASE used in manifest downloads below
CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
@@ -154,4 +154,4 @@ if [[ "${GENERIC_PACK}" ]]; then
fi
fi
exec /start-finalSetup03Modconfig $@
exec ${SCRIPTS:-/}start-finalSetupModconfig $@

23
start-finalSetupPlugins Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
: ${PLUGINS_SYNC_UPDATE:=true}
isDebugging && set -x
if [ -d /plugins ]; then
case ${TYPE} in
SPIGOT|BUKKIT|PAPER)
mkdir -p /data/plugins
log "Copying plugins over..."
if isTrue ${PLUGINS_SYNC_UPDATE}; then
updateArg="--update"
fi
# Copy plugins over using rsync to allow deeply nested updates of plugins
rsync -a --out-format="update:%f:Last Modified %M" --prune-empty-dirs $updateArg /plugins /data
;;
esac
fi
exec ${SCRIPTS:-/}start-finalSetupServerProperties $@

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
# FUNCTIONS
function setServerProp {
@@ -77,6 +77,18 @@ function customizeServerProps {
setServerProp "resource-pack" "$RESOURCE_PACK"
setServerProp "resource-pack-sha1" "$RESOURCE_PACK_SHA1"
setServerProp "player-idle-timeout" "$PLAYER_IDLE_TIMEOUT"
setServerProp "broadcast-console-to-ops" "$BROADCAST_CONSOLE_TO_OPS"
setServerProp "broadcast-rcon-to-ops" "$BROADCAST_RCON_TO_OPS"
setServerProp "enable-jmx-monitoring" "$ENABLE_JMX"
setServerProp "sync-chunk-writes" "$SYNC_CHUNK_WRITES"
setServerProp "enable-status" "$ENABLE_STATUS"
setServerProp "entity-broadcast-range-percentage" "$ENTITY_BROADCAST_RANGE_PERCENTAGE"
setServerProp "function-permission-level" "$FUNCTION_PERMISSION_LEVEL"
setServerProp "network-compression-threshold" "$NETWORK_COMPRESSION_THRESHOLD"
setServerProp "op-permission-level" "$OP_PERMISSION_LEVEL"
setServerProp "prevent-proxy-connections" "$PREVENT_PROXY_CONNECTIONS"
setServerProp "use-native-transport" "$USE_NATIVE_TRANSPORT"
setServerProp "enforce-whitelist" "$ENFORCE_WHITELIST"
if [ -n "$DIFFICULTY" ]; then
case $DIFFICULTY in
@@ -180,4 +192,18 @@ else
log "server.properties already created, skipping"
fi
exec /start-finalSetup05EnvVariables $@
if isTrue "${ENABLE_AUTOPAUSE}"; then
current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' )
if (( $current_max_tick > 0 && $current_max_tick < 86400000 )); then
log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled."
log "Warning (cont): Autopause functionality resuming the process might trigger the Watchdog and restart the server completely."
log "Warning (cont): Set the max-tick-time property to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)."
fi
fi
if isDebugging; then
log "DEBUG Dumping server.properties"
cat /data/server.properties
fi
exec ${SCRIPTS:-/}start-finalSetupEnvVariables $@

54
start-finalSetupWorld Normal file
View File

@@ -0,0 +1,54 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
set -e
isDebugging && set -x
if [ $TYPE = "FEED-THE-BEAST" ]; then
worldDest=$FTB_DIR/$LEVEL
else
worldDest=/data/$LEVEL
fi
if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); then
if isURL $WORLD; then
curl -fsSL "$WORLD" -o /tmp/world.zip
zipSrc=/tmp/world.zip
elif [[ "$WORLD" =~ .*\.zip ]]; then
zipSrc="$WORLD"
fi
if [[ "$zipSrc" ]]; then
log "Unzipping world"
# Stage contents so that the correct subdirectory can be picked off
mkdir -p /tmp/world-data
(cd /tmp/world-data && unzip -o -q "$zipSrc")
baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;)
count=$(echo "$baseDirs" | wc -l)
if [[ $count -gt 1 ]]; then
baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
baseName=$(basename "$baseDir")
log "WARN multiple levels found, picking: $baseName"
elif [[ $count -gt 0 ]]; then
baseDir="$baseDirs"
else
log "ERROR invalid world content"
exit 1
fi
rsync --remove-source-files --recursive --delete "$baseDir/" "$worldDest"
else
log "Cloning world directory from $WORLD ..."
rsync --recursive --delete "${WORLD%/}"/ "$worldDest"
fi
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"
fi
fi
exec ${SCRIPTS:-/}start-finalSetupModpack $@

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
if [ -n "$OPS" ]; then
log "Setting/adding ops"
@@ -66,18 +66,6 @@ do
fi
done
case ${TYPE} in
SPIGOT|BUKKIT|PAPER)
mkdir -p /data/plugins
if [ -d /plugins ]; then
log "Copying plugins over..."
# Copy plugins over using rsync to allow deeply nested updates of plugins
# only updates files if the source file is newer and print updated files
rsync -a --out-format="update:%f:Last Modified %M" --prune-empty-dirs --update /plugins /data
fi
;;
esac
EXTRA_ARGS=""
# Optional disable console
if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then
@@ -182,12 +170,13 @@ if [[ ${TYPE} == "CURSE_INSTANCE" ]]; then
elif [[ ${TYPE} == "FEED-THE-BEAST" ]]; then
mcServerRunnerArgs="${mcServerRunnerArgs} --shell bash"
if [ ! -e "${FTB_DIR}/ops.json" -a -e /data/ops.txt ]; then
cp -f /data/ops.txt ${FTB_DIR}/
fi
# copy player modification files unconditionally since their
# processing into json is additive anyway
[ -f /data/ops.txt ] && cp -f /data/ops.txt ${FTB_DIR}/
[ -f /data/white-list.txt ] && cp -f /data/white-list.txt ${FTB_DIR}/
if [ ! -e "${FTB_DIR}/whitelist.json" -a -e /data/white-list.txt ]; then
cp -f /data/white-list.txt ${FTB_DIR}/
if [ ! -e "${FTB_DIR}/server-icon.png" -a -e /data/server-icon.png ]; then
cp -f /data/server-icon.png ${FTB_DIR}/
fi
cp -f /data/eula.txt "${FTB_DIR}/"

View File

@@ -1,5 +1,7 @@
#!/bin/bash
function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }
function isURL {
local value=$1
@@ -49,6 +51,14 @@ function log {
echo "[init] $*"
}
function logAutopause {
echo "[Autopause loop] $*"
}
function logAutopauseAction {
echo "[$(date -Iseconds)] [Autopause] $*"
}
function normalizeMemSize {
local scale=1
case ${1,,} in
@@ -75,10 +85,27 @@ function versionLessThan {
return 1
fi
if (( activeParts[0] < givenParts[0] )) || \
(( activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1] )); then
return 0
if (( ${#activeParts[@]} == 2 )); then
if (( activeParts[0] < givenParts[0] )) || \
(( activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1] )); then
return 0
else
return 1
fi
else
return 1
if (( activeParts[0] < givenParts[0] )) || \
(( activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1] )) || \
(( activeParts[0] == givenParts[0] && activeParts[1] == givenParts[1] && activeParts[2] < givenParts[2] )); then
return 0
else
return 1
fi
fi
}
}
requireVar() {
if [ ! -v $1 ]; then
log "ERROR: $1 is required to be set"
exit 1
fi
}

View File

@@ -1,6 +1,6 @@
#!/bin/bash
. /start-utils
. ${SCRIPTS:-/}start-utils
if ! [[ -v CURSE_INSTANCE_JSON ]]; then
log "ERROR: CURSE_INSTANCE_JSON needs to be set"
@@ -15,4 +15,4 @@ fi
log "Resolved CURSE_INSTANCE_JSON as ${CURSE_INSTANCE_JSON}"
# Continue to Final Setup
exec /start-finalSetup01World "$@"
exec ${SCRIPTS:-/}start-finalSetupWorld "$@"

View File

@@ -0,0 +1,17 @@
version: "3.8"
services:
sut:
depends_on:
- mc
image: itzg/mc-monitor:0.6.0
command: status --host mc --retry-interval 1s --retry-limit 120
mc:
restart: "no"
build:
context: ..
cache_from:
- itzg/minecraft-server:latest
environment:
EULA: "TRUE"

17
tests/test.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
cd $(dirname $0)
failed=false
args="-f docker-compose.test.yml"
docker-compose $args run sut || failed=true
echo "
Result: failed=$failed"
$failed && docker-compose $args logs mc
docker-compose $args down -v
if $failed; then
exit 1
fi