diff --git a/.github/workflows/build-multiarch.yml b/.github/workflows/build-multiarch.yml index 0d66ccb1..128f4199 100644 --- a/.github/workflows/build-multiarch.yml +++ b/.github/workflows/build-multiarch.yml @@ -2,16 +2,18 @@ name: Build and publish multiarch on: push: branches: + - master - multiarch - multiarch-latest - java15 - - java16 + - java16* - test/multiarch/* tags: + - "[0-9]+.[0-9]+.[0-9]+" - "[0-9]+.[0-9]+.[0-9]+-multiarch" - "[0-9]+.[0-9]+.[0-9]+-multiarch-latest" - "[0-9]+.[0-9]+.[0-9]+-java15" - - "[0-9]+.[0-9]+.[0-9]+-java16" + - "[0-9]+.[0-9]+.[0-9]+-java16*" paths-ignore: - "*.md" - "docs/**" @@ -20,29 +22,22 @@ on: jobs: docker-buildx: runs-on: ubuntu-20.04 + env: + CACHE_NAME: master steps: - name: Checkout uses: actions/checkout@v2.3.4 - - 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: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + images: | + itzg/minecraft-server + tags: | + type=ref,event=branch + type=ref,event=tag + type=edge,branch=master - name: Setup Docker Buildx uses: docker/setup-buildx-action@v1 @@ -51,9 +46,9 @@ jobs: uses: actions/cache@v2.1.5 with: path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ steps.prep.outputs.cache_version }}-${{ github.sha }} + key: ${{ runner.os }}-buildx-${{ env.CACHE_NAME }}-${{ github.sha }} restore-keys: | - ${{ runner.os }}-buildx-${{ steps.prep.outputs.cache_version }}- + ${{ runner.os }}-buildx-${{ env.CACHE_NAME }}- - name: Set up QEMU uses: docker/setup-qemu-action@v1.1.0 @@ -69,19 +64,14 @@ jobs: uses: docker/build-push-action@v2.4.0 with: context: . - file: ./Dockerfile platforms: linux/amd64,linux/arm/v7,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.prep.outputs.tags }} + tags: ${{ steps.meta.outputs.tags }} # 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 }} + labels: ${{ steps.meta.outputs.labels }} - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/.github/workflows/generate-toc.yml b/.github/workflows/generate-toc.yml index 4a31c0b1..104e8f3f 100644 --- a/.github/workflows/generate-toc.yml +++ b/.github/workflows/generate-toc.yml @@ -17,4 +17,4 @@ jobs: ./gh-md-toc --insert --no-backup README.md - uses: stefanzweifel/git-auto-commit-action@v4.11.0 with: - commit_message: Auto update markdown TOC \ No newline at end of file + commit_message: "docs: Auto update markdown TOC" \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6d74d3e5..d402dcdc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,14 +3,12 @@ name: Build and Publish on: push: branches: - - master - java8 - openj9 - openj9-11 - adopt11 - 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" diff --git a/BUILDING.md b/BUILDING.md new file mode 100644 index 00000000..7b26714c --- /dev/null +++ b/BUILDING.md @@ -0,0 +1,11 @@ +Ensure buildx/BuildKit support is enabled and run: + +```shell script +docker buildx build --platform=linux/arm64 --platform=linux/arm/v7 --platform=linux/amd64 --tag itzg/minecraft-server:multiarch --push . +``` + +To build for local testing, use: + +```shell script +docker buildx build --platform=linux/amd64 --tag mc-multiarch --load . +``` diff --git a/Dockerfile b/Dockerfile index 54ee51e4..8930091e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,28 +2,28 @@ FROM openjdk:8u212-jre-alpine LABEL org.opencontainers.image.authors="Geoff Bourne " -RUN apk add --no-cache -U \ - openssl \ - imagemagick \ - lsof \ - su-exec \ - shadow \ - bash \ - curl iputils wget \ - git \ - jq \ - mysql-client \ - tzdata \ - rsync \ - nano \ - sudo \ - knock \ - ttf-dejavu +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive \ + apt-get install -y \ + imagemagick \ + gosu \ + sudo \ + net-tools \ + curl wget \ + git \ + jq \ + dos2unix \ + mysql-client \ + tzdata \ + rsync \ + nano \ + unzip \ + knockd \ + ttf-dejavu \ + && apt-get clean -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 +RUN addgroup --gid 1000 minecraft \ + && adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft COPY files/sudoers* /etc/sudoers.d @@ -31,9 +31,9 @@ EXPOSE 25565 25575 # hook into docker BuildKit --platform support # see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope -ARG TARGETOS=linux -ARG TARGETARCH=amd64 -ARG TARGETVARIANT="" +ARG TARGETOS +ARG TARGETARCH +ARG TARGETVARIANT ARG EASY_ADD_VER=0.7.1 ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add @@ -69,7 +69,7 @@ WORKDIR /data STOPSIGNAL SIGTERM ENV UID=1000 GID=1000 \ - JVM_XX_OPTS="-XX:+UseG1GC" MEMORY="1G" \ + MEMORY="1G" \ TYPE=VANILLA VERSION=LATEST \ ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \ SERVER_PORT=25565 ONLINE_MODE=TRUE SERVER_NAME="Dedicated Server" \ @@ -84,5 +84,6 @@ 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 diff --git a/README.md b/README.md index 797590a5..e626021b 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ By default, the container will download the latest version of the "vanilla" [Min * [Enabling Autopause](#enabling-autopause) * [Running on RaspberryPi](#running-on-raspberrypi) - + @@ -274,12 +274,13 @@ To use a different version of Java, please use a docker tag to run your Minecraf | Tag name | Java version | Linux | JVM Type | Architecture | | -------------- | -------------|--------|----------|-------------------| -| latest | 11 | Alpine | Hotspot | amd64 | +| latest | 16 | Debian | Hotspot | amd64,arm64,armv7 | +| edge | 16 | Debian | Hotspot | amd64,arm64,armv7 | | 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 | | java16 | 16 | Debian | Hotspot | amd64,arm64,armv7 | +| java16-openj9 | 16 | Debian | OpenJ9 | amd64 | | adopt11 | 11 | Alpine | Hotspot | amd64 | | openj9 | 8 | Alpine | OpenJ9 | amd64 | | openj9-11 | 11 | Alpine | OpenJ9 | amd64 | diff --git a/docker-versions-create.sh b/docker-versions-create.sh index 54736a20..b006f6aa 100755 --- a/docker-versions-create.sh +++ b/docker-versions-create.sh @@ -8,8 +8,8 @@ branches_list=( 'openj9-11' 'adopt11' 'java15' - 'java15-openj9' 'java16' + 'java16-openj9' 'multiarch' 'multiarch-latest' ) diff --git a/docs/.gitkeep b/docs/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/files/autopause/autopause-fcns.sh b/files/autopause/autopause-fcns.sh index bf6cc7c4..69eb9d08 100644 --- a/files/autopause/autopause-fcns.sh +++ b/files/autopause/autopause-fcns.sh @@ -5,15 +5,15 @@ current_uptime() { } java_running() { - [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] + [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] } java_process_exists() { - [[ -n "$(ps -a -o comm | grep 'java')" ]] + [[ -n "$(ps -ax -o comm | grep 'java')" ]] } rcon_client_exists() { - [[ -n "$(ps -a -o comm | grep 'rcon-cli')" ]] + [[ -n "$(ps -ax -o comm | grep 'rcon-cli')" ]] } mc_server_listening() { diff --git a/files/autopause/knockd-config.cfg b/files/autopause/knockd-config.cfg index 86c98d02..68ab28de 100644 --- a/files/autopause/knockd-config.cfg +++ b/files/autopause/knockd-config.cfg @@ -3,10 +3,10 @@ [unpauseMCServer-server] sequence = 25565 seq_timeout = 1 - command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh + command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh tcpflags = syn [unpauseMCServer-rcon] sequence = 25575 seq_timeout = 1 - command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh + command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh tcpflags = syn diff --git a/files/autopause/pause.sh b/files/autopause/pause.sh index 9bcb4a06..bcd1a06c 100755 --- a/files/autopause/pause.sh +++ b/files/autopause/pause.sh @@ -2,7 +2,7 @@ . /start-utils -if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then +if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then # save world rcon-cli save-all >/dev/null diff --git a/files/autopause/resume.sh b/files/autopause/resume.sh index 5d1686f0..6ae5a8cf 100755 --- a/files/autopause/resume.sh +++ b/files/autopause/resume.sh @@ -2,7 +2,7 @@ . /start-utils -if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then +if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then logAutopauseAction "Knocked, resuming Java process" pkill -CONT java fi diff --git a/health.sh b/health.sh index e2ad7e72..a3f14aa6 100644 --- a/health.sh +++ b/health.sh @@ -5,7 +5,7 @@ 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 +elif isTrue "${ENABLE_AUTOPAUSE}" && [[ "$( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }')" =~ ^T.*$ ]]; then echo "Java process suspended by Autopause function" exit 0 else diff --git a/start b/start index e91b7da5..9e252956 100644 --- a/start +++ b/start @@ -40,7 +40,7 @@ if ! isTrue "${SKIP_SUDO:-false}" && [ $(id -u) = 0 ]; then echo 'hosts: files dns' > /etc/nsswitch.conf fi - exec su-exec ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration $@ + exec gosu ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration $@ else exec ${SCRIPTS:-/}start-configuration $@ fi diff --git a/start-configuration b/start-configuration index d24fa1d4..fabe1918 100644 --- a/start-configuration +++ b/start-configuration @@ -13,6 +13,8 @@ shopt -s nullglob #umask 002 export HOME=/data +log "Running as uid=$(id -u) gid=$(id -g) with /data as '$(ls -lnd /data)'" + if [ ! -e /data/eula.txt ]; then if ! isTrue "$EULA"; then log "" @@ -28,15 +30,6 @@ if [ ! -e /data/eula.txt ]; then fi -log "Running as uid=$(id -u) gid=$(id -g) with /data as '$(ls -lnd /data)'" - -if ! touch /data/.verify_access; then - log "ERROR: /data doesn't seem to be writable. Please make sure attached directory is writable by uid=$(id -u)" - exit 2 -fi - -rm /data/.verify_access || true - if [[ $PROXY ]]; then export http_proxy="$PROXY" export https_proxy="$PROXY" @@ -112,6 +105,10 @@ case "${TYPE^^}" in exec ${SCRIPTS:-/}start-deployFabric "$@" ;; + FTBA) + exec ${SCRIPTS:-/}start-deployFTBA "$@" + ;; + FTB|CURSEFORGE) exec ${SCRIPTS:-/}start-deployCF "$@" ;; diff --git a/start-deployFTBA b/start-deployFTBA new file mode 100644 index 00000000..38fae975 --- /dev/null +++ b/start-deployFTBA @@ -0,0 +1,75 @@ +#!/bin/bash + +ftbInstallMarker=".ftb-installed" + +. ${SCRIPTS:-/}start-utils +isDebugging && set -x +set -e + +if ! [[ -v FTB_MODPACK_ID ]]; then + log "ERROR FTB_MODPACK_ID is required with TYPE=FTB" + exit 1 +fi + +if ! [[ ${FTB_MODPACK_ID} =~ [0-9]+ ]]; then + log "ERROR FTB_MODPACK_ID needs to be numeric" + exit 1 +fi + +if ! [[ -v FTB_MODPACK_VERSION_ID ]]; then + if ! FTB_MODPACK_VERSION_ID=$(curl -fsSL https://api.modpacks.ch/public/modpack/${FTB_MODPACK_ID} | jq -r '.versions | sort_by(.updated)[-1].id'); then + log "ERROR unable to resolve latest modpack version ID for modpack ${FTB_MODPACK_ID}" + exit 1 + fi +elif ! [[ ${FTB_MODPACK_VERSION_ID} =~ [0-9]+ ]]; then + log "ERROR FTB_MODPACK_VERSION_ID needs to be numeric" + exit 1 +fi + +if ! [ -f "${ftbInstallMarker}" ] || [ $(cat "${ftbInstallMarker}") != "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" ]; then + ftbInstaller=/data/ftb-installer + if ! [[ -f "${ftbInstaller}" ]]; then + log "Downloading FTB installer" + curl -fsSL https://api.modpacks.ch/public/modpack/1/1/server/linux -o "${ftbInstaller}" + chmod +x "${ftbInstaller}" + fi + + rm -rf forge*jar mods config libraries defaultconfigs changelogs + + log "Installing modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}" + ${ftbInstaller} ${FTB_MODPACK_ID} ${FTB_MODPACK_VERSION_ID} --noscript --auto + rm -f forge*installer.jar + + 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 + +isDebugging && cat version.json +forgeVersion=$(jq -r '.targets|unique[] | select(.name == "forge") | .version' version.json) +mcVersion=$(jq -r '.targets|unique[] | select(.name == "minecraft") | .version' version.json) + +variants=( + forge-${mcVersion}-${forgeVersion}.jar + forge-${mcVersion}-${forgeVersion}-universal.jar + forge-${mcVersion}-${forgeVersion}-${mcVersion}-universal.jar +) +for f in ${variants[@]}; do + if [ -f $f ]; then + export SERVER=$f + break + fi +done +if ! [ -v SERVER ]; then + log "ERROR unable to locate the installed forge server jar" + ls *.jar + exit 2 +fi + +# Continue to Final Setup +exec ${SCRIPTS:-/}start-finalSetupWorld $@ diff --git a/start-minecraftFinalSetup b/start-minecraftFinalSetup index 75cfcf21..a6edf5c2 100644 --- a/start-minecraftFinalSetup +++ b/start-minecraftFinalSetup @@ -246,3 +246,4 @@ else exec mc-server-runner ${bootstrapArgs} ${mcServerRunnerArgs} java "${finalArgs[@]}" fi fi +