Full Code of itzg/docker-minecraft-server for AI

master fba656561f17 cached
370 files
618.2 KB
174.5k tokens
1 requests
Download .txt
Showing preview only (701K chars total). Download the full file or copy to clipboard to get everything.
Repository: itzg/docker-minecraft-server
Branch: master
Commit: fba656561f17
Files: 370
Total size: 618.2 KB

Directory structure:
gitextract_eezdj074/

├── .dockerignore
├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   ├── config.yml
│   │   └── enhancement.yml
│   ├── dependabot.yml
│   ├── release.yml
│   └── workflows/
│       ├── auto-release.yml
│       ├── build.yml
│       ├── discord.yml
│       ├── issue-label.yml
│       ├── stale-check.yml
│       └── verify-pr.yml
├── .gitignore
├── .readthedocs.yaml
├── Dockerfile
├── LICENSE
├── README.md
├── build/
│   ├── alpine/
│   │   ├── install-packages.sh
│   │   └── setup-user.sh
│   ├── ol/
│   │   ├── install-packages.sh
│   │   └── setup-user.sh
│   ├── run.sh
│   └── ubuntu/
│       ├── install-packages.sh
│       └── setup-user.sh
├── compose-dev.yml
├── compose-docs.yml
├── docker-compose.yml
├── docs/
│   ├── Dockerfile
│   ├── configuration/
│   │   ├── auto-rcon-commands.md
│   │   ├── interpolating.md
│   │   ├── jvm-options.md
│   │   ├── misc-options.md
│   │   └── server-properties.md
│   ├── css/
│   │   └── extra.css
│   ├── data-directory.md
│   ├── img/
│   │   ├── .gitignore
│   │   ├── Minecraft server containment.xml
│   │   └── docs-banner.txt
│   ├── index.md
│   ├── misc/
│   │   ├── autopause-autostop/
│   │   │   ├── autopause.md
│   │   │   └── autostop.md
│   │   ├── autoscale/
│   │   │   └── autoscale.md
│   │   ├── building.md
│   │   ├── contributing/
│   │   │   ├── development.md
│   │   │   └── docs.md
│   │   ├── deployment/
│   │   │   └── index.md
│   │   ├── examples.md
│   │   ├── healthcheck.md
│   │   ├── log4j.md
│   │   ├── raspberrypi.md
│   │   ├── related-projects.md
│   │   ├── troubleshooting.md
│   │   └── world-data.md
│   ├── mods-and-plugins/
│   │   ├── curseforge-files.md
│   │   ├── index.md
│   │   ├── modrinth.md
│   │   ├── packwiz.md
│   │   └── spiget.md
│   ├── requirements.txt
│   ├── sending-commands/
│   │   ├── commands.md
│   │   ├── ssh.md
│   │   └── websocket.md
│   ├── types-and-platforms/
│   │   ├── index.md
│   │   ├── mod-platforms/
│   │   │   ├── auto-curseforge.md
│   │   │   ├── curseforge.md
│   │   │   ├── ftb.md
│   │   │   ├── gtnh.md
│   │   │   └── modrinth-modpacks.md
│   │   └── server-types/
│   │       ├── bukkit-spigot.md
│   │       ├── fabric.md
│   │       ├── forge.md
│   │       ├── hybrids.md
│   │       ├── others.md
│   │       ├── paper.md
│   │       └── quilt.md
│   ├── variables.md
│   └── versions/
│       ├── java.md
│       └── minecraft.md
├── examples/
│   ├── .gitignore
│   ├── README.md
│   ├── apply-extra-configs/
│   │   ├── compose.yml
│   │   └── shared-configs/
│   │       └── LuckPerms/
│   │           └── config.yml
│   ├── auto-curseforge/
│   │   ├── aof7/
│   │   │   └── docker-compose.yml
│   │   ├── atm10/
│   │   │   └── docker-compose.yml
│   │   ├── atm8/
│   │   │   ├── docker-compose.yml
│   │   │   └── filebrowser.json
│   │   ├── atm9/
│   │   │   └── docker-compose.yml
│   │   ├── craftoria/
│   │   │   └── docker-compose.yml
│   │   ├── fabric-custom-loader/
│   │   │   └── docker-compose.yml
│   │   ├── ftb-evolution/
│   │   │   └── compose.yaml
│   │   ├── modpack-manifest/
│   │   │   ├── docker-compose.yml
│   │   │   └── manifests/
│   │   │       └── manifest.json
│   │   ├── one-block-modded/
│   │   │   ├── .gitignore
│   │   │   └── docker-compose.yml
│   │   ├── pixelmon/
│   │   │   └── docker-compose.yml
│   │   ├── prominence2/
│   │   │   └── docker-compose.yml
│   │   ├── rad2/
│   │   │   └── compose.yaml
│   │   ├── skyfactory4/
│   │   │   └── compose.yml
│   │   ├── skyfactory5/
│   │   │   └── compose.yml
│   │   ├── using-excludes/
│   │   │   └── docker-compose.yml
│   │   ├── valhesia5/
│   │   │   └── docker-compose.yml
│   │   └── vault-hunters-1-18-2/
│   │       └── docker-compose.yml
│   ├── autopause/
│   │   └── compose.yml
│   ├── autostop/
│   │   └── compose.yml
│   ├── bentobox/
│   │   └── compose.yml
│   ├── bettermc/
│   │   └── docker-compose.yml
│   ├── canyon/
│   │   └── compose.yml
│   ├── cleanroom/
│   │   └── compose.yml
│   ├── curseforge-files/
│   │   └── docker-compose.yml
│   ├── docker-compose-big.yml
│   ├── docker-compose-curseforge-atm7.yaml
│   ├── docker-compose-curseforge.yml
│   ├── docker-compose-forge-bettermcplus
│   ├── docker-compose-forge.yml
│   ├── docker-compose-magma.yml
│   ├── docker-compose-mods-mount.yml
│   ├── docker-compose-rconcmd.yml
│   ├── docker-compose-simple.yml
│   ├── docker-compose-spongeforge.yml
│   ├── docker-compose-world-download.yml
│   ├── docker-compose.yml
│   ├── fabric/
│   │   └── compose.yml
│   ├── fabric-cardboard/
│   │   └── compose.yml
│   ├── ftba/
│   │   ├── compose.yml
│   │   └── stoneblock4/
│   │       └── compose.yml
│   ├── generic-pack/
│   │   └── rlcraft/
│   │       └── compose.yml
│   ├── geyser/
│   │   └── docker-compose.yml
│   ├── gtnh/
│   │   ├── docker-compose-type-gtnh.yaml
│   │   └── docker-compose.yaml
│   ├── jline/
│   │   └── docker-compose.yml
│   ├── k8s/
│   │   ├── using-statefulset.yml
│   │   └── vanilla-deployment.yml
│   ├── ketting/
│   │   └── docker-compose.yml
│   ├── lazymc/
│   │   └── docker_compose.yml
│   ├── lazytainer/
│   │   └── docker_compose.yml
│   ├── mc-router-autoscale/
│   │   ├── compose-minimal.yml
│   │   └── compose.yml
│   ├── modrinth/
│   │   ├── bmc4/
│   │   │   └── compose.yml
│   │   ├── local-modpack/
│   │   │   └── docker-compose.yml
│   │   ├── modrinth-modpack/
│   │   │   └── compose.yml
│   │   ├── modrinth-paper/
│   │   │   └── compose.yml
│   │   ├── modrinth-projects/
│   │   │   └── compose.yml
│   │   └── version-from-modrinth-projects/
│   │       └── compose.yml
│   ├── mods-file/
│   │   ├── docker-compose.yml
│   │   └── mods.txt
│   ├── mohist/
│   │   └── compose.yml
│   ├── multi-project/
│   │   ├── README.md
│   │   ├── dbs/
│   │   │   └── docker-compose.yml
│   │   └── servers/
│   │       ├── docker-compose.yml
│   │       ├── mc-plugins/
│   │       │   └── LuckPerms/
│   │       │       └── config.yml
│   │       ├── velocity-config/
│   │       │   └── velocity.toml
│   │       └── waterfall-config/
│   │           ├── config.yml
│   │           └── waterfall.yml
│   ├── multiline-motd/
│   │   └── docker-compose.yml
│   ├── neoforge/
│   │   └── docker-compose.yml
│   ├── ngrok/
│   │   └── compose.yml
│   ├── optimized-server-config/
│   │   ├── README.md
│   │   └── docker-compose.yml
│   ├── packwiz/
│   │   └── compose.yml
│   ├── paper/
│   │   ├── compose.yml
│   │   ├── paper-build-plugins/
│   │   │   ├── Dockerfile
│   │   │   ├── docker-compose.yml
│   │   │   └── plugins/
│   │   │       ├── .gitignore
│   │   │       └── README.md
│   │   └── paper-proxy-protocol/
│   │       ├── config/
│   │       │   └── paper-global.yml
│   │       └── docker-compose.yml
│   ├── proxied/
│   │   └── compose.yml
│   ├── quilt/
│   │   └── docker-compose.yml
│   ├── rlcraft/
│   │   └── docker-compose.yml
│   ├── simple-voice-chat/
│   │   ├── fabric-compose.yaml
│   │   ├── neoforge-compose.yaml
│   │   └── paper-compose.yaml
│   ├── skript/
│   │   └── docker-compose.yml
│   ├── spiget/
│   │   └── docker-compose.yml
│   ├── spigot/
│   │   └── docker-compose.yml
│   ├── tailscale/
│   │   └── compose.yml
│   ├── valhelsia2/
│   │   └── docker-compose.yml
│   └── vanilla-tweaks/
│       ├── docker-compose.yml
│       ├── vanillatweaks-craftingtweaks.json
│       ├── vanillatweaks-datapacks.json
│       └── vanillatweaks-resourcepacks.json
├── files/
│   ├── cf-exclude-include.json
│   ├── knockd-config.cfg
│   ├── modrinth-exclude-include.json
│   ├── nanolimbo-settings-patch.json
│   ├── property-definitions.json
│   └── server.properties
├── images.json
├── kustomize/
│   ├── README.md
│   └── base/
│       ├── kustomization.yml
│       ├── service.yml
│       └── statefulset.yml
├── notes/
│   ├── .gitignore
│   ├── Minecraft server containment.xml
│   └── rbac-processing.mmd
├── renovate.json5
├── scripts/
│   ├── auto/
│   │   ├── autopause-daemon.sh
│   │   ├── autopause-fcns.sh
│   │   ├── autostop-daemon.sh
│   │   ├── pause.sh
│   │   ├── rcon-cmds-daemon.sh
│   │   ├── resume.sh
│   │   └── stop.sh
│   ├── shims/
│   │   ├── mc-health
│   │   ├── mc-send-to-console
│   │   └── mcstatus
│   ├── start
│   ├── start-autopause
│   ├── start-autostop
│   ├── start-configuration
│   ├── start-deployArcLight
│   ├── start-deployAutoCF
│   ├── start-deployBukkitSpigot
│   ├── start-deployCF
│   ├── start-deployCanyon
│   ├── start-deployCrucible
│   ├── start-deployCustom
│   ├── start-deployFTBA
│   ├── start-deployFabric
│   ├── start-deployFolia
│   ├── start-deployForge
│   ├── start-deployGTNH
│   ├── start-deployKetting
│   ├── start-deployLeaf
│   ├── start-deployLimbo
│   ├── start-deployMagma
│   ├── start-deployMagmaMaintained
│   ├── start-deployModrinth
│   ├── start-deployMohist
│   ├── start-deployNanoLimbo
│   ├── start-deployNeoForge
│   ├── start-deployPaper
│   ├── start-deployPoseidon
│   ├── start-deployPufferfish
│   ├── start-deployPurpur
│   ├── start-deployQuilt
│   ├── start-deploySpongeVanilla
│   ├── start-deployVanilla
│   ├── start-finalExec
│   ├── start-rconcmds
│   ├── start-setupDatapack
│   ├── start-setupEnvVariables
│   ├── start-setupModpack
│   ├── start-setupMounts
│   ├── start-setupRbac
│   ├── start-setupServerProperties
│   ├── start-setupWorld
│   ├── start-spiget
│   └── start-utils
├── tests/
│   ├── .gitignore
│   ├── fulltests/
│   │   ├── multi-part-motd/
│   │   │   └── docker-compose.yml
│   │   ├── test.sh
│   │   └── vanilla-latest/
│   │       └── docker-compose.yml
│   ├── setuponlytests/
│   │   ├── auto_curseforge/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── auto_curseforge_file/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── cf_files/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── listing.txt
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── conflicting_world_for_spigot_server/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── conflicting_world_for_vanilla_server/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── curseforge/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── defaults/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── generic-packs/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   └── verify.sh
│   │   ├── generic-packs-prefix/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── icon-file-exact/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── icon-file-scale/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   └── verify.sh
│   │   ├── icon-gif-multiframe/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── icon-png-atscale/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── icon-png-scale/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   └── verify.sh
│   │   ├── modrinth/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── mounts-custom/
│   │   │   ├── custom/
│   │   │   │   ├── config/
│   │   │   │   │   └── test.json
│   │   │   │   ├── mods/
│   │   │   │   │   └── mod.jar
│   │   │   │   └── plugins/
│   │   │   │       └── plugin.jar
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   └── verify.sh
│   │   ├── nanolimbo/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── ops_from_scratch/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── packwiz/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── require.sh
│   │   │   ├── verify.sh
│   │   │   └── web/
│   │   │       ├── index.toml
│   │   │       ├── mods/
│   │   │       │   └── architectury-api.pw.toml
│   │   │       └── pack.toml
│   │   ├── pufferfish/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── quilt/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── spiget/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── spigot_world_for_spigot_server/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── spigot_world_for_vanilla_server/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── spongevanilla_version_compare/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── test.sh
│   │   ├── vanilla_world_for_spigot_server/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── vanilla_world_for_vanilla_server/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── vanillatweaks_file/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   ├── verify.sh
│   │   │   ├── vt-craftingtweaks.json
│   │   │   ├── vt-datapacks.json
│   │   │   └── vt-resourcepacks.json
│   │   ├── vanillatweaks_sharecode/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── whitelist_from_scratch/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── world_from_tar/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── world_from_tarbz2/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   ├── verify.sh
│   │   │   └── worlds/
│   │   │       └── world-for-testing.tar.bz2
│   │   ├── world_from_targz/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── world_from_tarzst/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   ├── verify.sh
│   │   │   └── worlds/
│   │   │       └── world-for-testing.tar.zst
│   │   └── world_from_zip/
│   │       ├── docker-compose.yml
│   │       └── verify.sh
│   └── test.sh
└── zensical.toml

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
data
testdata
examples
k8s-examples
.idea
.git


================================================
FILE: .editorconfig
================================================
[start-*]
indent_size = 2
indent_style = space
end_of_line = lf


================================================
FILE: .github/FUNDING.yml
================================================
github: itzg
custom:
  - https://www.buymeacoffee.com/itzg
  - https://paypal.me/itzg


================================================
FILE: .github/ISSUE_TEMPLATE/bug.yml
================================================
name: Bug Report
description: File a bug report
labels:
  - bug
  - status/needs triage
body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to report a bug.
        
        Please double check some things first:
        1. Do you just have a question about something? If so, asking in the [Q&A Discussions](https://github.com/itzg/docker-minecraft-server/discussions/categories/q-a) or asking on [the Discord server](https://discord.gg/DXfKpjB) would be best.
        2. Did you **re-pull the newest image** and confirmed the issue after that? Run `docker pull <image>` or if using a compose file, it's as easy as running `docker compose pull`. If using Kubernetes, add `imagePullPolicy: Always` to the container. 
        4. Is this bug happening after the `[init]` prefixed logs and after the log that says "Starting the Minecraft server"? If so, please report the bug with Mojang or the respective server provider.
        5. Are you seeing a performance problem? If so, that is typically outside the scope of this image. Ask a question as above or contact the respective server provider.
  - type: textarea
    id: problem
    attributes:
      label: Describe the problem
    validations:
      required: true
  - type: textarea
    id: container
    attributes:
      label: Container definition
      description: Please provide the compose file or run command used to create the container
      value: |
        ```
        Paste run command or compose file here
        ```
  - type: textarea
    id: logs
    attributes:
      label: Container logs
      description: |
        Please provide container logs from the start of the container, which will be the ones prefixed with `[init]`. It is even better if you can set the variable `DEBUG` to "true" and provide those debug container logs.
      value: |
        ```
        Paste logs here
        ```


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
contact_links:
  - name: Ask a question in discussions
    url: https://github.com/itzg/docker-minecraft-server/discussions
    about: Please ask questions here
  - name: Ask a question on Discord
    url: https://discord.gg/DXfKpjB
    about: Please ask questions here

================================================
FILE: .github/ISSUE_TEMPLATE/enhancement.yml
================================================
name: Enhancement Request
description: Request an enhancement
labels:
  - enhancement
  - status/needs triage
body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to request an enhancement.
        
        Even if you plan on submitting a pull request with a contributed enhancement it is best to describe the enhancement here first. Somebody might already be working on a similar thing and could use your help.
  - type: dropdown
    id: type
    attributes:
      label: Enhancement Type
      options:
        - Improve an existing feature
        - A completely new feature
        - New server type
        - Not sure
    validations:
      required: true
  - type: textarea
    id: description
    attributes:
      label: Describe the enhancement
    validations:
      required: true

================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    groups:
      updates:
        patterns:
          - "*"
        update-types:
          - patch
          - minor
  - package-ecosystem: pip
    directory: "/docs"
    schedule:
      interval: weekly
    groups:
      patches:
        patterns:
          - "*"
        update-types:
          - patch
          - minor


================================================
FILE: .github/release.yml
================================================
changelog:
  exclude:
    authors:
      - dependabot
      - renovate
  categories:
    - title: Enhancements
      labels:
        - enhancement
    - title: Bug Fixes
      labels:
        - bug
    - title: Documentation
      labels:
        - documentation
    - title: Other Changes
      labels:
        - "*"


================================================
FILE: .github/workflows/auto-release.yml
================================================
name: Auto release
on:
  schedule:
    - cron: "0 14 * * *"
  workflow_dispatch:
jobs:
  auto-release:
    runs-on: ubuntu-latest
    steps:
      - uses: zenengeo/github-auto-release-action@main
        with:
          stable-duration: 3d
          force-duration: 14d
          token: '${{ secrets.GH_TOKEN }}'
  


================================================
FILE: .github/workflows/build.yml
================================================
name: Build and Publish
on:
  push:
    branches:
      - master
      - test/**
    tags:
      - "[0-9]+.[0-9]+.[0-9]+"
    paths-ignore:
      - "*.md"
      - "docs/**"
      - "examples/**"
      - "notes/**"
      - "kustomize/**"
      - "docker-compose.yml"
      - "images.json"
      - "compose-docs.yml"
      - "zensical.toml"
      - ".readthedocs.yaml"
      - "renovate.json5"

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        # NOTE: the "latest" variant is identified in the Docker meta step's 'latest' config
        variant:
          - java25
          - java25-alpine
          - java25-jdk
          - java21
          - java21-alpine
          - java21-jdk
          - java17
          - java16
          - java11
          - java8
          - java8-jdk
        include:
        # JAVA 25
          - variant: java25
            baseImage: eclipse-temurin:25-jre
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java25-alpine
            baseImage: eclipse-temurin:25-jre-alpine
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java25-jdk
            baseImage: eclipse-temurin:25
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
        # JAVA 21:
          - variant: java21
            baseImage: eclipse-temurin:21-jre
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java21-jdk
            baseImage: eclipse-temurin:21
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java21-alpine
            baseImage: eclipse-temurin:21-jre-alpine
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
        # JAVA 17:
          - variant: java17
            # jammy doesn't work until minecraft updates to https://github.com/netty/netty/issues/12343
            baseImage: eclipse-temurin:17-jre-focal
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.20.4
        # JAVA 16
          - variant: java16
            baseImage: adoptopenjdk:16-jre-hotspot
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.16.5
        # JAVA 11
          - variant: java11
            baseImage: adoptopenjdk:11-jre-hotspot
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.16.4
        # JAVA 8: NOTE: Unable to go past 8u312 because of Forge dependencies
          - variant: java8
            baseImage: eclipse-temurin:8u312-b07-jre-focal
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.12.2
            # Pin version for Java 8
            mcHelperVersion: 1.51.1
          - variant: java8-jdk
            baseImage: eclipse-temurin:8u312-b07-jdk-focal
            platforms: linux/amd64,linux/arm64
            mcVersion: 1.12.2
            # Pin version for Java 8
            mcHelperVersion: 1.51.1
    env:
      IMAGE_TO_TEST: "${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}"
      HAS_IMAGE_REPO_ACCESS: ${{ secrets.DOCKER_USER != '' && secrets.DOCKER_PASSWORD != '' }}
      MAIN_VARIANT: java25
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@v6.0.2
        with:
          # for build-files step
          fetch-depth: 0

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v5.10.0
        with:
          # NOTE for forks: if your Docker Hub organization doesn't match your Github repo's,
          # then the use of ${{ github.repository_owner }} will need to be replaced.
          images: |
            ${{ github.repository_owner }}/minecraft-server
            ghcr.io/${{ github.repository_owner }}/minecraft-server
          tags: |
            # Apply the variant as a moving tag for most recent commit per variant
            type=raw,value=${{ matrix.variant }},enable=${{ github.ref_name == github.event.repository.default_branch }}            
            # For the "main" variant, it gets the tag as-is
            type=pep440,pattern={{version}},enable=${{ matrix.variant == env.MAIN_VARIANT }}
            # ...and all variants (including main one) get the tag with the variant suffix, such as 2023.1.1-java17
            type=pep440,pattern={{version}},suffix=-${{ matrix.variant }}
            # latest tag gets a moving 'stable' image tag applied to the main variant
            type=pep440,pattern=stable,enable=${{ matrix.variant == env.MAIN_VARIANT }}
            # ...and qualified stable for all variants
            type=pep440,pattern=stable,suffix=-${{ matrix.variant }}
            # for building test/* branch images
            type=ref,event=branch,suffix=-${{ matrix.variant }},enable=${{ github.ref_name != github.event.repository.default_branch }}
            # for backward compatibility with users referencing java8-multiarch, this will set an extra label on java8
            type=raw,value=java8-multiarch,enable=${{ matrix.variant == 'java8' && github.ref_name == github.event.repository.default_branch }}
          # NOTE this identifies which variant will be published as "latest", which isn't
          # necessarily the newest version of Java
          flavor: |
            latest=${{ matrix.variant == env.MAIN_VARIANT && github.ref_name == github.event.repository.default_branch }}
          labels: |
            org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@v3.12.0

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3.7.0

      - name: Build for test
        uses: docker/build-push-action@v6.19.2
        with:
          platforms: linux/amd64
          tags: ${{ env.IMAGE_TO_TEST }}
          # ensure latest base image is used
          pull: true
          # load into daemon for test usage in next step
          load: true
          push: false
          build-args: |
            BASE_IMAGE=${{ matrix.baseImage }}
            ${{ matrix.mcHelperVersion && format('MC_HELPER_VERSION={0}', matrix.mcHelperVersion) }}
          cache-from: type=gha,scope=${{ matrix.variant }}
          # no cache-to to avoid cross-cache update from next build step

      - name: Run tests
        env:
          MINECRAFT_VERSION: ${{ matrix.mcVersion }}
          VARIANT: ${{ matrix.variant }}
          CF_API_KEY: ${{ secrets.CF_API_KEY }}
          GH_TOKEN: ${{ github.token }}
        run: |
          tests/test.sh

      - name: Login to DockerHub
        uses: docker/login-action@v3.7.0
        if: env.HAS_IMAGE_REPO_ACCESS
        with:
          username: ${{ secrets.DOCKER_USER }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Login to GHCR
        uses: docker/login-action@v3.7.0
        if: env.HAS_IMAGE_REPO_ACCESS
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ github.token }}

      - name: Build and push
        uses: docker/build-push-action@v6.19.2
        if: github.actor == github.repository_owner
        with:
          platforms: ${{ matrix.platforms }}
          push: >
            ${{ 
            github.ref_type == 'tag' 
            || github.ref_name == github.event.repository.default_branch
            || startsWith(github.ref_name, 'test/')
            || ( github.event_name == 'pull_request' 
                 && env.HAS_IMAGE_REPO_ACCESS 
                 && contains(github.event.pull_request.labels.*.name, 'ci/push-image') 
               )
            }}
          tags: ${{ steps.meta.outputs.tags }}
          # ensure latest base image is used
          pull: true
          labels: ${{ steps.meta.outputs.labels }}
          # Since some consumers, like Watchtower are broken https://github.com/containrrr/watchtower/discussions/1529
          # Also refer to https://github.com/docker/build-push-action/releases/tag/v3.3.0
          provenance: false
          build-args: |
            BASE_IMAGE=${{ matrix.baseImage }}
            BUILD_FILES_REV=${{ steps.build-files-rev.outputs.REV }}
            BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
            VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
            REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
            ${{ matrix.mcHelperVersion && format('MC_HELPER_VERSION={0}', matrix.mcHelperVersion) }}
          cache-from: type=gha,scope=${{ matrix.variant }}
          cache-to: type=gha,mode=max,scope=${{ matrix.variant }}


================================================
FILE: .github/workflows/discord.yml
================================================
name: Discord notifications

on:
  release:
    types:
      - published
  workflow_run:
    workflows: ["Build and Publish"]
    types:
      - completed

env:
  DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}

jobs:
  discord:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - name: on-publish
        if: github.event_name == 'release' && github.event.action == 'published'
        uses: SethCohen/github-releases-to-discord@v1.19.0
        with:
          webhook_url: ${{ secrets.DISCORD_WEBHOOK }}
      - name: on-success
        if: github.event.workflow_run.conclusion == 'success'
        uses: Ilshidur/action-discord@master
        with:
          args: |
            Github repo: ${{ github.repository }}
            - Branch: ${{ github.event.workflow_run.head_branch }}
            - [Link: to Actions](<${{ github.event.workflow_run.html_url }}>)
            - Status: 🎉  ${{ github.event.workflow_run.conclusion }}  🍏
      - name: on-failure
        if: github.event.workflow_run.conclusion == 'failure'
        uses: Ilshidur/action-discord@master
        with:
          args: |
            Github repo: ${{ github.repository }}
            - Branch: ${{ github.event.workflow_run.head_branch }}
            - [Link: to Actions](<${{ github.event.workflow_run.html_url }}>)
            - Status: 🤔  ${{ github.event.workflow_run.conclusion }}  💣💥


================================================
FILE: .github/workflows/issue-label.yml
================================================
name: Issues notify

on:
  issues:
    types:
      - opened
      - labeled
      - unlabeled
      - closed

jobs:
  notify:
    uses: itzg/github-workflows/.github/workflows/issues-notify-discord.yml@main
    with:
      triageLabel: 'status/needs triage'
    secrets:
      discordWebhook: "${{secrets.DISCORD_ISSUES_WEBHOOK}}"


================================================
FILE: .github/workflows/stale-check.yml
================================================
name: Stale Check

on:
  schedule:
    - cron: 0 2 * * *

jobs:
  check:
    runs-on: ubuntu-22.04
    permissions:
      issues: write
      pull-requests: write
    steps:
      - name: Process Stale Issues
        uses: actions/stale@v10
        with:
          stale-issue-label: status/stale
          stale-pr-label: status/stale
          stale-issue-message: >
            This issue is stale because it has been open 30 days with no activity. 
            Please add a comment describing the reason to keep this issue open.
          days-before-stale: 30
          days-before-close: 5
          exempt-issue-labels: 'enhancement,keep,status/needs triage,priority/high'



================================================
FILE: .github/workflows/verify-pr.yml
================================================
name: Verify PR
on:
  pull_request:
    branches:
      - master
    paths-ignore:
      - "*.md"
      - "docs/**"
      - "examples/**"
      - "notes/**"
      - "kustomize/**"
      - "docker-compose.yml"
      - "images.json"
      - "compose-docs.yml"
      - "zensical.toml"
      - ".readthedocs.yaml"
      - "renovate.json5"

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        variant:
          - java25
          - java25-alpine
          - java17
          - java8
        include:
        # JAVA 21/25:
          - variant: java25
            baseImage: eclipse-temurin:25-jre
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java25-alpine
            baseImage: eclipse-temurin:25-jre-alpine
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
        # JAVA 17:
          - variant: java17
            # jammy doesn't work until minecraft updates to https://github.com/netty/netty/issues/12343
            baseImage: eclipse-temurin:17-jre-focal
            platforms: linux/amd64
            mcVersion: 1.20.4
          - variant: java8
            baseImage: eclipse-temurin:8u312-b07-jre-focal
            platforms: linux/amd64
            mcVersion: 1.12.2
            # Pin version for Java 8
            mcHelperVersion: 1.51.1
    env:
      IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@v6.0.2
        with:
          # for build-files step
          fetch-depth: 0

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@v3.12.0

      - name: Confirm multi-arch build
        uses: docker/build-push-action@v6.19.2
        with:
          platforms: ${{ matrix.platforms }}
          # ensure latest base image is used
          pull: true
          build-args: |
            BASE_IMAGE=${{ matrix.baseImage }}
            ${{ matrix.mcHelperVersion && format('MC_HELPER_VERSION={0}', matrix.mcHelperVersion) }}
          cache-from: type=gha,scope=${{ matrix.variant }}

      - name: Build for test
        uses: docker/build-push-action@v6.19.2
        with:
          # Only build single platform since loading multi-arch image into daemon fails with
          # "docker exporter does not currently support exporting manifest lists"
          platforms: linux/amd64
          tags: ${{ env.IMAGE_TO_TEST }}
          # ensure latest base image is used
          pull: true
          # load into daemon for test usage in next step
          load: true
          push: false
          build-args: |
            BASE_IMAGE=${{ matrix.baseImage }}
            ${{ matrix.mcHelperVersion && format('MC_HELPER_VERSION={0}', matrix.mcHelperVersion) }}
          cache-from: type=gha,scope=${{ matrix.variant }}

      - name: Run tests
        env:
          MINECRAFT_VERSION: ${{ matrix.mcVersion }}
          VARIANT: ${{ matrix.variant }}
          CF_API_KEY: ${{ secrets.CF_API_KEY }}
          DEBUG: ${{ runner.debug }}
          GH_TOKEN: ${{ github.token }}
        run: |
          tests/test.sh


================================================
FILE: .gitignore
================================================
.vscode
/data/
/.idea/
*.iml
/gh-md-toc
personal-build-and-develop.*
site/


================================================
FILE: .readthedocs.yaml
================================================
version: 2

build:
  os: ubuntu-24.04
  tools:
    python: "3.14"
  jobs:
    # We recommend using a requirements file for reproducible builds.
    # This is just a quick example to get started.
    # https://docs.readthedocs.io/page/guides/reproducible-builds.html
    install:
      - pip install -r docs/requirements.txt
    build:
      html:
        - zensical build
    post_build:
      - mkdir -p $READTHEDOCS_OUTPUT/html/
      - cp --recursive site/* $READTHEDOCS_OUTPUT/html/


================================================
FILE: Dockerfile
================================================
ARG BASE_IMAGE=eclipse-temurin:25-jre
FROM ${BASE_IMAGE}

# hook into docker BuildKit --platform support
# see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT

# The following three arg/env vars get used by the platform specific "install-packages" script
ARG EXTRA_DEB_PACKAGES=""
ARG EXTRA_DNF_PACKAGES=""
ARG EXTRA_ALPINE_PACKAGES=""
ARG FORCE_INSTALL_PACKAGES=1
RUN --mount=target=/build,source=build \
    TARGET=${TARGETARCH}${TARGETVARIANT} \
    /build/run.sh install-packages
COPY --from=tianon/gosu /gosu /usr/local/bin/

RUN --mount=target=/build,source=build \
    /build/run.sh setup-user

EXPOSE 25565

ARG APPS_REV=1
ARG GITHUB_BASEURL=https://github.com

# renovate: datasource=github-releases packageName=itzg/easy-add
ARG EASY_ADD_VERSION=0.8.11
ADD ${GITHUB_BASEURL}/itzg/easy-add/releases/download/${EASY_ADD_VERSION}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
RUN chmod +x /usr/bin/easy-add

# renovate: datasource=github-releases packageName=itzg/restify
ARG RESTIFY_VERSION=1.7.12
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
  --var version=${RESTIFY_VERSION} --var app=restify --file {{.app}} \
  --from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz

# renovate: datasource=github-releases packageName=itzg/rcon-cli
ARG RCON_CLI_VERSION=1.7.4
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
  --var version=${RCON_CLI_VERSION} --var app=rcon-cli --file {{.app}} \
  --from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz

# renovate: datasource=github-releases packageName=itzg/mc-monitor
ARG MC_MONITOR_VERSION=0.16.1
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
  --var version=${MC_MONITOR_VERSION} --var app=mc-monitor --file {{.app}} \
  --from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz

# renovate: datasource=github-releases packageName=itzg/mc-server-runner
ARG MC_SERVER_RUNNER_VERSION=1.14.3
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
  --var version=${MC_SERVER_RUNNER_VERSION} --var app=mc-server-runner --file {{.app}} \
  --from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz

# renovate: datasource=github-releases packageName=itzg/mc-image-helper versioning=loose
ARG MC_HELPER_VERSION=1.55.2
ARG MC_HELPER_BASE_URL=${GITHUB_BASEURL}/itzg/mc-image-helper/releases/download/${MC_HELPER_VERSION}
# used for cache busting local copy of mc-image-helper
ARG MC_HELPER_REV=1
RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \
  | tar -C /usr/share -zxf - \
    && ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/ /usr/share/mc-image-helper \
    && ln -s /usr/share/mc-image-helper/bin/mc-image-helper /usr/bin

VOLUME ["/data"]
WORKDIR /data

STOPSIGNAL SIGTERM

# End user MUST set EULA and change RCON_PASSWORD
ENV TYPE=VANILLA VERSION=LATEST EULA="" UID=1000 GID=1000 LC_ALL=en_US.UTF-8

COPY --chmod=755 scripts/start* /image/scripts/

# Backward compatible shim for those with legacy entrypoint
COPY --chmod=755 <<EOF /start
#!/bin/bash
exec /image/scripts/start
EOF

COPY --chmod=755 scripts/auto/* /image/scripts/auto/
COPY --chmod=755 scripts/shims/* /image/scripts/shims/
RUN ln -s /image/scripts/shims/* /usr/local/bin/
COPY --chmod=755 files/* /image/

RUN curl -fsSL -o /image/Log4jPatcher.jar https://github.com/CreeperHost/Log4jPatcher/releases/download/v1.0.1/Log4jPatcher-1.0.1.jar

RUN dos2unix /image/scripts/start* /image/scripts/auto/*

ENTRYPOINT [ "/image/scripts/start" ]
HEALTHCHECK --start-period=2m --retries=2 --interval=30s CMD mc-health

ARG BUILDTIME=local
ARG VERSION=local
ARG REVISION=local
COPY <<EOF /etc/image.properties
buildtime=${BUILDTIME}
version=${VERSION}
revision=${REVISION}
EOF


================================================
FILE: LICENSE
================================================
Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

================================================
FILE: README.md
================================================
[![Docker Pulls](https://img.shields.io/docker/pulls/itzg/minecraft-server.svg?logo=docker)](https://hub.docker.com/r/itzg/minecraft-server/)
[![Docker Stars](https://img.shields.io/docker/stars/itzg/minecraft-server.svg?logo=docker)](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?label=Discord&logo=discord)](https://discord.gg/DXfKpjB)
[![Build and Publish](https://github.com/itzg/docker-minecraft-server/actions/workflows/build.yml/badge.svg)](https://github.com/itzg/docker-minecraft-server/actions/workflows/build.yml)
[![](https://img.shields.io/badge/Donate-Buy%20me%20a%20coffee-orange.svg)](https://www.buymeacoffee.com/itzg)
[![Documentation Status](https://readthedocs.org/projects/docker-minecraft-server/badge/?version=latest)](https://docker-minecraft-server.readthedocs.io/en/latest/?badge=latest)

 [![Read the docs](docs/img/docs-banner.png)](https://docker-minecraft-server.readthedocs.io/)

There you will find things like
- [Quick start with Docker Compose](https://docker-minecraft-server.readthedocs.io/en/latest/#using-docker-compose)
- Running [different versions of Minecraft](https://docker-minecraft-server.readthedocs.io/en/latest/versions/minecraft/) and using [various server types](https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/) for Java Edition
- [Setting server properties via container environment variables](https://docker-minecraft-server.readthedocs.io/en/latest/configuration/server-properties/)
- [Managing mods and plugins with automated downloads and cleanup](https://docker-minecraft-server.readthedocs.io/en/latest/mods-and-plugins/)
- [Using various modpack providers/platforms](https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/)
- ...and much more

There are also many examples located in [the examples directory](examples) of this repo.

This image only supports Java edition natively; however, if looking for a server that is compatible with Bedrock edition, then use [itzg/minecraft-bedrock-server](https://github.com/itzg/docker-minecraft-bedrock-server) or [refer to this section](https://docker-minecraft-server.readthedocs.io/en/latest/misc/examples/#bedrock-compatible-server) to add Bedrock compatibility to a Java edition server.


================================================
FILE: build/alpine/install-packages.sh
================================================
#!/bin/sh

set -e
set -o pipefail

# Install necessary packages
# shellcheck disable=SC2086
apk add --no-cache -U \
    openssl \
    imagemagick \
    file \
    lsof \
    coreutils \
    findutils \
    procps \
    shadow \
    bash \
    curl \
    iputils \
    git \
    jq \
    mysql-client \
    tzdata \
    rsync \
    nano \
    ncurses \
    sudo \
    tar \
    zstd \
    nfs-utils \
    libpcap \
    libwebp \
    libcap \
    numactl \
    ${EXTRA_ALPINE_PACKAGES}

# Download and install patched knockd
curl -fsSL -o /tmp/knock.tar.gz https://github.com/Metalcape/knock/releases/download/0.8.1/knock-0.8.1-alpine-amd64.tar.gz
tar -xf /tmp/knock.tar.gz -C /usr/local/ && rm /tmp/knock.tar.gz
ln -s /usr/local/sbin/knockd /usr/sbin/knockd
setcap cap_net_raw=ep /usr/local/sbin/knockd

# Set Git credentials globally
cat <<EOF >> /etc/gitconfig
[user]
	name = Minecraft Server on Docker
	email = server@example.com
EOF

================================================
FILE: build/alpine/setup-user.sh
================================================
#!/bin/sh

set -e

addgroup -g 1000 minecraft
adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft


================================================
FILE: build/ol/install-packages.sh
================================================
#!/bin/bash

export TARGET

set -euo pipefail

os_major_version=$(awk -F'[= ."]+' '/^VERSION_ID=/{ print $2 }' /etc/os-release)

# Install and configure dnf
microdnf install dnf -y
dnf install 'dnf-command(config-manager)' -y
dnf config-manager --set-enabled ol${os_major_version}_codeready_builder

# Add EPEL repository
tee /etc/yum.repos.d/ol${os_major_version}-epel.repo <<EOF
[ol${os_major_version}_developer_EPEL]
name=Oracle Linux \$releasever EPEL (\$basearch)
baseurl=https://yum.oracle.com/repo/OracleLinux/OL${os_major_version}$([ "$os_major_version" -ge 10 ] && echo '/0' || echo '')/developer/EPEL/\$basearch/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
gpgcheck=1
enabled=1
EOF

# Update system
dnf update -y

# Install necessary packages
# shellcheck disable=SC2086
# shellcheck disable=SC2046
dnf install -y \
  ImageMagick \
  file \
  sudo \
  net-tools \
  iputils \
  curl \
  git \
  jq \
  dos2unix \
  $([ "$os_major_version" -ge 10 ] && echo 'mysql8.4' || echo 'mysql') \
  procps-ng \
  tzdata \
  rsync \
  nano \
  unzip \
  zstd \
  $([ "$os_major_version" -ge 10 ] && echo 'bzip2' || echo 'lbzip2') \
  libpcap \
  libwebp \
  findutils \
  which \
  glibc-langpack-en \
  $([ "$os_major_version" -ge 10 ] && echo 'git-lfs' || echo '') \
  $([ "$os_major_version" -ge 10 ] && echo 'openssl' || echo '') \
  ${EXTRA_DNF_PACKAGES}

# Install Git LFS through third party repository for older OL releases
if [ "$os_major_version" -lt 10 ]; then
  curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.rpm.sh | sudo bash
  dnf update -y
  dnf install -y git-lfs
fi

# Clean up DNF when done
dnf clean all

cat <<EOF > /usr/local/sbin/knockd
#!/bin/sh

echo "Auto-pause (using knockd) is currently unavailable on graalvm image variants"
echo "Consider using a different image variant https://docker-minecraft-server.readthedocs.io/en/latest/versions/java/"
echo "or mc-router's auto scale up/down feature https://github.com/itzg/mc-router#docker-auto-scale-updown"
exit 2
EOF
chmod 755 /usr/local/sbin/knockd
# TODO restore retrieval from https://github.com/Metalcape/knock when tar's "Cannot open: Invalid argument" is solved

# Set git credentials globally
cat <<EOF >> /etc/gitconfig
[user]
	name = Minecraft Server on Docker
	email = server@example.com
EOF


================================================
FILE: build/ol/setup-user.sh
================================================
groupadd --gid 1000 minecraft
useradd --system --shell /bin/false --uid 1000 -g minecraft --home /data minecraft


================================================
FILE: build/run.sh
================================================
#!/bin/sh

set -e

distro=$(cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | sed -e 's/"//g')

"$(dirname "$0")/${distro}/$1".sh

================================================
FILE: build/ubuntu/install-packages.sh
================================================
#!/bin/bash

export TARGET

set -euo pipefail

# Update and install packages
apt-get update
# shellcheck disable=SC2086
DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
  imagemagick \
  file \
  sudo \
  net-tools \
  iputils-ping \
  curl \
  git \
  jq \
  dos2unix \
  mysql-client \
  tzdata \
  rsync \
  nano \
  unzip \
  zstd \
  lbzip2 \
  nfs-common \
  libpcap0.8 \
  libnuma1 \
  ${EXTRA_DEB_PACKAGES}

# Install Git LFS
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
apt-get update
apt-get install -y git-lfs

# Clean up APT when done
apt-get clean

# Download and install patched knockd
curl -fsSL -o /tmp/knock.tar.gz https://github.com/Metalcape/knock/releases/download/0.8.1/knock-0.8.1-$TARGET.tar.gz
tar -xf /tmp/knock.tar.gz -C /usr/local/ && rm /tmp/knock.tar.gz
ln -s /usr/local/sbin/knockd /usr/sbin/knockd
setcap cap_net_raw=ep /usr/local/sbin/knockd
find /usr/lib -name 'libpcap.so.0.8' -execdir cp '{}' libpcap.so.1 \;

# Set git credentials globally
cat <<EOF >> /etc/gitconfig
[user]
	name = Minecraft Server on Docker
	email = server@example.com
EOF


================================================
FILE: build/ubuntu/setup-user.sh
================================================
#!/bin/sh

set -e

if id ubuntu > /dev/null 2>&1; then
  deluser ubuntu
fi

addgroup --gid 1000 minecraft
adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft

================================================
FILE: compose-dev.yml
================================================
services:
  mc-dev:
    build:
      context: .
    environment:
      EULA: true
    volumes:
      - ./scripts:/image/scripts:ro
      - data:/data
    ports:
      - "25565:25565"
    stdin_open: true
    tty: true
volumes:
  data:

================================================
FILE: compose-docs.yml
================================================
# This composition can be used to serve up the rendered mkdocs for local authoring.
#
# docker compose -f compose-docs.yml -p zensical up
#
# and then access http://localhost:8000

services:
  zensical:
    build:
      context: .
      dockerfile: docs/Dockerfile
    volumes:
      - ./zensical.toml:/docs/zensical.toml
      - ./docs:/docs/docs
    ports:
      - "8000:8000"


================================================
FILE: docker-compose.yml
================================================
services:
  mc:
    image: itzg/minecraft-server
    environment:
      EULA: "true"
    ports:
      - "25565:25565"
    volumes:
      - data:/data
    stdin_open: true
    tty: true
    restart: unless-stopped
volumes:
  data: {}

================================================
FILE: docs/Dockerfile
================================================
FROM zensical/zensical

RUN --mount=target=/build/requirements.txt,source=docs/requirements.txt \
    pip install -r /build/requirements.txt


================================================
FILE: docs/configuration/auto-rcon-commands.md
================================================

# Auto-execute RCON commands

RCON commands can be configured to execute when the server starts, a client connects, or a client disconnects.

!!! note

    When declaring several commands within a compose file environment variable, it's easiest to use YAML's `|-` [block style indicator](https://yaml-multiline.info/).

**On Server Start:**

``` yaml
      RCON_CMDS_STARTUP:  |-
        gamerule doFireTick false
        pregen start 200
```

**On Client Connection:**

``` yaml
      RCON_CMDS_ON_CONNECT:  |-
        team join New @a[team=]
```

**Note:**
* On client connect we only know there was a connection, and not who connected. RCON commands will need to be used for that.

**On Client Disconnect:**

``` yaml
      RCON_CMDS_ON_DISCONNECT:  |-
        gamerule doFireTick true
```

**On First Client Connect**

``` yaml
      RCON_CMDS_FIRST_CONNECT: |-
        pregen stop
```

**On Last Client Disconnect**

``` yaml
      RCON_CMDS_LAST_DISCONNECT: |-
        kill @e[type=minecraft:boat]
        pregen start 200

```

**Example of rules for new players**

Uses team NEW and team OLD to track players on the server. So move player with no team to NEW, run a command, move them to team OLD.
[Reference Article](https://www.minecraftforum.net/forums/minecraft-java-edition/redstone-discussion-and/2213523-detect-players-first-join)

``` yaml
      RCON_CMDS_STARTUP:  |-
        /pregen start 200
        /gamerule doFireTick false
        /team add New
        /team add Old
      RCON_CMDS_ON_CONNECT: |-
        /team join New @a[team=]
        /give @a[team=New] birch_boat
        /team join Old @a[team=New]
      RCON_CMDS_FIRST_CONNECT: |-
        /pregen stop
      RCON_CMDS_LAST_DISCONNECT: |-
        /kill @e[type=minecraft:boat]
        /pregen start 200
```


================================================
FILE: docs/configuration/interpolating.md
================================================
---
title: Modifying config files
---

## Replacing variables inside configs

Sometimes you have mods or plugins that require configuration information that is only available at deploy-time. 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.

When the environment variable `REPLACE_ENV_IN_PLACE` is set to `true` (the default), the startup script will go through all files inside the container's `/data` path and replace variables that match the container's environment variables. Variables can instead (or in addition to) be replaced in files sync'ed from `/plugins`, `/mods`, and `/config` by setting `REPLACE_ENV_DURING_SYNC` to `true` (defaults to `false`).

Variables that you want to replace need to be declared inside curly brackets and prefixed with a dollar sign, such as  `${CFG_YOUR_VARIABLE}`, which is same as many scripting languages.

You can also change `REPLACE_ENV_VARIABLE_PREFIX`, which defaults to "CFG_", to limit which environment variables are allowed to be used. For example, with "CFG_" as the prefix, the variable `${CFG_DB_HOST}` would be substituted, but not `${DB_HOST}`. The prefix can be set to an empty string to allow for matching any variable name.

If you want to use a file's content for value, such as when using secrets mounted as files, declare the placeholder named like normal in the file and declare an environment variable named the same but with the suffix `_FILE`.

For example, a `my.cnf` file could contain:

```toml
[client]
password = ${CFG_DB_PASSWORD}
```

...a secret declared in the compose file with:
```yaml
secrets:
  db_password:
    external: true
```

...and finally the environment variable would be named with a `_FILE` suffix and point to the mounted secret:
```yaml
    environment:
      CFG_DB_PASSWORD_FILE: /run/secrets/db_password
```

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`.

```yaml
---
database:
  host: ${CFG_DB_HOST}
  name: ${CFG_DB_NAME}
  password: ${CFG_DB_PASSWORD}
```

This is how your `compose.yaml` file could look like:

```yaml title="compose.yaml"
# 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"

volumes:
  mc:
  rcon:

secrets:
  db_password:
    file: ./db_password
```

## Patching existing files

JSON path based patches can be applied to one or more existing files by setting the variable `PATCH_DEFINITIONS` to the path of a directory that contains one or more [patch definition json files](https://github.com/itzg/mc-image-helper#patchdefinition) or a [patch set json file](https://github.com/itzg/mc-image-helper#patchset). 

The `file` and `value` fields of the patch definitions may contain `${...}` variable placeholders. The allowed environment variables in placeholders can be restricted by setting `REPLACE_ENV_VARIABLE_PREFIX`, which defaults to "CFG_".

The following example shows a patch-set file where various fields in the `paper.yaml` configuration file can be modified and added:

```json
{
  "patches": [
    {
      "file": "/data/paper.yml",
      "ops": [
        {
          "$set": {
            "path": "$.verbose",
            "value": true
          }
        },
        {
          "$set": {
            "path": "$.settings['velocity-support'].enabled",
            "value": "${CFG_VELOCITY_ENABLED}",
            "value-type": "bool"
          }
        },
        {
          "$put": {
            "path": "$.settings",
            "key": "my-test-setting",
            "value": "testing"
          }
        }
      ]
    }
  ]
}
```

Supports the file formats:
- JSON
- JSON5
- Yaml
- TOML, but processed output is not pretty


================================================
FILE: docs/configuration/jvm-options.md
================================================
# JVM Options

## Memory Limit

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 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]`.

To have control over heap size, without relying on absolute memory sizes percentages are also supported using `<size>%`.

!!! info "RAMPercentage parameters"
    Percentage based heap sizing is enabled using `-XX:InitialRAMPercentage` for `INIT_MEMORY` and `-XX:MaxRAMPercentage` for `MAX_MEMORY`.
    For details on the function of these parameters look [here](https://www.baeldung.com/java-jvm-parameters-rampercentage).

!!! example "Using docker run"

    ```
        -e MEMORY=2G
    ```

    or to use init and max memory:

    ```
        -e INIT_MEMORY=1G -e MAX_MEMORY=4G
    ```

!!! example "Using compose file"

    ```
        environment:
          MEMORY: 2G
    ```

    or to use init and max memory:

    ```
        environment:
          INIT_MEMORY: 1G
          MAX_MEMORY: 4G
    ```

To let the JVM calculate the heap size from the container declared memory limit, unset `MEMORY` with an empty value, such as `-e MEMORY=""`. By default, the JVM will use 25% of the container memory limit as the heap limit.

!!! important
    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).

## Extra JVM Options

General JVM options can be passed to the Minecraft Server invocation by passing a `JVM_OPTS`
environment variable. If needing to set `-XX` options, then pass those with the `JVM_XX_OPTS` variable instead. Both variables accept space-delimited, raw JVM arguments.

```
docker run ... -e JVM_OPTS="-XsomeJVMOption -DpropName=value" ...
```

**NOTE** When declaring `JVM_OPTS` in a compose file's `environment` section with list syntax, **do not** include the quotes:

```yaml
    environment:
      - EULA=true
      - JVM_OPTS=-XsomeJVMOption -DpropName=value
```

Using object syntax is recommended and more intuitive:

```yaml
    environment:
      EULA: "true"
      JVM_OPTS: "-XsomeJVMOption -DpropName=value"
# or without quotes
#     JVM_OPTS: -XsomeJVMOption -DpropName=value
```

As a shorthand for passing several system properties as `-D` arguments, you can instead pass a comma separated list of `name=value` or `name:value` pairs with `JVM_DD_OPTS`. (The colon syntax is provided for management platforms like Plesk that don't allow `=` inside a value.)

For example, instead of passing

```yaml
  JVM_OPTS: -Dfml.queryResult=confirm -Dname=value
```

you can use

```yaml
  JVM_DD_OPTS: fml.queryResult=confirm,name=value
```

## Enable Remote JMX for Profiling

To enable remote JMX, such as for profiling with VisualVM or JMC, set the environment variable `ENABLE_JMX` to "true", set `JMX_HOST` to the IP/host running the Docker container, and add a port forwarding of TCP port 7091, such as:

!!! example

    With `docker run`

    ```
    -e ENABLE_JMX=true -e JMX_HOST=$HOSTNAME -p 7091:7091
    ```

If needing to map to a different port, then also set the environment variable `JMX_PORT` to the desired host port.

!!! example

    With a compose file:

    ```yaml
    environment:
      ENABLE_JMX: true
      JMX_HOST: ${HOSTNAME}
      JMX_PORT: "7092"
    ports:
      - "7092:7092"
    ```

## Enable Aikar's Flags

[Aikar has done some research](https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/) into finding the optimal JVM flags for GC tuning, which becomes more important as more users are connected concurrently. [PaperMC also has an explanation](https://docs.papermc.io/paper/aikars-flags) of what the JVM flags are doing.

The set of flags documented there can be added using

    -e USE_AIKAR_FLAGS=true

When `MEMORY` is greater than or equal to 12G, then the Aikar flags will be adjusted according to the article.

## Enable MeowIce's Flags

[MeowIce has created an updated set of JVM flags](https://github.com/MeowIce/meowice-flags?tab=readme-ov-file#why-would-i-have-to-switch-) based on Aikar's flags but with support for optimizations for Java 17 and above

The set of flags documented there can be added by setting the environment variable `USE_MEOWICE_FLAGS` to `true`. There is an optional `USE_MEOWICE_GRAALVM_FLAGS` variable to enable GraalVM specific optimizations, defaults to `FALSE`.


================================================
FILE: docs/configuration/misc-options.md
================================================
## 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
JAR via `CUSTOM_SERVER`. It can either be a URL or a container path to an existing JAR file.

If it is a URL, it will only be downloaded into the `/data` directory if it wasn't already. As
such, if you need to upgrade or re-download the JAR, then you will need to stop the container,
remove the file from the container's `/data` directory, and start again.

## Force re-download of the server file

For VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, CURSEFORGE, SPONGEVANILLA server types, set
`$FORCE_REDOWNLOAD` to some value (e.g. 'true) to force a re-download of the server file for
the particular server type. by adding a `-e FORCE_REDOWNLOAD=true` to your command-line.

For example, with Paper, it would look something like this:

```
docker run -d --pull=always \
    -v /path/on/host:/data \
    -e TYPE=PAPER -e FORCE_REDOWNLOAD=true \
    -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
```

## Running as alternate user/group ID

By default, the container will switch to and run the Minecraft server as user ID 1000 and group ID 1000; however, that can be changed by setting the environment variables `UID` and `GID`.

The startup will also skip user switching if the `--user`/`-u` argument is passed to `docker run` or `user` is set on the compose service.

## Extra Arguments

Arguments that would usually be passed to the jar file (those which are written after the filename) can be passed via the `EXTRA_ARGS` environment variable.

See [Custom worlds directory path](../misc/world-data.md#custom-worlds-directory-path) for an example.

## Interactive and Color Console

When RCON is enabled, which is the default, and [TTY](https://docs.docker.com/compose/compose-file/05-services/#tty) is enabled on the container, then some server types will output colorized logs and provide a fully interactive console. To access the interactive console, use [`docker attach`](https://docs.docker.com/engine/reference/commandline/container_attach/) (not `exec`). When finished, make sure to use the sequence Control-P, Control-Q to detach without stopping the container.

If this behavior interferes with the log content, then disable TTY or remove the setting entirely since the default is disabled. In a compose file, set the service's `tty` parameter to `false`. On the `docker run` command-line remove the `-t` argument.

## Server Shutdown Options

To allow time for players to finish what they're doing during a graceful server shutdown, set `STOP_SERVER_ANNOUNCE_DELAY` to a number of seconds to delay after an announcement is posted by the server.

!!! warning "Increase stop grace period"

    The Docker stop grace period must be increased to a value longer than the announce delay. The value to use that is longer than announce delay will vary based upon the amount of time it takes for final world data saving. If the container exits with exit code 137, then that indicates a longer grace period is needed. 
    
    The grace period can be increased using [the -t option on `docker compose down`](https://docs.docker.com/compose/reference/down/) or set the [stop_grace_period](https://docs.docker.com/compose/compose-file/05-services/#stop_grace_period) in the compose file.

The `STOP_SERVER_ANNOUNCE_DELAY` can be bypassed by sending a `SIGUSR1` signal to the `mc-server-runner` process.

`docker`:

        docker stop --signal SIGUSR1 mc

`docker compose`:

        docker compose kill --signal SIGUSR1

## Configuration Options for Minecraft Server Health Monitoring

The image tags include specific variables to simplify configuration for monitoring the health of a Minecraft server:

- `-e SERVER_HOST=localhost` : This variable sets the host address of the Minecraft server to be monitored. By default, it is set to `localhost`, but you can replace it with the actual hostname or IP address of your Minecraft server.

- `-e SERVER_PORT=25565` : This variable sets the port number on which the Minecraft server is running. By default, Minecraft servers run on port 25565, but if your server is configured to use a different port, you should replace `25565` with the correct port number. This helps the monitoring system to accurately check the health status of the Minecraft server on the specified port.

## OpenJ9 Specific Options

The openj9 image tags include specific variables to simplify configuration:

- `-e TUNE_VIRTUALIZED=TRUE` : enables the option to
  [optimize for virtualized environments](https://www.eclipse.org/openj9/docs/xtunevirtualized/)
- `-e TUNE_NURSERY_SIZES=TRUE` : configures nursery sizes where the initial size is 50%
  of the `MAX_MEMORY` and the max size is 80%.

## Customize Minecraft server logging

The image can use a templated log4j2 configuration based on PaperMC's logging setup, which is automatically applied for versions that don't require Log4j security patches. This configuration provides rolling logs and advanced logging features by default.

Set the environment variable `GENERATE_LOG4J2_CONFIG` to "true" to enable the following features.

!!! note

    This configures the server logging only. To diagnose container startup, set the `DEBUG` environment variable to "true".

### Customization via environment variables

You can customize various aspects of the logging behavior using environment variables:

- `LOG_LEVEL` : Root logger level (default: `info`)
  ```
  -e LOG_LEVEL=debug
  ```

- `ROLLING_LOG_FILE_PATTERN` : Pattern for rolled log file names (default: `logs/%d{yyyy-MM-dd}-%i.log.gz`)
  ```
  -e ROLLING_LOG_FILE_PATTERN="logs/archive/%d{yyyy-MM-dd}-%i.log.gz"
  ```

- `ROLLING_LOG_MAX_FILES` : Maximum number of archived log files to keep (default: `1000`)
  ```
  -e ROLLING_LOG_MAX_FILES=30
  ```

### Customizing log message formats

For full control over how log messages are formatted, you can customize the Log4j2 pattern layouts using these variables. These use [Log4j2 Pattern Layout syntax](https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout):

- `LOG_CONSOLE_FORMAT` : Format for console output (what you see in `docker logs`)
  Default: `[%d{HH:mm:ss}] [%t/%level]: %msg%n`

- `LOG_FILE_FORMAT` : Format for file logs (written to `logs/latest.log`)
  Default: `[%d{HH:mm:ss}] [%t/%level]: %msg%n`

- `LOG_TERMINAL_FORMAT` : Format for interactive terminal console (used with `docker attach`)
  Default: `[%d{HH:mm:ss} %level]: %msg%n`

### Example configurations

Simple timestamp customization (most common use case):
```yaml
environment:
  # What you see in docker logs
  LOG_CONSOLE_FORMAT: "[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%t/%level]: %msg%n"
  # What gets written to logs/latest.log
  LOG_FILE_FORMAT: "[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%t/%level]: %msg%n"
```

Advanced customization:
```yaml
environment:
  LOG_LEVEL: debug
  # Custom ISO8601 format with logger names
  LOG_CONSOLE_FORMAT: "%d{ISO8601} %-5level [%t] %logger{36} - %msg%n"
  LOG_FILE_FORMAT: "%d{ISO8601} %-5level [%t] %logger{36} - %msg%n"
  ROLLING_LOG_MAX_FILES: 50
```

### Legacy ENABLE_ROLLING_LOGS option

The `ENABLE_ROLLING_LOGS` environment variable is no longer needed for most use cases, as rolling logs are now enabled by default through the templated configuration. This option is maintained for backward compatibility but is only checked for error reporting when rolling logs cannot be used due to Log4j security patches.

> **NOTE** The templated log4j2 configuration may interfere with interactive/color consoles [as described in the section above](#interactive-and-color-console)

## 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 --pull=always -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 --pull=always -v /etc/timezone:/etc/timezone:ro -p 25565:25565 --name mc itzg/minecraft-server

## HTTP Proxy

You may configure the use of an HTTP/HTTPS proxy by passing the proxy's "host:port" via the environment variable `PROXY`. In [the example compose file](https://github.com/itzg/docker-minecraft-server/blob/master/examples/proxied/compose.yml) it references a Squid proxy. The host and port can be separately passed via the environment variables `PROXY_HOST` and `PROXY_PORT`. A `|` delimited list of hosts to exclude from proxying can be passed via `PROXY_NON_PROXY_HOSTS`.

## Using "noconsole" option

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

Some older servers get confused and think that the GUI interface is enabled. You can explicitly
disable that by passing `-e GUI=FALSE`.

## Stop Duration

When the container is signaled 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 default, it waits 60 seconds, but that duration can be configured by setting the environment variable `STOP_DURATION` to the number of seconds.

Be sure to also increase the shutdown timeout described [here for docker compose down](https://docs.docker.com/reference/cli/docker/compose/down/#options) and [here for docker stop](https://docs.docker.com/reference/cli/docker/container/stop/#options).

## Setup only

If you are using a host-attached data directory, then you can have the image setup the Minecraft server files and stop prior to launching the server process by setting `SETUP_ONLY` to `true`. 
    
## Enable Flare Flags
    
To enable the JVM flags required to fully support the [Flare profiling suite](https://blog.airplane.gg/flare), set the following variable:
    
    -e USE_FLARE_FLAGS=true
    
Flare is built-in to Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types.

## Enable support for optimized SIMD operations

To enable support for optimized SIMD operations, the JVM flag can be set with the following variable:

    -e USE_SIMD_FLAGS=true

SIMD optimized operations are supported by Pufferfish and Purpur.

For example, to download configuration files for plugins:

```yaml
environment:
  DOWNLOAD_EXTRA_CONFIGS: |
    plugins/WorldEdit<https://raw.githubusercontent.com/EngineHub/WorldEdit/refs/heads/version/7.3.x/worldedit-bukkit/src/main/resources/defaults/config.yml
    plugins/EssentialsX<https://raw.githubusercontent.com/EssentialsX/Essentials/refs/heads/2.x/Essentials/src/main/resources/config.yml
```

Or as a single line:

```yaml
environment:
  DOWNLOAD_EXTRA_CONFIGS: "plugins/WorldEdit<https://example.com/worldedit.yml,config<https://example.com/another.yml"
```

The files will be downloaded to `/data/` relative paths, so `plugins/WorldEdit` will be saved as `/data/plugins/WorldEdit/config.yml`.

!!! note 
    The downloaded files can be further processed using [environment variable replacement](interpolating.md) or [patch definitions](interpolating.md#patching-existing-files)

## Enable timestamps in init logs

Before the container starts the Minecraft Server its output is prefixed with `[init]`, such as

```
[init] Starting the Minecraft server...
```

To also include the timestamp with each log, set `LOG_TIMESTAMP` to "true". The log output will then look like:

```
[init] 2022-02-05 16:58:33+00:00 Starting the Minecraft server...
```


================================================
FILE: docs/configuration/server-properties.md
================================================
To unify management of the Minecraft server container, all known [`server.properties`](https://minecraft.wiki/w/Server.properties) entries can be managed by the environment variables described in the sections below. Some mappings provide additional functionality above and beyond the properties file and will be described in the sections below.

!!! warning "Version compatibility"

    Not all server properties are supported by all versions of Minecraft. Since this image supports a wide range of versions, please consult the [server properties documentation](https://minecraft.wiki/w/Server.properties) for the version you are using.

If you prefer to manually manage the `server.properties` file, set `OVERRIDE_SERVER_PROPERTIES` to "false". Similarly, you can entirely skip the startup script's creation of `server.properties` by setting `SKIP_SERVER_PROPERTIES` to "true".

!!! note
  
    To clear a server property, set the variable to an empty string, such as `-e RESOURCE_PACK=""`. An unset variable is ignored and the existing server property is left unchanged.

To see what `server.properties` will get used by the server, set the environment variable `DUMP_SERVER_PROPERTIES` to "true" and the contents of `server.properties` will get output before the server starts.

## Placeholders

When declaring a server properties via container environment variables, those values may contain placeholders that are processed when the `server.properties` file is updated. 

The syntax of placeholders is DOS-style, `%VAR%`, to avoid being processed by Docker or the shell and the following options are available:

`%VAR%` or `%env:VAR%`

: Replaced with the resolved value or the environment variable `VAR`

`%date:FMT%`

: Formats the current date/time with the given `FMT` string processed by [Java's DateTimeFormatter](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html).

Any declared or resolved environment variable may be referenced, such as `VERSION` and `TYPE`. Additionally, [Modrinth](../types-and-platforms/mod-platforms/modrinth-modpacks.md) and [Auto CurseForge](../types-and-platforms/mod-platforms/auto-curseforge.md) modpacks will expose the environment variables `MODPACK_NAME` and `MODPACK_VERSION`. The originally declared version, such as "LATEST" or "SNAPSHOT", is available in the variable `DECLARED_VERSION` 

!!! example

    As a compose file environment entry:

    ```yaml
        MOTD: Running %MODPACK_NAME% version %env:MODPACK_VERSION%
        LEVEL: world-%date:yyyy-MM-dd%
    ```

!!! warning

    Placeholders are not supported when manually managing `server.properties`

## Properties

### Message of the Day

The message of the day, shown below each server entry in the client UI, can be changed with the `MOTD` environment variable or a default is computed from the server type and version, such as

    A Paper Minecraft Server powered by Docker

That way you can easily differentiate between several server types you may have started.

The section symbol (§) and other unicode characters are automatically converted to allow [formatting codes](https://minecraft.wiki/w/Formatting_codes) to be used consistently with all server versions. For Minecraft versions less than 1.20, unicode characters in `server.properties` will be escaped as `\uXXXX`, by default. That behavior can be altered by setting `SERVER_PROPERTIES_ESCAPE_UNICODE` to "true" or "false".

!!! example

    With `docker run`
    
         -e MOTD="A §l§cMinecraft§r §nserver"
    
    or within a compose file
    
        environment:
          MOTD: "A §l§cMinecraft§r §nserver"

    renders
    
    ![](../img/motd-example.png)

To produce a multi-line MOTD, embed a newline character as `\n` in the string, such as the following example.

!!! example "Multi-line MOTD"

    With `docker run`
    
    ```
    -e MOTD="Line one\nLine two"
    ```
    
    or within a compose file
    
    ```yaml
          MOTD: |
            line one
            line two
    # or
    #      MOTD: "line one\nline two"
    ```

The following example combines a multi-line MOTD with [placeholders](#placeholders) from the latest version of the installed modpack:

!!! example

    ```yaml
    MOD_PLATFORM: AUTO_CURSEFORGE
    CF_SLUG: craftoria
    MOTD: |
      A %TYPE% server on %VERSION%
      running %MODPACK_NAME% %MODPACK_VERSION%
    ```
    
    ![](../img/motd-with-placeholders.png)

### Difficulty

The difficulty level (default: `easy`) can be set like:

```
docker run -d -e DIFFICULTY=hard ...
```

Valid values are: `peaceful`, `easy`, `normal`, and `hard`, and an
error message will be output in the logs if it's not one of these
values.

Refer to [the Minecraft wiki](https://minecraft.wiki/w/Difficulty)

### Whitelist Players

!!! warning "For public servers" 
    
    It is very important to consider setting a whitelist of expected players.

To whitelist players for your Minecraft server, you can:  

- Provide a list of usernames and/or UUIDs separated by commas or newlines via the `WHITELIST` environment variable
- Provide the URL or container path to a whitelist file via `WHITELIST_FILE` that will be retrieved/copied into the standard location

!!! example 

    In a compose file, a text block can be used to improve maintainability, such as

    ```yaml
          WHITELIST: |
            user1
            user2
            user3
    ```

When either is set, [whitelisting of connecting users](https://minecraft.wiki/w/Server.properties#white-list) is enabled.

To change the behavior when the whitelist file already exists, set the variable `EXISTING_WHITELIST_FILE` to one of the following options:

`SKIP`
: Skip processing of the whitelist file when one is already present. This is the same as setting the legacy variable `OVERRIDE_WHITELIST` to "false".

`SYNCHRONIZE`
: Synchronize the list of users in the file with the `WHITELIST` or `WHITELIST_FILE` provided. When using both, `WHITELIST` will take precedence. This is the same as setting the legacy variable `OVERRIDE_WHITELIST` to "true".

`MERGE`
: Merge the list of users from `WHITELIST` into the existing file. `WHITELIST_FILE` cannot be used with this option.

`SYNC_FILE_MERGE_LIST` (default)
: When `WHITELIST_FILE` is provided it will overwrite an existing whitelist file. Also, if `WHITELIST` is provided, then those users will be merged into the newly copied file.

!!! note 

    For versions prior to 1.7.3, `white-list.txt` will be maintained instead. Only usernames are supported for those versions.

To [enforce the whitelist changes immediately](https://minecraft.wiki/w/Server.properties#enforce-whitelist) when whitelist commands are used , set `ENFORCE_WHITELIST` to "true". If managing the whitelist file manually, `ENABLE_WHITELIST` can be set to "true" to set the `white-list` property.

!!! tip "Changing user API provider"

    The usernames provided for whitelist and ops processing are resolved using either [PlayerDB](https://playerdb.co/) or [Mojang's API](https://wiki.vg/Mojang_API#Username_to_UUID). The default uses PlayerDB, but can be changed by setting the environment variable `USER_API_PROVIDER` to "mojang". Sometimes one or the other service can become overloaded, which is why there is the ability to switch providers.


### Op/Administrator Players

Similar to the whitelist, users can be provisioned as operators (aka administrators) to your Minecraft server by

- Providing a list of usernames and/or UUIDs separated by commas or newlines via the `OPS` environment variable
- Providing the URL or container path to an ops file via `OPS_FILE` that will be retrieved/copied into the standard location

!!! example

    In a compose file, a text block can be used to improve maintainability, such as

    ```yaml
          OPS: |
            user1
            user2
            user3
    ```

To change the behavior when the ops file already exists, set the variable `EXISTING_OPS_FILE` to one of the following options:

`SKIP`
: Skip processing of the ops file when one is already present. This is the same as setting the legacy variable `OVERRIDE_OPS` to "false".

`SYNCHRONIZE`
: Synchronize the list of users in the file with the `OPS` or `OPS_FILE` provided. When using both, `OPS` will take precedence. The `level` and `bypassesPlayerLimit` will be retained from previous entries. This is the same as setting the legacy variable `OVERRIDE_OPS` to "true".

`MERGE`
: Merge the list of users from `OPS` into the existing file. `OPS_FILE` cannot be used with this option.

`SYNC_FILE_MERGE_LIST` (default)
: When `OPS_FILE` is provided it will overwrite an existing ops file. Also, if `OPS` is provided, then those users will be merged into the newly copied file.

!!! note

    For versions prior to 1.7.3, `ops.txt` will be maintained instead. Only usernames are supported for those versions.

### Enable/disable initial selection of datapacks

New to [22W42A](https://www.minecraft.net/en-us/article/minecraft-snapshot-22w42a), datapacks with feature flags can be controlled before initial world creation by setting these to a comma separated list of packs:

- `INITIAL_ENABLED_PACKS`
  such as "update_1_20,bundle"
- `INITIAL_DISABLED_PACKS`

### Server icon

A server icon can be configured by setting the `ICON` variable to a URL to download or a container path. The image will be automatically downloaded (if a URL), scaled, and converted from any other image format:

!!! example

    Using `docker run`:
    
    ```
    docker run -d -e ICON=http://..../some/image.png ...
    ```
    
    In compose file:
    
    ```yaml
    environment:
      ICON: http://..../some/image.png
    ```
    
    Using a file from host filesystem:
    
    ```yaml
    environment:
      ICON: /icon.png
      OVERRIDE_ICON: true
    volumes:
      ./icon.png:/icon.png
    ```

By default an existing `server-icon.png` file will not be replaced, that can be changed by setting `OVERRIDE_ICON` to "true".

### RCON

RCON is **enabled by default** to allow for graceful shut down of the server and coordination of save state during backups. RCON can be disabled by setting `ENABLE_RCON` to "false".

!!! warning

    Disabling RCON will remove and limit some features, such as interactive and color console support.

#### RCON Password

The default password is randomly generated on each startup. However, you can specify a password using one of the following environment variables:

* Set `RCON_PASSWORD` to your desired password.
* Set `RCON_PASSWORD_FILE` to the path of a file containing the password.

Using `RCON_PASSWORD_FILE` is the recommended method for managing sensitive data, as it allows full support for [Docker Secrets](https://docs.docker.com/compose/how-tos/use-secrets/).

??? example
    ```yaml title="compose.yaml"
    services:
      mc:
        image: itzg/minecraft-server:latest
        pull_policy: daily
        tty: true
        stdin_open: true
        ports:
          - "25565:25565"
        environment:
          EULA: "TRUE"
          RCON_PASSWORD_FILE: /run/secrets/rcon_pass # Points to the path where the secret is mounted
        volumes:
          # attach the relative directory 'data' to the container's /data path
          - ./data:/data
        secrets:
          - rcon_pass
    
    secrets:
      rcon_pass:
        file: ./rcon_password # local file containing the password
    ```
!!! warning
    **BE CAUTIOUS OF MAPPING THE RCON PORT EXTERNALLY** unless you are aware of all the consequences and have set a **secure password**.

!!! info 

    Mapping ports (`-p` command line or `ports` in compose) outside the container and docker networking needs to be a purposeful choice. Most production Docker deployments do not need any of the Minecraft ports mapped externally from the server itself.

By default, the server listens for RCON on port 25575 within the container. It can be changed with `RCON_PORT` but only do this if you have a very good reason. **DO NOT change `rcon.port` via `server.properties`** or integrations will break.

### Query

Set the environment variable `ENABLE_QUERY` to "true" to enable the gamespy query protocol. Maps to the server property [enable-query](https://minecraft.wiki/w/Server.properties#enable-query). By default, the query port will be `25565` (UDP) but can be changed with the `QUERY_PORT` environment variable.

### Level Seed

If you want to create the Minecraft level with a specific seed, set the environment variable `SEED`, which maps to the [level-seed](https://minecraft.wiki/w/Server.properties#level-seed) property.

If using a negative value for the seed, make sure to quote the value such as:

!!! example "Using docker run"

    ``` 
    -e SEED="-1785852800490497919"
    ```

!!! example "Using compose"

    ```yaml
    environment:
      SEED: "-1785852800490497919"
    ```

### Game Mode

By default, Minecraft servers are configured to run in Survival mode. You can
change the mode using `MODE` where you can either provide the [standard
numerical values](http://minecraft.wiki/Game_mode#Game_modes) or the
shortcut values:

- creative
- survival
- adventure
- spectator (only for Minecraft 1.8 or later)

For example:

    docker run -d -e MODE=creative ...

### 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 listed here](https://minecraft.wiki/w/Server.properties#level-type).

For some of the level types, `GENERATOR_SETTINGS` can be used to further customize the world generation.

To configure the `GENERATOR_SETTINGS` you need to add the appropriate `GeneratorOptions` JSON configuration. In the case of a superflat world, you may omit the `flat_world_options`.

The layers are applied from -64 and up and are added in the order of the list

Example for a superflat world:

- 1x bedrock
- 2x stone
- 15x sandstone
- Desert biome

```yaml
environment:
  LEVEL_TYPE: FLAT
  GENERATOR_SETTINGS: >-
      {
          "layers": [
              {
                  "block": "minecraft:bedrock",
                  "height": 1
              },
              {
                  "block": "minecraft:stone",
                  "height": 2
              },
              {
                  "block": "minecraft:sandstone",
                  "height": 15
              }
          ],
          "biome": "minecraft:desert"
      }
```
For more details, refer to the Minecraft Wiki sections for [Superflat Multiplayer](https://minecraft.wiki/w/Superflat#Multiplayer) and [generator options tag format](https://minecraft.wiki/w/Java_Edition_level_format#generatorOptions_tag_format).

### Custom Server Resource Pack

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 'RESOURCE_PACK=http://link.com/to/pack.zip?=1' -e 'RESOURCE_PACK_SHA1=d5db29cd03a2ed055086cef9c31c252b4587d6d0'

You can enforce the resource pack on clients by setting `RESOURCE_PACK_ENFORCE` to `TRUE` (default: `FALSE`).

### Level / World Save Name

You can either switch between world saves or run multiple containers with different saves by using the `LEVEL` option,
where the default is "world":

    docker run -d -e LEVEL=bonus ...

> **NOTE:** if running multiple containers be sure to either specify a different `-v` host directory for each
`LEVEL` in use or don't use `-v` and the container's filesystem will keep things encapsulated.

> **INFO** Refer to the [data directory](../data-directory.md) section for a visual description of where the `$LEVEL` directory is situated.

### Server port

> **WARNING:** only change this value if you know what you're doing. It only needs to be changed when using host-networking and it is rare that host networking should be used. Use `-p` port mappings instead.

If you must, the server port can be set like:

!!! example "Using docker run"

    ```
    docker run -d -e SERVER_PORT=25566 ...
    ```

!!! example "Using compose"

    ```yaml
    environment:
      SERVER_PORT: 25566
    ```

**however**, be sure to change your port mapping accordingly and be prepared for some features to break.

### Custom server properties

Some mods/plugins utilize custom `server.properties` entries which can be declared via the `CUSTOM_SERVER_PROPERTIES` environment variable. The contents must be newline delimited `name=value` pairs.

Within a compose file, newline delimited entries can be declared as shown here:

```yaml
      CUSTOM_SERVER_PROPERTIES: |
        custom1=value1
        defaultworldgenerator-port=f8c04631-f744-11ec-b260-f02f74b094e0
```

When using `docker run` from a bash shell, the entries must be quoted with the `$'` syntax, such as

```
-e CUSTOM_SERVER_PROPERTIES=$'k1=v1\nk2=v2'
```

### Other server property mappings

!!! warning "Version compatibility"

    Not all server properties are supported by all versions of Minecraft. Since this image supports a wide range of versions, please consult the [server properties documentation](https://minecraft.wiki/w/Server.properties) for the version you are using.

| Environment Variable                    | Server Property                                                                                                               |
|-----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|
| ACCEPTS_TRANSFERS                       | [accepts-transfers](https://minecraft.wiki/w/Server.properties#accepts-transfers)                                             |
| ALLOW_FLIGHT                            | [allow-flight](https://minecraft.wiki/w/Server.properties#allow-flight)                                                       |
| ALLOW_NETHER                            | [allow-nether](https://minecraft.wiki/w/Server.properties#allow-nether)                                                       |
| ANNOUNCE_PLAYER_ACHIEVEMENTS            | [announce-player-achievements](https://minecraft.wiki/w/Server.properties#announce-player-achievements)                       |
| BROADCAST_CONSOLE_TO_OPS                | [broadcast-console-to-ops](https://minecraft.wiki/w/Server.properties#broadcast-console-to-ops)                               |
| BROADCAST_RCON_TO_OPS                   | [broadcast-rcon-to-ops](https://minecraft.wiki/w/Server.properties#broadcast-rcon-to-ops)                                     |
| BUG_REPORT_LINK                         | [bug-report-link](https://minecraft.wiki/w/Server.properties#bug-report-link)                                                 |
| ENABLE_COMMAND_BLOCK                    | [enable-command-block](https://minecraft.wiki/w/Server.properties#enable-command-block)                                       |
| ENABLE_STATUS                           | [enable-status](https://minecraft.wiki/w/Server.properties#enable-status)                                                     |
| ENFORCE_SECURE_PROFILE                  | [enforce-secure-profile](https://minecraft.wiki/w/Server.properties#enforce-secure-profile)                                   |
| ENTITY_BROADCAST_RANGE_PERCENTAGE       | [entity-broadcast-range-percentage](https://minecraft.wiki/w/Server.properties#entity-broadcast-range-percentage)             |
| FORCE_GAMEMODE                          | [force-gamemode](https://minecraft.wiki/w/Server.properties#force-gamemode)                                                   |
| FUNCTION_PERMISSION_LEVEL               | [function-permission-level](https://minecraft.wiki/w/Server.properties#function-permission-level)                             |
| GENERATE_STRUCTURES                     | [generate-structures](https://minecraft.wiki/w/Server.properties#generate-structures)                                         |
| GENERATOR_SETTINGS                      | [generator-settings](https://minecraft.wiki/w/Server.properties#generator-settings)                                           |                                                                                                                    
| HARDCORE                                | [hardcore](https://minecraft.wiki/w/Server.properties#hardcore)                                                               |
| HIDE_ONLINE_PLAYERS                     | [hide-online-players](https://minecraft.wiki/w/Server.properties#hide-online-players)                                         |
| LOG_IPS                                 | [log-ips](https://minecraft.wiki/w/Server.properties#log-ips)                                                                 |
| MANAGEMENT_SERVER_ALLOWED_ORIGINS       | [management-server-allowed-origins](https://minecraft.wiki/w/Server.properties#management-server-allowed-origins)             |
| MANAGEMENT_SERVER_ENABLED               | [management-server-enabled](https://minecraft.wiki/w/Server.properties#management-server-enabled)                             |
| MANAGEMENT_SERVER_HOST                  | [management-server-host](https://minecraft.wiki/w/Server.properties#management-server-host)                                   |
| MANAGEMENT_SERVER_PORT                  | [management-server-port](https://minecraft.wiki/w/Server.properties#management-server-port)                                   |
| MANAGEMENT_SERVER_SECRET                | [management-server-secret](https://minecraft.wiki/w/Server.properties#management-server-secret)                               |
| MANAGEMENT_SERVER_TLS_ENABLED           | [management-server-tls-enabled](https://minecraft.wiki/w/Server.properties#management-server-tls-enabled)                     |
| MANAGEMENT_SERVER_TLS_KEYSTORE          | [management-server-tls-keystore](https://minecraft.wiki/w/Server.properties#management-server-tls-keystore)                   |
| MANAGEMENT_SERVER_TLS_KEYSTORE_PASSWORD | [management-server-tls-keystore-password](https://minecraft.wiki/w/Server.properties#management-server-tls-keystore-password) |
| MAX_BUILD_HEIGHT                        | [max-build-height](https://minecraft.wiki/w/Server.properties#max-build-height)                                               |
| MAX_COMMAND_CHAIN_LENGTH                | [max-command-chain-length](https://minecraft.wiki/w/Server.properties#max-command-chain-length)                               |
| MAX_ENTITY_CRAMMING                     | [max-entity-cramming](https://minecraft.wiki/w/Server.properties#max-entity-cramming)                                         |
| MAX_ENTITY_COLLISION_RADIUS             | [max-entity-collision-radius](https://minecraft.wiki/w/Server.properties#max-entity-collision-radius)                         |
| MAX_FUNCTION_CHAIN_DEPTH                | [max-function-chain-depth](https://minecraft.wiki/w/Server.properties#max-function-chain-depth)                               |
| MAX_NEIGHBORS                           | [max-neighbors](https://minecraft.wiki/w/Server.properties#max-neighbors)                                                     |
| MAX_CHAINED_NEIGHBOR_UPDATES            | [max-chained-neighbor-updates](https://minecraft.wiki/w/Server.properties#max-chained-neighbor-updates)                       |
| MAX_PLAYERS                             | [max-players](https://minecraft.wiki/w/Server.properties#max-players)                                                         |
| MAX_TICK_TIME                           | [max-tick-time](https://minecraft.wiki/w/Server.properties#max-tick-time)                                                     |
| MAX_WORLD_SIZE                          | [max-world-size](https://minecraft.wiki/w/Server.properties#max-world-size)                                                   |
| NETWORK_COMPRESSION_THRESHOLD           | [network-compression-threshold](https://minecraft.wiki/w/Server.properties#network-compression-threshold)                     |
| ONLINE_MODE                             | [online-mode](https://minecraft.wiki/w/Server.properties#online-mode)                                                         |
| OP_PERMISSION_LEVEL                     | [op-permission-level](https://minecraft.wiki/w/Server.properties#op-permission-level)                                         |
| PAUSE_WHEN_EMPTY_SECONDS                | [pause-when-empty-seconds](https://minecraft.wiki/w/Server.properties#pause-when-empty-seconds)                               |
| PLAYER_IDLE_TIMEOUT                     | [player-idle-timeout](https://minecraft.wiki/w/Server.properties#player-idle-timeout)                                         |
| PREVENT_PROXY_CONNECTIONS               | [prevent-proxy-connections](https://minecraft.wiki/w/Server.properties#prevent-proxy-connections)                             |
| PVP                                     | [pvp](https://minecraft.wiki/w/Server.properties#pvp)                                                                         |
| RATE_LIMIT                              | [rate-limit](https://minecraft.wiki/w/Server.properties#rate-limit)                                                           |
| REGION_FILE_COMPRESSION                 | [region-file-compression](https://minecraft.wiki/w/Server.properties#region-file-compression)                                 |
| RESOURCE_PACK_ID                        | [resource-pack-id](https://minecraft.wiki/w/Server.properties#resource-pack-id)                                               |
| RESOURCE_PACK_PROMPT                    | [resource-pack-prompt](https://minecraft.wiki/w/Server.properties#resource-pack-prompt)                                       |
| SERVER_NAME                             | [server-name](https://minecraft.wiki/w/Server.properties#server-name)                                                         |
| SIMULATION_DISTANCE                     | [simulation-distance](https://minecraft.wiki/w/Server.properties#simulation-distance)                                         |
| SNOOPER_ENABLED                         | [snooper-enabled](https://minecraft.wiki/w/Server.properties#snooper-enabled)                                                 |
| SPAWN_ANIMALS                           | [spawn-animals](https://minecraft.wiki/w/Server.properties#spawn-animals)                                                     |
| SPAWN_MONSTERS                          | [spawn-monsters](https://minecraft.wiki/w/Server.properties#spawn-monsters)                                                   |
| SPAWN_NPCS                              | [spawn-npcs](https://minecraft.wiki/w/Server.properties#spawn-npcs)                                                           |
| SPAWN_PROTECTION                        | [spawn-protection](https://minecraft.wiki/w/Server.properties#spawn-protection)                                               |
| STATUS_HEARTBEAT_INTERVAL               | [status-heartbeat-interval](https://minecraft.wiki/w/Server.properties#status-heartbeat-interval)                             |
| SYNC_CHUNK_WRITES                       | [sync-chunk-writes](https://minecraft.wiki/w/Server.properties#sync-chunk-writes)                                             |
| USE_NATIVE_TRANSPORT                    | [use-native-transport](https://minecraft.wiki/w/Server.properties#use-native-transport)                                       |
| VIEW_DISTANCE                           | [view-distance](https://minecraft.wiki/w/Server.properties#view-distance)                                                     |


================================================
FILE: docs/css/extra.css
================================================


================================================
FILE: docs/data-directory.md
================================================
Everything the container manages is located under the **container's** `/data` path, as shown here:

![](img/level-vs-world.drawio.png)

!!! 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. 

### Attaching data directory to host filesystem

In most cases the easiest way to persist and work with the minecraft data files is to use [bind mounts](https://docs.docker.com/storage/bind-mounts/) with the `-v` argument to map a directory on your host machine to the container's `/data` directory. In the following example, the path `/home/user/minecraft-data` **must be** a directory on your host machine:

    -v /home/user/minecraft-data:/data
       ------------------------- -----
        |                         |
        |                         +-- must always be /data
        |
        +-- replace with a directory on your host machine

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.

!!! important "Rootless, Podman, SELinux, AppArmor usage"
    When running rootless containers, such as with Podman, or using SELinux / AppArmor on your system, append ":Z" to the volume mapping. For example:

    ```
    /home/user/minecraft-data:/data:Z
    ```

    There might be a safer/better way to accommodate these systems. Please post an issue or PR if you have more information.
    
With Docker Compose, setting up a host attached directory is even easier since relative paths can be configured. For example, with the following `compose.yaml` Docker will automatically create/attach the relative directory `minecraft-data` to the container.

```yaml title="compose.yaml"

services:
  mc:
    image: itzg/minecraft-server:latest
    pull_policy: daily
    ports:
      - 25565:25565
    environment:
      EULA: "TRUE"
    tty: true
    stdin_open: true
    restart: unless-stopped
    volumes:
      # attach a directory relative to the directory containing this compose file
      - ./minecraft-data:/data
```

### Converting anonymous `/data` volume to named volume

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.

!!! note 

    In this example, it is assumed the original container was given a `--name` of "mc", so change the container identifier accordingly.
    
    You can also locate the Docker-managed directory from the `Source` field obtained from `docker inspect <container id or name> -f "{{json .Mounts}}"`

First, stop the existing container:

``` shell
docker stop mc
```

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
```

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
```

### Locating filesystem path of anonymous volume

The `Source` field from the output of this command will show where the anonymous volume is mounted from:

``` shell
docker inspect -f "{{json .Mounts}}" CONTAINER_NAME_OR_ID
```

!!! note

    On Windows with WSL the volumes path is `\\wsl$\docker-desktop-data\data\docker\volumes`


================================================
FILE: docs/img/.gitignore
================================================
/.*.bkp

================================================
FILE: docs/img/Minecraft server containment.xml
================================================
<mxfile userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36" version="6.4.4" editor="www.draw.io" type="github"><diagram name="Page-1">1VVNc5swEP01HDMDUiDOMbGd5pK2Ux96VkGAxgJRIRvcX9+VWD40ODOZ1j0Uz9jS2w+t3ts1Ad1W/SfNmvJNZVwGJMz6gO4CQjZRCN8WuAxA8vgwAIUW2QBFM3AQvziCGFecRMZbz9EoJY1ofDBVdc1T42FMa9X5brmS/qkNK/gKOKRMrtHvIjMlolEYzoZXLooSj97EaPjB0mOh1anG8wJCc/cM5oqNudC/LVmmugVE9wHdaqXMsKr6LZeW2pG2Ie7lHetUt+a1+UgAGQLOTJ74WHEiIfQ5E2dbn7kgJ8nPky3q2fDe3DEpijqgT+AheW5mK6wK/HVZ2obVI7ZT6ZFrCHlVrRkdoLSlzwJ2BYwo8WohXSkMPzQstfsOWhCcSlNJ2EX21JFVu8mFlFsllXahdJ/YD+Bnro0AyZ+Gu+yMslnwZjt3LVd/KurCpgptLlWbA5aBXNs0vH+X/mgSFWaFq4obfQEXDKDYBhd/2809RzeIlYt2mxwZ9nkxZZ61hgXKfV16upK+EjBMmuXmruX67KSCATMMYL2SwDU5z5DkvxAE52NNvdHqyBeOoXs8UWIbplP8A3ES3UCVja/K41oVEl5RJYpuoMr9SpU34B+Qr0rD0ITD0JE4TuI/nopwLcKLexYi6OFet6CT3Pt8TjwtCI3IFUJv0eXxis9v2y+fr/D58P/yGf87PmE7v4ycbfHCp/vf</diagram></mxfile>

================================================
FILE: docs/img/docs-banner.txt
================================================
Generated at https://textcraft.net/

Line 1:
"Click here for"
Small, none, Minecraftia

Line 2:
"Documentation"
Large, non, Minecrafter

Overall settings:
- drop shadow

================================================
FILE: docs/index.md
================================================
# Intro

[![Docker Pulls](https://img.shields.io/docker/pulls/itzg/minecraft-server.svg)](https://hub.docker.com/r/itzg/minecraft-server/)
[![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?label=Discord&logo=discord)](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.

To simply use the latest stable version, run

    docker run -d -it -p 25565:25565 -e EULA=TRUE itzg/minecraft-server

where, in this case, the standard server port 25565 will be exposed on your host machine.

!!! important "Persistent Data"

    The Minecraft server will store its data in the container's `/data` directory. This directory can be [mounted](https://docs.docker.com/storage/volumes/) from the host machine or a managed volume.

    Using `docker run` add a `-v` option somewhere before the image name:
    
    ```
    ... -v /path/on/host:/data itzg/minecraft-server
    ```
    
    Using docker compose, add a `volumes` section to the service definition:
    
    ```yaml
    services:
      mc:
        # ... image and environment section
        volumes:
          # attach the relative directory 'data' to the container's /data path
          - ./data:data
    ```

!!! note

    If you plan on running a server for a longer amount of time it is highly recommended using a management layer such as [Docker Compose](#using-docker-compose) or [Kubernetes](misc/deployment/index.md#on-kubernetes) to allow for incremental reconfiguration and image upgrades.

!!! info 

    Be sure to always include `-e EULA=TRUE` in your commands and container definitions, as Mojang/Microsoft requires EULA acceptance.

By default, the container will download the latest version of the "vanilla" [Minecraft: Java Edition server](https://www.minecraft.net/en-us/download/server) provided by Mojang. The [`VERSION`](versions/minecraft.md) and the [`TYPE`](types-and-platforms/index.md) can be configured to create many variations of desired Minecraft server. 

## Using [Docker Compose](https://docs.docker.com/compose/)

1. Create a new directory
2. Put the contents of the file below in a file called `compose.yaml`
3. Run `docker compose up -d` in that directory
4. Done! Point your client at your host's name/IP address and port 25565.

```yaml title="compose.yaml"

services:
  mc:
    image: itzg/minecraft-server:latest
    pull_policy: daily
    tty: true
    stdin_open: true
    ports:
      - "25565:25565"
    environment:
      EULA: "TRUE"
    volumes:
      # attach the relative directory 'data' to the container's /data path
      - ./data:/data
```

To apply changes made to the compose file, just run `docker compose up -d` again.

Follow the logs of the container using `docker compose logs -f`, check on the status with `docker compose ps`, and stop the container using `docker compose stop`.

!!! note "Configurator Tool"
    If you prefer to use an interactive tool to create or edit a Docker Compose file for this image, you can check out [setupmc.com's configurator](https://setupmc.com/java-server/). It provides a form that supports most of the image variables and generates the `compose.yaml` file in real time.

!!! note "More Compose Examples"
    There are more [examples located in the Github repo](https://github.com/itzg/docker-minecraft-server/tree/master/examples).

!!! note "Deployment Examples"
    The [deployments page](misc/deployment/index.md) provides more examples of deployment with and beyond Docker Compose.



================================================
FILE: docs/misc/autopause-autostop/autopause.md
================================================
# Auto-Pause

!!! important

    As of [1.21.2](https://minecraft.wiki/w/Java_Edition_1.21.2) it is not recommend to use this feature since Minecraft server natively auto-pauses when the server is empty. That is configured via the enivironment variable `PAUSE_WHEN_EMPTY_SECONDS`, which maps to the `pause-when-empty-seconds` server property. 

An auto-pause functionality is provided that monitors whether clients are connected to the server. If a client is not connected for a specified time, the Java process is put into a pause state. When a client attempts to connect while the process is paused, then process will be restored to a running state. The experience for the client does not change. This feature can be enabled by setting the environment variable `ENABLE_AUTOPAUSE` to "true".

!!! important

**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 [server properties](../../configuration/server-properties.md).

    Non-vanilla versions might have their own configuration file, you might have to disable their watchdogs separately. For PaperMC servers, you need to send the JVM flag `-Ddisable.watchdog=true`, this can be done with the docker env variable `-e JVM_DD_OPTS=disable.watchdog:true`

    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 file called `.paused` is created in `/data` directory when the server is paused and removed when the server is resumed. Other services may check for this file's existence before waking the server.

A `.skip-pause` file can be created in the `/data` directory to make the server skip autopausing, for as long as the file is present. The autopause timer will also be reset.

A starting, example compose file has been provided in [the examples](https://github.com/itzg/docker-minecraft-server/blob/master/examples/autopause/compose.yml).

!!! note 

    When configuring kubernetes readiness/liveness health checks with auto-pause enabled, be sure to reference the `mc-health` wrapper script rather than `mc-status` directly.

## Additional configuration

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.
- `AUTOPAUSE_STATUS_RETRY_LIMIT`, default 10
- `AUTOPAUSE_STATUS_RETRY_INTERVAL`, default 2s

!!! tip

    To troubleshoot, add `DEBUG_AUTOPAUSE=true` to see additional output

## Rootless Auto-Pause

If you're running the container as rootless, then it is necessary to add the `CAP_NET_RAW` capability to the container, such as using [the `cap_add` service field](https://docs.docker.com/compose/compose-file/05-services/#cap_add) in a compose file or [`--cap-add` docker run argument](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities). It may also be necessary to set the environment variable `SKIP_SUDO` to "true". 

You might need to set change the default port forwarder from RootlessKit to slirp4netns.

For Docker, see the following for setup:

- https://docs.docker.com/engine/security/rootless/#networking-errors
- https://rootlesscontaine.rs/getting-started/docker/#changing-the-port-forwarder

For Podman, see the following for setup:
- https://rootlesscontaine.rs/getting-started/podman/#changing-the-port-forwarder


!!! example "Using docker run"

    -e AUTOPAUSE_KNOCK_INTERFACE=tap0 --cap-add=CAP_NET_RAW --network slirp4netns:port_handler=slirp4netns



================================================
FILE: docs/misc/autopause-autostop/autostop.md
================================================
# Auto-Stop

An option to stop the server after a specified time has been added for niche applications (e.g. billing saving on AWS Fargate). The function is incompatible with the Autopause functionality, as they basically cancel out each other.

!!! note

    the docker container variables have to be set accordingly (restart policy set to "no") and that the container has to be manually restarted.

A `.skip-stop` file can be created in the `/data` directory to make the server skip autostopping, for as long as the file is present. The autostop timer will also be reset.

A starting, example compose file has been provided in [examples/docker-compose-autostop.yml](https://github.com/itzg/docker-minecraft-server/blob/master/examples/docker-compose-autostop.yml).

Enable the Autostop functionality by setting:

```
-e ENABLE_AUTOSTOP=TRUE
```

The following environment variables define the behavior of auto-stopping:
- `AUTOSTOP_TIMEOUT_EST`, default `3600` (seconds)
  describes the time between the last client disconnect and the stopping of the server (read as timeout established)
- `AUTOSTOP_TIMEOUT_INIT`, default `1800` (seconds)
  describes the time between server start and the stopping of the server, when no client connects in-between (read as timeout initialized)
- `AUTOSTOP_PERIOD`, default `10` (seconds)
  describes period of the daemonized state machine, that handles the stopping of the server
- `AUTOPAUSE_STATUS_RETRY_LIMIT`, default 10
- `AUTOPAUSE_STATUS_RETRY_INTERVAL`, default 2s

> To troubleshoot, add `DEBUG_AUTOSTOP=true` to see additional output

## Proxy Support
If you make use of PROXY Protocol, i.e. through something like HAProxy or Fly.io, you will need to enable it in your variety of server's configuration, and then set the `USES_PROXY_PROTOCOL` envar to `true`. This lets Autostop monitor the server, where it otherwise wouldn't


================================================
FILE: docs/misc/autoscale/autoscale.md
================================================

# Autoscaling (sleep when idle)

Autoscaling (sometimes called *sleeping*, *scale to zero* or *wake on join*) is the pattern of stopping a Minecraft server when nobody is playing and starting it again when someone tries to connect with the intention of saving resources when the server is not in use (e.g., on a VPS with limited CPU/RAM or a home server).

## mc-router

[mc-router](https://github.com/itzg/mc-router) is a Minecraft-aware router/multiplexer.

- Routes players by the hostname they connect with (useful for multiple servers behind one port)
- Can auto-start a backend container on join and stop it again after an idle timeout

Examples:

- See the mc-router section in [Examples](../examples.md#mc-router-with-auto-scale)

## Lazymc

[Lazymc](https://github.com/timvisee/lazymc) can keep a server “asleep” until a player connects. With Docker it’s commonly used via [lazymc-docker-proxy](https://github.com/joesturge/lazymc-docker-proxy).

- Players connect to the proxy; the proxy starts/stops the server container
- Usually requires a static IP for the Minecraft container on a user-defined network

Example:

- See the Lazymc section in [Examples](../examples.md#lazymc-put-your-minecraft-server-to-rest-when-idle)

## Lazytainer

[Lazytainer](https://github.com/vmorganp/Lazytainer) starts/stops containers based on network traffic.

- Uses packet thresholds + inactivity timeouts (not Minecraft hostname aware)
- Can be triggered by port scans/pings in noisy environments

Example:

- See the Lazytainer section in [Examples](../examples.md#lazytainer-stop-minecraft-container-based-on-traffic)




================================================
FILE: docs/misc/building.md
================================================

## Simple image additions

You can easily build upon the base image using an inline Dockerfile.

```yaml title="compose.yaml"
services:
  mc:
    build:
      context: .
      dockerfile_inline: |
        FROM itzg/minecraft-server:latest

        RUN apt-get update && apt-get install -y \
            webp \
            && rm -rf /var/lib/apt/lists/*
      pull: true # Always pull new base image
    pull_policy: build
    restart: unless-stopped
    environment:
      EULA: true
    ports:
      - "25565:25565/tcp"
    volumes:
      - ./data:/data
```

Here is an example to add Nvidia GPU support for C2ME:

??? Example "C2ME GPU example"
    ```yaml title="compose.yaml"
    
    services:
      mc:
        build:
          context: .
          dockerfile_inline: |
            FROM itzg/minecraft-server:java25
    
            # Install OpenCL loader and NVIDIA driver capabilities
            RUN apt-get update && apt-get install -y \
                ocl-icd-libopencl1 \
                opencl-headers \
                clinfo \
                && rm -rf /var/lib/apt/lists/*
    
            # 1. Create the vendor directory
            # 2. Tell OpenCL to use the NVIDIA library
            RUN mkdir -p /etc/OpenCL/vendors && \
                echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd
    
            # Tell the NVIDIA container runtime to expose all GPU capabilities (including compute/utility)
            ENV NVIDIA_VISIBLE_DEVICES all
            ENV NVIDIA_DRIVER_CAPABILITIES compute,utility,graphics,video
    
            COPY ./mods /mods
          pull: true # Always pull new base image
        pull_policy: build
        restart: unless-stopped
        deploy:
          resources:
            reservations:
              devices:
                - driver: nvidia
                  count: 1
                  capabilities: [gpu]
        environment:
          EULA: true
          TYPE: "FABRIC"
          VERSION: 1.21.10
          MEMORY: 8G
          MODRINTH_PROJECTS: |-
            fabric-api
            c2me
        ports:
          - "25565:25565/tcp"
        volumes:
          - ./data:/data
    ```


!!! tip "For advanced use only"

    This page describes a capability that is not applicable to most users. It is only intended for rare cases when a very specific Java base image is needed or additional packages need to be installed that are not generally applicable or would bloat the image size.

    Be sure to confirm that the desired [version and variant of Java isn't already provided](../versions/java.md).

## Building image locally with alternate Java base

An alternate Java base image can be specified by setting the [docker build argument](https://docs.docker.com/reference/cli/docker/buildx/build/#build-arg) `BASE_IMAGE` to the desired base image. The following shows an example of using the base image `ghcr.io/graalvm/graalvm-ce:ol8-java11`:

```shell
docker build --build-arg BASE_IMAGE=ghcr.io/graalvm/graalvm-ce:ol8-java11 -t IMG_PREFIX/minecraft-server:java11-graalvm .
```

## Building a multi-architecture image

Ensure buildx/BuildKit support is enabled and run the following to build multi-architecture and push to the repository as named by the image:

```shell
docker buildx build --platform=linux/arm64 --platform=linux/arm/v7 --platform=linux/amd64 --tag IMG_PREFIX/minecraft-server --push .
```

To build for local images, multi-architecture is not supported, use the following with buildx to load the image into the local daemon:

```shell
docker buildx build --tag IMG_PREFIX/minecraft-server --load .
```

or just a plain build

```shell
docker build -t IMG_PREFIX/minecraft-server .
```

## Installing extra packages

The following build args can be set to install additional packages for the respective base image distro:

- `EXTRA_DEB_PACKAGES`
- `EXTRA_DNF_PACKAGES`
- `EXTRA_ALPINE_PACKAGES`


================================================
FILE: docs/misc/contributing/development.md
================================================
## 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-deployFabric](https://github.com/itzg/docker-minecraft-server/blob/master/scripts/start-deployFabric) 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-setupWorld` 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](https://github.com/itzg/docker-minecraft-server/blob/master/scripts/start-configuration)
5. Add a section to the [docs](https://github.com/itzg/docker-minecraft-server/tree/master/docs). 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

The included `compose-dev.yml` will mount the local `scripts` code into the container and allow for iterative development. Replace `[-e key=value]` with any environment variables you wish to set for testing the modified scripts.

```shell
docker compose -f compose-dev.yml run --rm -it [-e key=value]  mc-dev
```

!!! tip

    To speed up the development cycle, it is recommended to set `SETUP_ONLY` to `true` as part of the run command above.

## Using development copy of tools

In the cloned repo, such as [`mc-image-helper`](https://github.com/itzg/mc-image-helper), install the distribution locally by running:

```shell
./gradlew installDist
```

The distribution will be installed in the project's `build/install/mc-image-helper`. Obtain the absolute path to that directory use in the next step.

Refer to the instructions above to mount any locally modified image scripts or build a local copy of the image using or with alternate `BASE_IMAGE`, as described above:

```shell
docker build -t itzg/minecraft-server .
```

Mount the local mc-image-helper distribution directory as a volume in the container at the path `/usr/share/mc-image-helper`, such as

```shell
docker run -it --rm \
  -v /path/to/mc-image-helper/build/install/mc-image-helper:/usr/share/mc-image-helper \
  -e EULA=true \
  itzg/minecraft-server
```

In a compose file, include the volume mount in the `volumes` section of the container definition:

```yaml
services:
  mc:
    # ... usual container definition
    volumes:
      - /path/to/mc-image-helper/build/install/mc-image-helper:/usr/share/mc-image-helper:ro
```

For Go base tools, run

```shell
goreleaser release --snapshot --clean
```

Clone [itzg/github-releases-proxy](https://github.com/itzg/github-releases-proxy) and run it according to the instructions shown there.

In the Docker build, configure the following 

```shell
--build-arg GITHUB_BASEURL=http://host.docker.internal:8080 \
--build-arg APPS_REV=1
```

and declare one or more version overrides, such as

```
--build-arg MC_HELPER_VERSION=1.8.1-SNAPSHOT
```

## 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
```


================================================
FILE: docs/misc/contributing/docs.md
================================================
# Site documentation

The documentation for this image/repository is written in markdown and built using [Zensical](https://zensical.org/) into a documentation website hosted at [Read the Docs](https://readthedocs.org/). [Here is general information about writing Zensical markdown](https://zensical.org/docs/authoring/markdown/).

!!! note
    The README.md rarely needs to be modified and only serves as a brief introduction to the project.

The documentation source is maintained in the [docs](https://github.com/itzg/docker-minecraft-server/tree/master/docs) folder and is organized into sections by directory and files. Look through the existing content to determine if an existing file should be updated or a new file/directory added.

It will be very helpful to view the rendered documentation as you're editing. To do that run the following from the top-level directory:

```shell
docker compose -f compose-docs.yml -p zensical up
```

You can access the live documentation rendering at <http://localhost:8000>.


================================================
FILE: docs/misc/deployment/index.md
================================================
# More Deployment Info 

## On Kubernetes

### Using Helm

- itzg Helm Chart:
    - [GitHub repo](https://github.com/itzg/minecraft-server-charts)
      - [Helm Chart repo](https://itzg.github.io/minecraft-server-charts/)
- [mcsh/server-deployment](https://github.com/mcserverhosting-net/charts)

### Using Shulker

[Shulker](https://github.com/jeremylvln/Shulker) is a Kubernetes operator for managing complex and dynamic Minecraft infrastructures, including game servers and proxies. It uses the docker-minecraft-server and docker-bungeecord images under-the-hood.

## With Ansible

[Ansible](https://docs.ansible.com/ansible/latest/getting_started/introduction.html) is an open-source task automation tool built in [Python](https://www.python.org/). Ansible playbooks can be used to automate all kinds of tasks, including deploying remote Minecraft servers.

### Using the MASH playbook

[The MASH Playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) is a premade playbook with the option to deploy a [wide variety of open-source services](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md) to your server(s), including [docker-minecraft-server](https://github.com/XHawk87/ansible-role-minecraft), making it a good option if you want all the bells and whistles alongside your Minecraft server.
- Check out the [Installation Guide](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/README.md) for the MASH playbook to get started.
- You can then enable [Minecraft](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/minecraft.md) in your vars.yml.
- Enable any supporting services that you might find useful, such as [user authentication](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/authelia.md), [remote backups](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/backup-borg.md), [email relay](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/exim-relay.md), [cron monitoring](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/healthchecks.md), [audio and video conferencing](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/jitsi.md), databases ([MariaDB](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/mariadb.md), [PostgresSQL](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/postgres.md)), [push notifications](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/ntfy.md), [uptime monitoring](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/uptime-kuma.md), [a website](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/wordpress.md), as well as installing any [extra files, folders, applications, services and running commands](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/auxiliary.md) automatically on deployment.

## On CloudFormation (AWS)

If you're looking for a simple way to deploy this to the Amazon Web Services Cloud, check out the [Minecraft Server Deployment (CloudFormation) repository](https://github.com/vatertime/minecraft-spot-pricing). This repository contains a CloudFormation template that will get you up and running in AWS in a matter of minutes. Optionally it uses Spot Pricing so the server is very cheap, and you can easily turn it off when not in use.

## Supporting Articles

Below are supporting articles for server deployment.

- "Zero to Minecraft Server with Docker Desktop and Compose"

    https://dev.to/rela-v/zero-to-minecraft-server-with-docker-desktop-and-compose-500a

    - This is a reference guide/tutorial on how to set up a vanilla Minecraft server using this project, including step-by-step instructions, and information on topics such as port-forwarding.


================================================
FILE: docs/misc/examples.md
================================================
# Examples

Various examples are [maintained in the repository](https://github.com/itzg/docker-minecraft-server/tree/master/examples). The sections below highlight a few particular ones.

## Bedrock compatible server

Using the [GeyserMC plugin](https://geysermc.org/) with a Paper server (or similar) "enables clients from Minecraft Bedrock Edition to join your Minecraft Java server". The example also includes [Floodgate](https://wiki.geysermc.org/floodgate/) which "allows Xbox Live authenticated Bedrock users to join without a Java Edition account". 

```yaml title="compose.yaml"

services:
  mc:
    image: itzg/minecraft-server:latest
    pull_policy: daily
    environment:
      EULA: "true"
      TYPE: "PAPER"
      PLUGINS: |
        https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot
        https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot
    ports:
      - "25565:25565"
      - "19132:19132/udp"
    volumes:
      - ./data:/data
```

[Source](https://github.com/itzg/docker-minecraft-server/blob/master/examples/geyser/docker-compose.yml)


## mc-router with auto-scale

Using [mc-router](https://github.com/itzg/mc-router) in front of one or multiple Minecraft server containers allows you to route players based on the hostname they use to connect.

With `AUTO_SCALE_UP` and `AUTO_SCALE_DOWN` enabled, mc-router can automatically start a target server when a player connects and stop it again after a period of inactivity.

```yaml title="compose.yaml"
services:
  router:
    image: itzg/mc-router
    environment:
      IN_DOCKER: true
      AUTO_SCALE_DOWN: true
      AUTO_SCALE_UP: true
      AUTO_SCALE_DOWN_AFTER: 2h
      AUTO_SCALE_ASLEEP_MOTD: "Server is asleep. Join again to wake it up!"
    ports:
      - "25565:25565"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  vanilla:
    image: itzg/minecraft-server
    environment:
      EULA: "TRUE"
    labels:
      mc-router.host: "vanilla.example.com"

  paper:
    image: itzg/minecraft-server
    environment:
      EULA: "TRUE"
      TYPE: PAPER
    labels:
      mc-router.host: "paper.example.com"
```

[Source](https://github.com/itzg/mc-router/blob/main/examples/docker-autoscale/compose-minimal.yml)

[More detailed example](https://github.com/itzg/mc-router/blob/main/examples/docker-autoscale/compose.yml)

## Lazymc - Put your Minecraft server to rest when idle

With [lazymc-docker-proxy](https://github.com/joesturge/lazymc-docker-proxy) you are able to use [lazymc](https://github.com/timvisee/lazymc) with the minecraft container.

```yaml title="compose.yaml"
# Lazymc requires that the minecraft server have a static IP.
#
# To ensure that our servers have a static IP we need to create
# a network for our services to use.
#
# By default, Docker uses 172.17.0.0/16 subnet range.
# So we need to create a new network in a different subnet
# See the readme for more information.
#
# Please ensure that the subnet falls within the private CIDRs:
# https://datatracker.ietf.org/doc/html/rfc1918#section-3
#
# And that it is not in use by anything else.
networks:
  minecraft-network:
    driver: bridge    
    ipam:
      config:
        - subnet: 172.18.0.0/16

services:
  lazymc:
    image: ghcr.io/joesturge/lazymc-docker-proxy:latest
    # the IPs should start at .2 as .1 is reserved for the gateway
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.2
    restart: unless-stopped
    volumes:
      # you should mount the minecraft server dir under /server, using read only.
      - data:/server:ro
      # you need to supply the docker socket, so that the container can run docker command
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      # lazymc-docker-proxy acts as a proxy, so there is
      # no need to expose the server port on the Minecraft container
      - "25565:25565"

  # Standard Docker Minecraft server, also works with other server types
  mc:
    image: itzg/minecraft-server:java21
    pull_policy: daily
    # Assign a static IP to the server container
    networks:
      minecraft-network:
        ipv4_address: 172.18.0.3
    # We need to add a label here so that lazymc-docker-proxy knows which
    # container to manage
    labels:
      # Set lazymc.enabled to true to enable lazymc on this container
      - lazymc.enabled=true
      # Required to find the container to manage it
      - lazymc.group=mc
      # Point to the service name of the Minecraft server
      - lazymc.server.address=mc:25565
    tty: true
    stdin_open: true
    # This container should be managed solely by the lazymc container
    # so set restart to no, or else the container will start again...
    restart: no
    environment:
      EULA: "TRUE"
    volumes:
      - data:/data

volumes:
  data:
```
[Source](https://github.com/joesturge/lazymc-docker-proxy/blob/master/docker-compose.yaml)

## Lazytainer - Stop Minecraft container based on traffic
Monitors network traffic to the Minecraft containers. If there is traffic, the container runs, otherwise the container is stopped/paused.

By using [Lazytainer](https://github.com/vmorganp/Lazytainer) with the [docker-minecraft-server](https://github.com/itzg/docker-minecraft-server) a somehow similar behaviour to [Lazymc](https://github.com/timvisee/lazymc) can be archived.

```yaml title="compose.yaml"
services:
  lazytainer:
    image: ghcr.io/vmorganp/lazytainer:master
    environment:
      VERBOSE: false
    ports:
      - 25565:25565
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      - lazytainer.group.minecraft.sleepMethod=stop
      - lazytainer.group.minecraft.ports=25565
      - lazytainer.group.minecraft.minPacketThreshold=2 # Start after two incomming packets
      - lazytainer.group.minecraft.inactiveTimeout=600 # 10 minutes, to allow the server to bootstrap. You can probably make this lower later if you want.
    restart: unless-stopped
    network_mode: bridge
  mc:
    image: itzg/minecraft-server:latest
    pull_policy: daily
    environment:
      EULA: TRUE
      TYPE: PAPER
      MEMORY: 4G
    volumes:
      - ./data:/data
    labels:
      - lazytainer.group=minecraft
    depends_on:
      - lazytainer
    network_mode: service:lazytainer
    tty: true
    stdin_open: true
    restart: unless-stopped
```
[Source](https://github.com/itzg/docker-minecraft-server/blob/master/examples/lazytainer/docker-compose.yml)


================================================
FILE: docs/misc/healthcheck.md
================================================
## Healthcheck

This image contains [mc-monitor](https://github.com/itzg/mc-monitor) and uses its `status` command to continually check on the container's. That can be observed from the `STATUS` column of `docker ps`

```
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS                                 NAMES
b418af073764        mc                  "/start"            43 seconds ago      Up 41 seconds (healthy)   0.0.0.0:25565->25565/tcp, 25575/tcp   mc
```

You can also query the container's health in a script-friendly way:

``` shell
> docker container inspect -f "{{.State.Health.Status}}" mc
healthy
```

There's actually a wrapper script called `mc-health` that takes care of calling `mc-monitor status` with the correct arguments. If needing to customize the health checks parameters, such as in a Compose file, then use something like the following in the service declaration:

``` yaml
healthcheck:
  test: mc-health
  start_period: 1m
  interval: 5s
  retries: 20
```

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 health checks by setting the environment variable `DISABLE_HEALTHCHECK` to `true`.

The [health check in a Compose service declaration](https://docs.docker.com/reference/compose-file/services/#healthcheck) can also be disabled using:

```yaml
    healthcheck:
      disable: true
      test: ["NONE"]
```

### Health checks for older versions

This container disables health checks for Minecraft versions before b1.8 as those versions do not support any kind of server pinging. For more information see [Server List Ping](https://minecraft.wiki/w/Java_Edition_protocol/Server_List_Ping#Beta_1.8_to_1.3).


================================================
FILE: docs/misc/log4j.md
================================================
**Please ensure you have pulled the latest image** since [all official mitigations](https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition) are automatically applied by the container startup process.


================================================
FILE: docs/misc/raspberrypi.md
================================================
# Running on RaspberryPi

To run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags [list in the Java version section](../versions/java.md) that specify `armv7` for the architecture, which includes `itzg/minecraft-server:latest`.

!!! note
   
   You may need to lower the memory allocation, such as `-e MEMORY=750m`

!!! note

    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).


================================================
FILE: docs/misc/related-projects.md
================================================
### [itzg/minecraft-bedrock-server](https://github.com/itzg/docker-minecraft-bedrock-server)

Docker image that runs a Minecraft Bedrock server.

### [mc-router](https://github.com/itzg/mc-router)

Lightweight multiplexer/proxy for Minecraft Java servers. Provided as a stand-alone application and a Docker image.

### [itzg/mc-proxy](https://github.com/itzg/docker-bungeecord/)

Docker image that runs a proxy powered by Bungeecord, Velocity, or Waterfall

### [itzg/mc-backup](https://github.com/itzg/docker-mc-backup)

Docker image that runs as a side-car container to backup world data.

### [rcon-cli](https://github.com/itzg/rcon-cli)

A tool that is bundled with this image to provide CLI access to an RCON endpoint.

### [mc-monitor](https://github.com/itzg/mc-monitor)

A tool that is bundled with this image that provides health checks and metrics reporting, such as a Prometheus exporter or a telegraf data source.

### [mc-image-helper](https://github.com/itzg/mc-image-helper)

A tool that is bundled with this image to provide complex, re-usable preparation operations. 

### [itzg/rcon](https://github.com/itzg/docker-rcon-web-admin)

An image that dockerizes [rcon-web-admin](https://github.com/rcon-web-admin/rcon-web-admin).


================================================
FILE: docs/misc/troubleshooting.md
================================================
To troubleshoot the container initialization, such as when server files are pre-downloaded, set the environment variable `DEBUG` to `true`. The container logs will include **much more** output, and it is highly recommended including that output when reporting any [issues](https://github.com/itzg/docker-minecraft-server/issues).

To troubleshoot just the command-line used to start the Minecraft server, set the environment variable `DEBUG_EXEC` to `true`.

To troubleshoot any issues with memory allocation reported by the JVM, set the environment variable `DEBUG_MEMORY` to `true`.

If you are experiencing any issues with the "Changing ownership of /data" step, that can be disabled by setting `SKIP_CHOWN_DATA` to `true`.

To confirm the image version that has been pulled, use the following command, replacing `itzg/minecraft-server` as needed for specific image tags:

## Image labels

```shell
docker image inspect itzg/minecraft-server -f "{{json .Config.Labels}}"
```

such as

```json
{
  "org.opencontainers.image.authors": "... <...@gmail.com>",
  "org.opencontainers.image.created": "2025-04-03T02:15:51.405Z",
  "org.opencontainers.image.description": "Docker image that provides a Minecraft Server for Java Edition that automatically downloads selected version at startup",
  "org.opencontainers.image.licenses": "Apache-2.0",
  "org.opencontainers.image.ref.name": "ubuntu",
  "org.opencontainers.image.revision": "d6897a649ecbc16b5fb2e1500e24b64ef80270a0",
  "org.opencontainers.image.source": "https://github.com/itzg/docker-minecraft-server",
  "org.opencontainers.image.title": "docker-minecraft-server",
  "org.opencontainers.image.url": "https://github.com/itzg/docker-minecraft-server",
  "org.opencontainers.image.version": "java21"
}
```

The labels that are most interesting are:

- `org.opencontainers.image.created` : the date/time the image was built
- `org.opencontainers.image.revision` : which maps to <https://github.com/itzg/docker-minecraft-server/commit/REVISION>
- `org.opencontainers.image.version` : image tag and variant [as described in this page](../versions/java.md)

================================================
FILE: docs/misc/world-data.md
================================================

## Downloadable world

Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP or compressed TAR 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

    This URL must be accessible from inside the container. Therefore, 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, zip file, or compressed tar file that will be used as a source to clone or extract the world directory.

For example, the following would initially clone the world's content from `/worlds/basic`. Also notice in the example that you should use a read-only volume attachment to ensure the clone source remains pristine.

```
docker run ... -v $HOME/worlds:/worlds:ro -e WORLD=/worlds/basic
```

The following diagram shows how this option can be used in a compose deployment with a relative directory:

![](../img/world-copy-compose-project.drawio.png)

## 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.

## Custom worlds directory path
To set a custom worlds directory for the Multiverse plugin on a baremetal server, you'd pass the `--world-dir` argument after the jar file.
In order to accomplish the same in a containerized server, set the `EXTRA_ARGS` environment variable in your command line or docker compose yaml to the same argument string. For example:

```
docker run -d -e EXTRA_ARGS='--world-dir ./worlds/'
```
`--world-container`, `-W`, and `--universe` are aliases to `--world-dir` and can also be used.

## Datapacks

Datapacks can be installed in a similar manner to mods/plugins. There are many environment variables which function in the same way they do for [mods](../mods-and-plugins/index.md):

* `DATAPACKS`: comma-separated list of zip file URL, zip file in container, or directory in container
* `DATAPACKS_FILE`: a text file within the container where each line is a zip file URL, zip file in container, or directory in container
* `REMOVE_OLD_DATAPACKS`: if "true" the datapacks directory is removed of everything matching `REMOVE_OLD_DATAPACKS_INCLUDE`, but excluding `REMOVE_OLD_DATAPACKS_EXCLUDE` no deeper than `REMOVE_OLD_DATAPACKS_DEPTH`
* `REMOVE_OLD_DATAPACKS_DEPTH`: default is 16
* `REMOVE_OLD_DATAPACKS_INCLUDE`: default is `*.zip`
* `REMOVE_OLD_DATAPACKS_EXCLUDE`: default is empty

Datapacks will be placed in `/data/$LEVEL/datapacks`

## VanillaTweaks

[VanillaTweaks](https://vanillatweaks.net/) datapacks, crafting tweaks, and resource packs can be installed with a share code from the website **OR** a json file to specify packs to download and install. Datapacks and crafting tweaks will be installed into the current world directory specified by `$LEVEL`. As new versions of the packs are retrieved the previous versions will automatically be cleaned up.

The share code is the part following the hash sign, as shown here:

```
https://vanillatweaks.net/share/#MGr52E
                                 ------
                                  |
                                  +- share code MGr52E
```

Accepted Parameters:

- `VANILLATWEAKS_FILE`: comma separated list of JSON VanillaTweak pack files accessible within the container
- `VANILLATWEAKS_SHARECODE`: comma separated list of share codes

Example of expected VanillaTweaks share codes:

!!! note

    ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes

``` yaml
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
```

!!! note

    Datapack names are all lower case. [See their spec](https://vanillatweaks.net/assets/resources/json/1.21/dpcategories.json) for a full list of 1.21 datapacks, and [their spec](https://vanillatweaks.net/assets/resources/json/1.21/ctcategories.json) for a full list of 1.21 crafting tweaks.

Example of expected VanillaTweaks files:

``` yaml
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
```

``` json title="DataPacks json"
{
  "type": "datapacks",
  "version": "1.21",
  "packs": {
    "gameplay changes": [
      "graves",
      "multiplayer sleep",
      "armored elytra"
    ],
    "teleport commands": ["tpa"]
  }
}
```

``` json title="ResourcePacks json"
{
    "type": "resourcepacks",
    "version": "1.21",
    "packs": {
        "aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
    }
}
```


``` json title="CraftingTweaks Json"
{
    "type": "craftingtweaks",
    "version": "1.21",
    "packs": {
        "quality of life": [
            "dropper to dispenser",
            "double slabs",
            "back to blocks"
        ]
    }
}
```


================================================
FILE: docs/mods-and-plugins/curseforge-files.md
================================================
# Auto-download from CurseForge

Mods and plugins can be auto-downloaded and upgraded from CurseForge by setting `CURSEFORGE_FILES` to a comma or space delimited list of [project-file references](#project-file-references). References removed from the declaration are automatically cleaned up and setting `CURSEFORGE_FILES` to an empty string removes all previously managed project-files.

A specific file can be omitted from each reference to allow for auto-selecting the newest version of the selected mod/plugin. The resolved `VERSION` and `TYPE` will be taken into consideration for selecting the appropriate file. 

!!! warning "CurseForge API key usage"

    A CurseForge API key must be allocated and set with `CF_API_KEY` (or `CF_API_KEY_FILE`) [as described here](../types-and-platforms/mod-platforms/auto-curseforge.md#api-key).

## Project-file references

!!! tip

    Individual project files typically represent a version of the mod/plugin, but CurseForge refers to these items broadly as "files" rather than "versions". 

The following formats are supported in the list of project-file references:

- A project page URL, such as `https://www.curseforge.com/minecraft/mc-mods/jei`. _The newest applicable file will be automatically selected._
- A file page URL, such as `https://www.curseforge.com/minecraft/mc-mods/jei/files/4593548`
- Project slug, such as `jei`. _The newest applicable file will be automatically selected._
- Project ID, such as `238222`. _The newest applicable file will be automatically selected._
- Project slug or ID, `:`, and a file ID, such as `jei:4593548` or `238222:4593548`
- Project slug or ID, `@`, and a partial filename, such as `jei@10.2.1.1005`. This option is useful to refer to a version of the mod/plugin rather than looking up the file ID.
- An `@` followed by the **container path** to a listing file

!!! info "More about listing files"

    Each line in the listing file is processed as one of the references above; however, blank lines and comments that start with `#` are ignored.
    
    Make sure to place the listing file in a mounted directory/volume or declare an appropriate mount for it.
    
    For example, `CURSEFORGE_FILES` can be set to "@/extras/cf-mods.txt", assuming "/extras" has been added to `volumes` section, where the container file `/extras/cf-mods.txt` contains
    
    ```text
    # This comment is ignored
    jei:10.2.1.1005
    
    # This and previous blank line are ignore
    geckolib
    aquaculture
    naturalist
    ```

!!! tip "Multi-line values in Docker Compose"

    Making use of the space delimited option, compose file declarations can be organized nicely with a [multi-line string](https://yaml-multiline.info/), such as
    
    ```yaml
          CURSEFORGE_FILES: |
            geckolib
            aquaculture
            naturalist
    ```

## Dependencies

The files processing can detect if a dependency is missing from the given list, but is not able to resolve the dependencies otherwise since their metadata only gives the mod ID and not the specific file version/ID that is needed.


================================================
FILE: docs/mods-and-plugins/index.md
================================================
# Working with mods and plugins

## Modpack platforms

By far the easiest way to work with mod and plugins, especially large numbers of them, is to utilize modpacks with [one of the supported modpack platforms](../types-and-platforms/index.md).

The following are some supported modpack platforms:

- [Modrinth](../types-and-platforms/mod-platforms/modrinth-modpacks.md) 
- [CurseForge](../types-and-platforms/mod-platforms/auto-curseforge.md)
- [Feed the Beast](../types-and-platforms/mod-platforms/ftb.md)

## Download automation

On the left, there are sections describing some download automation options.

## Mods vs Plugins

The terms "mods" and "plugins" can be quite confusing. Generally, the rule of thumb is that "mods" are used by the types that run client side to modify rendering, add new blocks, and add behaviors server, such as [Forge](../types-and-platforms/server-types/forge.md) and [Fabric](../types-and-platforms/server-types/fabric.md). "Plugins" are used by the types that **only run on servers** to add behaviors, commands, etc such as [Paper](../types-and-platforms/server-types/paper.md) (which derives from [Bukkit/Spigot](../types-and-platforms/server-types/bukkit-spigot.md)). There are also some types that are [hybrids](../types-and-platforms/server-types/hybrids.md), such as Magma, that use both "mods" and "plugins".

Typically, mods needs to be installed in both the client and server; however, there are some cases when only the server needs a mod. Plugins only need to be installed in the server and are never needed in the client.

## Optional plugins, mods, and config attach points

There are optional volume paths that can be attached to supply content to be copied into the data area:

`/plugins`
: content in this directory is synchronized into `/data/plugins` for server types that use plugins, [as described above](#mods-vs-plugins). For special cases, the source can be changed by setting `COPY_PLUGINS_SRC` and destination by setting `COPY_PLUGINS_DEST`. If using a mod-based loader, such as Forge or Fabric, but a hybrid mod like [Cardboard](https://modrinth.com/mod/cardboard), then set `USES_PLUGINS` to have the automation utilize `/plugins` mount.

!!! example "Using Cardboard plugins with Fabric"

    ```yaml
        environment:
          EULA: "TRUE"
          TYPE: "FABRIC"
          MODRINTH_PROJECTS: |
            fabric-api
            cardboard
          USES_PLUGINS: true
    ```

`/mods`
: content in this directory is synchronized into `/data/mods` for server types that use mods, [as described above](#mods-vs-plugins). For special cases, the source can be changed by setting `COPY_MODS_SRC` and destination by setting `COPY_MODS_DEST`.

`/config`
: contents are synchronized into `/data/config` by default, but can be changed with `COPY_CONFIG_DEST`. 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. The source can be changed by setting `COPY_CONFIG_SRC`. Set `SYNC_SKIP_NEWER_IN_DESTINATION=false` if you want files from `/config` to take precedence over newer files in `/data/config`.

By default, the [environment variable processing](../configuration/interpolating.md) is performed on synchronized files that match the expected suffixes in `REPLACE_ENV_SUFFIXES` (by default "yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml") and are not excluded by `REPLACE_ENV_VARIABLES_EXCLUDES` and `REPLACE_ENV_VARIABLES_EXCLUDE_PATHS`. This processing can be disabled by setting `REPLACE_ENV_DURING_SYNC` to `false`.

If you want old mods/plugins to be removed before the content is brought over from those attach points, 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, which are comma separated lists of file glob patterns. If a directory is excluded, then it and all of its contents are excluded. By default, only jars are removed. 

You can also specify the `REMOVE_OLD_MODS_DEPTH` (default is 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.

These paths work 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.

!!! information "Multiple source directories"

    `COPY_PLUGINS_SRC`, `COPY_MODS_SRC`, `COPY_CONFIG_SRC` can each be set to a comma or newline delimited list of container directories to reference.

    For example, in a compose file:
    
    ```yaml
        environment:
          # ...EULA, etc
          TYPE: PAPER
          # matches up to volumes declared below
          COPY_PLUGINS_SRC: /plugins-common,/plugins-local
        volumes:
          - mc-data:/data
          # For example, reference a shared directory used by several projects
          - ../plugins-common:/plugins-common:ro
          # and add plugins unique to this project
          - ./plugins:/plugins-local:ro
    ```

    Alternatively, you can declare other directories along with files and URLs to use in [the `MODS` / `PLUGINS` variables](#modsplugins-list).

## Applying extra configuration files

You can download/copy additional configuration files or other resources before the server starts by using the `APPLY_EXTRA_FILES` environment variable. This is useful for downloading configs that you want to patch or modify during the startup process.

The format uses a `<` separator between the destination path and the source URL/path. The destination path is relative to the `/data` directory. If specifying a source path, it needs to be path mounted within the container.

!!! example

    With `docker run`
    
    ```
    -e APPLY_EXTRA_FILES=destination<source_url[,destination2<source_url2,...]
    ```
    
    With a compose file:
    ```yaml
    environment:
      APPLY_EXTRA_FILES: |
        destination<source1_url
        destination2<source2_path
    ```

!!! tip "Patch-able"

The `APPLY_EXTRA_FILES` feature is processed prior to [patch processing](../configuration/interpolating.md#patching-existing-files), so this can be used as for baseline files to be patched further at runtime.

## Zip file modpack

Like the `WORLD` option above, you can specify the URL or container path of a "mod pack" to download and install into `mods` for Forge/Fabric or `plugins` for Bukkit/Spigot. To use this option pass the environment variable `MODPACK`, such as

```shell
docker run -d -e MODPACK=http://www.example.com/mods/modpack.zip ...
```

!!! note
    The referenced URL/file must be a zip file with one or more jar files at the
    top level of the zip archive. Make sure the jars are compatible with the
    particular `TYPE` of server you are running.

## Generic pack files

To install all the server content (jars, mods, plugins, configs, etc.) from a zip or tgz file, then set `GENERIC_PACK` to the container path or URL of the archive file. This can also be used to apply a CurseForge modpack that is missing a server start script and/or Forge installer.

If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of archive file paths and/or URLs to files.

To avoid repetition, each entry will be prefixed by the value of `GENERIC_PACKS_PREFIX` and suffixed by the value of `GENERIC_PACKS_SUFFIX`, both of which are optional. For example, the following variables

```
GENERIC_PACKS=configs-v9.0.1,mods-v4.3.6
GENERIC_PACKS_PREFIX=https://cdn.example.org/
GENERIC_PACKS_SUFFIX=.zip
```

would expand to `https://cdn.example.org/configs-v9.0.1.zip,https://cdn.example.org/mods-v4.3.6.zip`.

If applying large generic packs, the update can be time-consuming. To skip the update set `SKIP_GENERIC_PACK_UPDATE_CHECK` to "true". Conversely, the generic pack(s) can be forced to be applied by setting `FORCE_GENERIC_PACK_UPDATE` to "true".

The most time-consuming portion of the generic pack update is generating and comparing the SHA1 checksum. To skip the checksum generation, set `SKIP_GENERIC_PACK_CHECKSUM` to "true".

To disable specific mods, which can be useful for conflicts between multiple generic packs, you can use the `GENERIC_PACKS_DISABLE_MODS` variable to specify mods to disable.

Disabling mods with docker run:
```shell
docker run -d -e GENERIC_PACKS_DISABLE_MODS="mod1.jar mod2.jar" ...
```

Disabling mods within docker compose files:
```yaml
      GENERIC_PACKS_DISABLE_MODS: |
        mod1.jar
        mod2.jar
```

## Mods/plugins list

You may also download or copy over individual mods/plugins using the `MODS` or `PLUGINS` environment variables. Both are a comma or newline delimited list of

- URL of a jar file
- container path to a jar file
- container path to a directory containing jar files

```shell
docker run -d -e MODS=https://www.example.com/mods/mod1.jar,/plugins/common,/plugins/special/mod2.jar ...
```

The newline delimiting allows for compose file usage like:
```yaml
      PLUGINS: |
        https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot
        https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot
```

!!! note "Auto-removal"

    Entries that are removed from the `MODS` or `PLUGINS` list will be automatically removed from the `mods` or `plugins` directory. This is useful for removing mods/plugins that are no longer needed. An empty `MODS` or `PLUGINS` list will remove all mods/plugins.

!!! note "Disable processing"

    To temporarily disable processing of the `MODS` or `PLUGINS` list, then comment out the `MODS` or `PLUGINS` environment variable.

## Mod/Plugin URL Listing File 

As an alternative to `MODS`/`PLUGINS`, the variable `MODS_FILE` or `PLUGINS_FILE` can be set with the container path or URL of a text file listing a mod/plugin URLs on each line. For example, the following

     -e MODS_FILE=/extras/mods.txt

would load from a file mounted into the container at `/extras/mods.txt`. That file might look like:

```text
https://edge.forgecdn.net/files/2965/233/Bookshelf-1.15.2-5.6.40.jar
https://edge.forgecdn.net/files/2926/27/ProgressiveBosses-2.1.5-mc1.15.2.jar
# This and next line are ignored
#https://edge.forgecdn.net/files/3248/905/goblintraders-1.3.1-1.15.2.jar
https://edge.forgecdn.net/files/3272/32/jei-1.15.2-6.0.3.16.jar
https://edge.forgecdn.net/files/2871/647/ToastControl-1.15.2-3.0.1.jar
```

!!! note

    Blank lines and lines that start with a `#` will be ignored

    [This compose file](https://github.com/itzg/docker-minecraft-server/blob/master/examples/mods-file/docker-compose.yml) shows another example of using this feature.

## Remove old mods/plugins

When the `MODPACK` option above is specified you can also instruct script to delete old mods/plugins prior to installing new ones. This behaviour is desirable in case you want to upgrade mods/plugins from downloaded zip file.

To use this option pass the environment variable `REMOVE_OLD_MODS=TRUE`, such as

```shell
docker run -d -e REMOVE_OLD_MODS=TRUE -e MODPACK=http://www.example.com/mods/modpack.zip ...
```

!!! danger 

    All content of the `mods` or `plugins` directory will be deleted before unpacking new content from the MODPACK or MODS.


================================================
FILE: docs/mods-and-plugins/modrinth.md
================================================
# Auto-download from Modrinth

[Modrinth](https://modrinth.com/) is an open source modding platform with a clean, easy to use website for finding [Fabric, Forge, etc mods](https://modrinth.com/mods) and [Paper, etc plugins](https://modrinth.com/plugins), and [datapacks](https://modrinth.com/datapacks). At startup, the container will automatically locate and download the newest versions of mod/plugin files that correspond to the `TYPE` and `VERSION` in use. Older file versions downloaded previously will automatically be cleaned up.

## Usage

To use this feature, set the environment variable `MODRINTH_PROJECTS` to a comma or newline separated list of projects.  

Each project entry can be any of the following combinations where a colon (`:`) is used to separate the different parts:

```
         Project
         Project : Version
         Project : Release Type
Prefix : Project
Prefix : Project : Version
Prefix : Project : Release Type
@ Listing File
```

Where:

- **Project** is the project slug or ID, see below
- **Version** is the version ID (such as "Oa9ZDzZq") or number (such as "2.21.2"). When omitted, the latest release version will be selected. Using version ID will override Minecraft and loader compatibility checks.
- **Release Type** is `release`, `beta`, or `alpha` indicating the latest version to select.
- **Prefix** is `datapack`, `fabric`, `forge`, or `paper`
    - The `datapack` prefix is optional when running a vanilla server
    - The `fabric`, `forge`, and `paper` prefixes allow for installing mods/plugins that differ from server's `TYPE`. Using [Sinytra Connector](https://modrinth.com/mod/connector) is an example of this, where Fabric mods can be loaded into a NeoForge server.
- **Listing file** is a container path to a file containing a list of projects

!!! tip "Project ID"

    The project ID can be copied to the clipboard from the project page menu:

    ![Modrinth copy project ID](../img/modrinth-copy-project-id.png)

!!! tip "Project Slug"

    The project slug is the part of the URL that follows `/mod/`, `/plugin/`, or `/datapack/`. For example, this one is "essentialsx".

    ![](../img/modrinth-plugin-project-slug.png)

!!! tip "Version number and ID"

    The version number and ID are located in the metadata panel on a version specific page, such as <https://modrinth.com/plugin/essentialsx/version/2.21.2>

    ![Version ID](../img/modrinth-version-id.drawio.png)

### Examples
            
| Description                     | Example projects entry                                |
|---------------------------------|-------------------------------------------------------|
| Select latest version           | `fabric-api`                                          |
| Select specific version         | `fabric-api:bQZpGIz0`<br/>`fabric-api:0.119.2+1.21.4` |
| Select latest beta version      | `fabric-api:beta`                                     |
| Latest version using project ID | `P7dR8mSH`                                            |
| Latest version of datapack      | `datapack:terralith`                                  |
| Specific version of datapack    | `datapack:terralith:2.5.5`                            |
| Mod loader override             | `fabric:fabric-api`<br/>`fabric:fabric-api:bQZpGIz0`  |
| Projects Listing File           | `@/path/to/modrinth-mods.txt`                         |

### Notes

!!! info "More about listing files"

    Each line in the listing file is processed as one of the references above; however, blank lines and comments that start with `#` are ignored.
    
    Make sure to place the listing file in a mounted directory/volume or declare an appropriate mount for it.
    
    For example, `MODRINTH_PROJECTS` can be set to "@/extras/modrinth-mods.txt", assuming "/extras" has been added to `volumes` section, where the container file `/extras/modrinth-mods.txt` contains
    
    ```text
    # This comment is ignored
    fabric-api
    
    # This and previous blank line are ignore
    cloth-config
    datapack:terralith
    ```

!!! note "Auto-removal"

    Entries that are removed from the `MODRINTH_PROJECTS` list will be automatically removed from the `mods` or `plugins` directory. This is useful for removing mods/plugins that are no longer needed. An empty `MODRINTH_PROJECTS` list will remove all mods/plugins.

!!! note "Disable processing"

    To temporarily disable processing of the `MODRINTH_PROJECTS` list, then comment out the `MODRINTH_PROJECTS` environment variable.

## Version from Projects

When the environment variable `VERSION_FROM_MODRINTH_PROJECTS` is set to "true" the Minecraft [`VERSION`](../versions/minecraft.md) will be automatically determined by looking at the most recent version of Minecraft that is supported by all the projects provided in `MODRINTH_PROJECTS`.

!!! example

    Given the environment variables
    
    ```yaml
        MODRINTH_PROJECTS: |
          viaversion
          viabackwards
          griefprevention
          discordsrv
        VERSION_FROM_MODRINTH_PROJECTS: true
    ```
    
    Let's say all are supported on Minecraft up to 1.21.8 except griefprevention, which is only supported up to 1.21.7. In that case, `VERSION` will be automatically set to 1.21.7.

## Extra options

`MODRINTH_DOWNLOAD_DEPENDENCIES`
: Can be set to `none` (the default), `required`, or `optional` to download required and/or optional dependencies.

`MODRINTH_PROJECTS_DEFAULT_VERSION_TYPE`
: The version type is used to determine the newest version to use from each project. The allowed values are `release` (default), `beta`, `alpha`. Setting to `beta` will pick up both release and beta versions. Setting to `alpha` will pick up release, beta, and alpha versions.

`MODRINTH_LOADER`
: When using a custom server, set this to specify which loader type will be requested during lookups



================================================
FILE: docs/mods-and-plugins/packwiz.md
================================================
# Packwiz Modpacks

[packwiz](https://packwiz.infra.link/) is a CLI tool for maintaining and providing modpack definitions, with support for both CurseForge and Modrinth as sources. See the [packwiz tutorial](https://packwiz.infra.link/tutorials/getting-started/) for more information.

To configure server mods using a packwiz modpack, set the `PACKWIZ_URL` environment variable to the location of your `pack.toml` modpack definition:

```
docker run -d --pull=always \
    -v /path/on/host:/data -e TYPE=FABRIC \
    -e "PACKWIZ_URL=https://example.com/modpack/pack.toml" \
    itzg/minecraft-server
```

packwiz modpack definitions are processed before other mod definitions (`MODPACK`, `MODS`, etc.) to allow for additional processing/overrides you may want to perform (in case of mods not available via Modrinth/CurseForge, or you do not maintain the pack).

!!! note 

    packwiz is pre-configured to only download server mods. If client-side mods are downloaded and cause issues, check your pack.toml configuration, and make sure any client-only mods are not set to `"both"`, but rather `"client"` for the side configuration item.


================================================
FILE: docs/mods-and-plugins/spiget.md
================================================
# Auto-download using Spiget

The `SPIGET_RESOURCES` variable can be set with a comma-separated list of SpigotMC resource IDs to automatically download [Spigot/Bukkit/Paper 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.

!!! important "SPIGET not SPIGOT"
    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/slug and a dot. For example, the ID is **28140** from

    https://www.spigotmc.org/resources/luckperms.28140/
                                                 =====

For example, the following will auto-download the [LuckPerms](https://www.spigotmc.org/resources/luckperms.28140/) and [Vault](https://www.spigotmc.org/resources/vault.34315/) plugins:

    -e SPIGET_RESOURCES=28140,34315

!!! note
    Some plugins, such as EssentialsX (resource ID 9089), do not permit automated downloads via Spiget. Instead, you will need to pre-download the desired file and supply it to the container, such as using the `/plugins` mount point, described [in the main section](index.md).



================================================
FILE: docs/requirements.txt
================================================
click==8.3.1
colorama==0.4.6
deepmerge==2.0
ghp-import==2.1.0
griffe==2.0.0
Jinja2==3.1.6
Markdown==3.10.2
MarkupSafe==3.0.3
mergedeep==1.3.4
mkdocs==1.6.1
mkdocs-autorefs==1.4.4
mkdocs-get-deps==0.2.2
mkdocstrings==1.0.3
mkdocstrings-python==2.0.3
packaging==26.0
pathspec==1.0.4
platformdirs==4.9.4
Pygments==2.19.2
pymdown-extensions==10.21
python-dateutil==2.9.0.post0
PyYAML==6.0.3
pyyaml_env_tag==1.1
six==1.17.0
watchdog==6.0.0
zensical==0.0.27


================================================
FILE: docs/sending-commands/commands.md
================================================
---
title: With Docker
---

[RCON](http://wiki.vg/RCON) is enabled by default, so you can `exec` into the container to
access the Minecraft server console:

```
docker exec -i mc rcon-cli
```

Note: The `-i` is required for interactive use of rcon-cli.

To run a simple, one-shot command, such as stopping a Minecraft server, pass the command as arguments to `rcon-cli`, such as:

```
docker exec mc rcon-cli stop
```

_The `-i` is not needed in this case._

## When RCON is disabled

If rcon is disabled you can send commands by passing them as arguments to the packaged `mc-send-to-console` script after setting the env var `CREATE_CONSOLE_IN_PIPE` to "true". For example, a player can be op'ed in the container `mc` with: 

```shell
docker exec --user 1000 mc mc-send-to-console op player
                        |                     |
                        +- container name     +- Minecraft commands start here
```

## Enabling interactive console

In order to attach and interact with the Minecraft server make sure to enable TTY and keep stdin open.

!!! example

    With `docker run` use the `-it` arguments:

    ```shell
    docker run -d -it -p 25565:25565 --name mc itzg/minecraft-server
    ```

    or with a compose file:

    ```yaml
    services:
      minecraft:
        stdin_open: true
        tty: true
    ```

With that you can attach and interact at any time using the following, replacing the `{...}` placeholders.

...when container is created with `docker run`
```
docker attach {container name or ID}
```

...or when declared using a compose file
```
docker compose attach {service name}
```

and then Control-p Control-q to **detach**.

!!! info "RCON is required for fully interactive, color console"

    RCON must be enabled, which is the default, in order to use a fully interactive console with auto-completion and colorized log output.


================================================
FILE: docs/sending-commands/ssh.md
================================================
---
title: Over SSH
---

The container can host an SSH console. It is enabled by setting `ENABLE_SSH` to `true`.
The SSH server only supports password based authentication. The password is the same as the RCON password.

!!! question
    See [the RCON password](../configuration/server-properties.md/#rcon-password) section under configuration/server-properties for more information on how to set an RCON password.

The SSH server runs on port `2222` inside the container.

??? tip "Tip: Exposing the SSH port"

    !!! warning "Security Implications"
        By default, publishing ports in Docker binds them to all network interfaces (`0.0.0.0`), making the SSH console accessible to any device that can reach your host machine.
        
        Since the SSH console grants **full administrative access** to your server, it is critical to use a strong [RCON password](../configuration/server-properties.md/#rcon-password). 
        
        If you wish to restrict access to the local machine only, refer to the [Docker documentation](https://docs.docker.com/engine/network/port-publishing/#publishing-ports) on binding to specific IP addresses (e.g., `127.0.0.1:2222:2222`).
      
        If SSH access is only intended for inter-container connections, consider **NOT** forwarding the port to the host machine, and putting the containers in a shared [Docker network](https://docs.docker.com/engine/network/#user-defined-networks).

    ```yaml title="compose.yaml"
    services:
      mc:
        ports:
          - '25565:25565'
          - '2222:2222'
    ```

## Connecting

Connecting should be as simple as running
```bash
ssh anyuser@127.0.0.1 -p 2222
```
and typing in the RCON password.

## Environment variables

| Environment Variable | Usage                     | Default |
| -------------------- | ------------------------- | ------- |
| `ENABLE_SSH`   | Enable remote SSH console | `false` |


## Example

```yaml title="compose.yaml"
services:
  mc:
    image: itzg/minecraft-server:latest
    pull_policy: daily
    tty: true
    stdin_open: true
    ports:
      - "25565:25565"
      - "2222:2222"
    environment:
      EULA: "TRUE"
      ENABLE_SSH: true
      RCON_PASSWORD_FILE: /run/secrets/rcon_pass
    volumes:
      # attach the relative directory 'data' to the container's /data path
      - ./data:/data
    
secrets:
  rcon_pass:
    file: ./rcon_password
```


================================================
FILE: docs/sending-commands/websocket.md
================================================
---
title: With WebSocket
---

With `WEBSOCKET_CONSOLE` set to `true`, logs can be streamed, and commands sent, over a WebSocket connection.
The API is available on `/console`.

## Password
A password must be supplied using the `Sec-WebSocket-Protocol` header. This is done by putting `mc-server-runner-ws-v1` in the first slot, and the password in the second. The password can be set with `RCON_PASSWORD` or `WEBSOCKET_PASSWORD`. The latter overwrites the former. Authentication can be disabled with `WEBSOCKET_DISABLE_AUTHENTICATION`.
??? Example "Examples"
    ```js title="JavaScript example"
    let socket = new WebSocket("http://localhost:80/websocket", ["mc-server-runner-ws-v1", "rcon-password"]);
    ```

## Allowed origins
A list of comma-separated allowed origins should be supplied with `WEBSOCKET_ALLOWED_ORIGINS`. Origin checking can be disabled with `WEBSOCKET_DISABLE_ORIGIN_CHECK`.

## Listen address
The listen address and port can be set with `WEBSOCKET_ADDRESS` (defaults to `0.0.0.0:80`), but it's recommended to listen on all interfaces when running in Docker.

## Log history
When a connection is established, the last 50 (by default, configurable with `WEBSOCKET_LOG_BUFFER_SIZE`) log lines are sent with a `logHistory` type message.

??? tip "Tip: Remember to forward the WebSocket port on the host"

    !!! warning "Security Implications"
        By default, publishing ports in Docker binds them to all network interfaces (`0.0.0.0`), making the WebSocket console accessible to any device that can reach your host machine.
        
        Since the WebSocket console grants **full administrative access** to your server, it is critical to use a strong [WebSocket password](#password) or [RCON password](../configuration/server-properties.md/#rcon-password).
      
        If you wish to restrict access to the local machine only, refer to the [Docker documentation](https://docs.docker.com/engine/network/port-publishing/#publishing-ports) on binding to specific IP addresses (e.g., `127.0.0.1:80:80`).
        
        If WebSocket access is only intended for inter-container connections, consider **NOT** forwarding the port to the host machine, and putting the containers in a shared [Docker network](https://docs.docker.com/engine/network/#user-defined-networks).

    ```yaml title="compose.yaml"
    services:
      mc:
        ports:
          - '25565:25565'
          - '80:80'
    ```

## Environment variables
| Environment Variable               | Usage                                                      | Default      |
| ---------------------------------- | ---------------------------------------------------------- | ------------ |
| `WEBSOCKET_CONSOLE`                | Allow remote shell over WebSocket                          | `false`      |
| `WEBSOCKET_ADDRESS`                | Bind address for WebSocket server                          | `0.0.0.0:80` |
| `WEBSOCKET_DISABLE_ORIGIN_CHECK`   | Disable checking if origin is trusted                      | `false`      |
| `WEBSOCKET_ALLOWED_ORIGINS`        | Comma-separated list of trusted origins                    | ` `          |
| `WEBSOCKET_PASSWORD`               | Password will be the same as RCON_PASSWORD if unset        | ` `          |
| `WEBSOCKET_DISABLE_AUTHENTICATION` | Disable WebSocket authentication                           | `false`      |
| `WEBSOCKET_LOG_BUFFER_SIZE`        | Number of log lines to save and send to connecting clients | `50`         |

## API Schema
```ts title="API Schema"
interface StdinMessage {
  type: "stdin";
  data: string;
}

interface StdoutMessage {
  type: "stdout";
  data: string;
}

interface StderrMessage {
  type: "stderr";
  data: string;
}

interface LogHistoryMessage {
  type: "logHistory";
  lines: string[];
}

interface AuthFailureMessage {
  type: "authFailure";
  reason: string;
}

// Messages sent from Client -> Server
export type ClientMessage = StdinMessage;

// Messages sent from Server -> Client
export type ServerMessage =
  | StdoutMessage
  | StderrMessage
  | LogHistoryMessage
  | AuthFailureMessage;
```


================================================
FILE: docs/types-and-platforms/index.md
================================================
# Server Types and Modpack Platforms

Server types can be selected by setting the `TYPE` environment variable to one of the types described in these sections.

The default server type is [the official software provided by Mojang](https://www.minecraft.net/en-us/download/server), which can be explicitly selected by setting `TYPE` to "VANILLA".

**From the sections to the left...**

The **modpack platforms** take a modpack identifier, file, etc and use that to select and download the appropriate version of a mod loader, such as Forge or Fabric, downloading declared mods/plugins, and apply any additional files. The modpack platforms are selected by setting `MODPACK_PLATFORM`; however, for ease of use and backward compatibility, the selection can be set in `TYPE` or `MOD_PLATFORM`.

The individual **server types** allow for selecting the mod loader / server type and specific versions of those. 

!!! important
    For all the server types, the `VERSION` environment variable is used to declare the Minecraft version itself, such as 1.19.4. Each server type will have specific variables for qualifying their version in addition to the Minecraft version.


================================================
FILE: docs/types-and-platforms/mod-platforms/auto-curseforge.md
================================================
# Auto CurseForge

To manage a CurseForge modpack automatically with upgrade support, pinned or latest version tracking, set `MODPACK_PLATFORM`, `MOD_PLATFORM` or `TYPE` to "AUTO_CURSEFORGE". The appropriate mod loader (Forge / Fabric) version will be automatically installed as declared by the modpack. This mode will also take care of cleaning up unused files installed by previous versions of the modpack, but world data is never auto-removed.

## API Key

!!! warning "CurseForge API key usage"

    A CurseForge API key is **required** to use this feature. Go to their [developer console](https://console.curseforge.com/), generate an API key, and set the environment variable `CF_API_KEY`.

    When entering your API Key in a docker compose file you will need to escape any `$` character with a second `$`. Refer to [this compose file reference section](https://docs.docker.com/compose/compose-file/compose-file-v3/#variable-substitution) for more information.

    Example if your key is `$11$22$33aaaaaaaaaaaaaaaaaaaaaaaaaa`:
    ```yaml title="compose.yaml"
    environment:
      CF_API_KEY: '$$11$$22$$33aaaaaaaaaaaaaaaaaaaaaaaaaa'
    ```
    If you use `docker run` you will need to make sure to use single quotes:

    ```shell
    docker run ... -e CF_API_KEY='$11$22$33aaaaaaaaaaaaaaaaaaaaaaaaaa'
    ```

    To avoid exposing the API key, it is highly recommended to use a `.env` file, which is [loaded automatically by docker compose](https://docs.docker.com/compose/environment-variables/set-environment-variables/#substitute-with-an-env-file). You **do not** need to escape `$`'s with a second `$` in the `.env` file **as long as the key is wrapped in single quotes**.

    ```title=".env"
    CF_API_KEY='$11$22$33aaaaaaaaaaaaaaaaaaaaaaaaaa'
    ```

    The variable should to be referenced from the compose file, such as:

    ```yaml title="compose.yaml"
    environment:
      CF_API_KEY: ${CF_API_KEY}
    ```

    The .env file should be placed in the same directory as your compose file like so:

    ```
    minecraft-server/
    ├── .env
    ├── compose.yaml
    ├── data/
    ```

    To use the equivalent with `docker run` you need to specify the `.env` file explicitly:
    ```shell
    docker run --env-file=.env itzg/minecraft-server
    ```

    Alternately you can use [docker secrets](https://docs.docker.com/compose/how-tos/use-secrets/) with a `CF_API_KEY_FILE` environment variable:
    ```yaml title="compose.yaml"
    service:
      environment:
        CF_API_KEY_FILE: /run/secrets/cf_api_key
      secrets:
        - cf_api_key

    secrets:
      cf_api_key:
        file: cf_api_key.secret
    ```


!!! note
    Be sure to use the appropriate [image tag for the Java version compatible with the modpack](../../versions/java.md).

    Most modpacks require a good amount of memory, so it best to set `MEMORY` to at least "4G" since the default is only 1 GB.

## Usage

Use one of the following to specify the modpack to install:

Pass a page URL to the modpack or a specific file with `CF_PAGE_URL` such as the modpack page "https://www.curseforge.com/minecraft/modpacks/all-the-mods-8" or a specific file "https://www.curseforge.com/minecraft/modpacks/all-the-mods-8/files/4248390".

!!! example "Using CF_PAGE_URL"

    ```yaml title="Using compose.yaml"
    environment:
      # ...
      MODPACK_PLATFORM: AUTO_CURSEFORGE
      # allocate from https://console.curseforge.com/ and set in .env file
      CF_API_KEY: ${CF_API_KEY}
      CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/all-the-mods-8
    ```

    ```title="Using docker run"
    docker run -e CF_API_KEY=${CF_API_KEY} -e TYPE=AUTO_CURSEFORGE -e CF_PAGE_URL=https://www.curseforge.com/minecraft/modpacks/all-the-mods-8
    ```

Instead of a URL, the modpack slug can be provided as `CF_SLUG`. The slug is the short identifier visible in the URL after "/modpacks/", such as

![cf-slug](../../img/cf-slug.png)

!!! example "Using CF_SLUG"

    ```yaml title="Using compose.yaml"
    environment:
      # ...
      MODPACK_PLATFORM: AUTO_CURSEFORGE
      # allocate from https://console.curseforge.com/ and set in .env file
      CF_API_KEY: ${CF_API_KEY}
      CF_SLUG: all-the-mods-8
    ```

    ```title="Using docker run"
    docker run -e CF_API_KEY=${CF_API_KEY} -e TYPE=AUTO_CURSEFORGE -e CF_SLUG=all-the-mods-8
    ```

### Pinning modpack and mod loader versions

The latest modpack file and its associated mod loader will be located and installed by default on startup (including automatic upgrading of both on subsequent startups, if a later version is found on CurseForge). If a specific version is desired instead, you can use one of the following options. With any of these options **do not select a server file** -- they lack the required manifest and defeat the ability to consistently automate startup.

- Use `CF_PAGE_URL`, but include the full URL to a specific file
- Set `CF_FILE_ID` to the numerical file ID
- Specify a substring to match the desired filename with `CF_FILENAME_MATCHER`

The following shows where to get the URL to the specific file and also shows where the file ID is located:

![cf-file-id](../../img/cf-file-id.png)

The following examples all refer to version 1.0.7 of ATM8:

```yaml
  CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/all-the-mods-8/files/4248390
```

```yaml
  CF_SLUG: all-the-mods-8
  CF_FILE_ID: "4248390"
```

```yaml
  CF_SLUG: all-the-mods-8
  CF_FILENAME_MATCHER: 1.0.7
```

Pinning modpack version also pins the mod loader (to the version specified by the modpack). Mod loader version cannot be pinned independently of the modpack.

### Custom modloader versions

By default, AUTO_CURSEFORGE will use the exact modloader version declared by the modpack. However, you can override the modloader version by setting the following environment variable:

- `CF_MOD_LOADER_VERSION`: Override the mod loader version (e.g., `43.4.22`)

!!! example "Override mod loader version"

    ```yaml
    environment:
      MODPACK_PLATFORM: AUTO_CURSEFORGE
      CF_API_KEY: ${CF_API_KEY}
      CF_SLUG: all-the-mods-8
      CF_MOD_LOADER_VERSION: "43.4.22"
    ```

    ```title="Using docker run"
    docker run -e CF_MOD_LOADER_VERSION=43.4.22 -e CF_SLUG=my-fabric-pack ...
    ```

!!! warning "Compatibility"

    Using a custom modloader version that differs significantly from what the modpack was designed for may cause compatibility issues. Use this feature carefully and test thoroughly.

## Manual Downloads

For mod, modpacks, and world files that are not allowed for automated download, the container path `/downloads` can be attached and matching files will be retrieved from there. The subdirectories `mods`, `modpacks`, and `worlds` will also be checked accordingly. To change the source location of downloaded files, set `CF_DOWNLOADS_REPO` to an existing container path. To disable this feature, set `CF_DOWNLOADS_REPO` to an empty string.

!!! warning "Download using a browser"

    It's important to use a browser to download the files listed for manual download. If your Docker host is running without a graphical interface, then you can use `scp` or similar to transfer the files to it.

!!! example

    Assuming Docker compose is being used:

    1. Create a directory next to the `compose.yaml` file. The name doesn't matter, but "downloads" is the common convention
    2. From the "Mods Need Download" output, visit the download page of each, click on the file download and save that file into the directory created in the previous step
    3. Add a host directory mount to the volumes section where the container path **must be** `/downloads`. The snippet below shows how that will look
    4. Re-run `docker compose up -d` to apply the changes

    ```yaml
        volumes:
          ./downloads:/downloads
    ```

## Unpublished Modpacks

If you wish to use an unpublished modpack zip, set the container path to the file in `CF_MODPACK_ZIP`. Similarly, the container path to a modpack manifest JSON can be passed to `CF_MODPACK_MANIFEST`.  In either case, **the modpack slug or page URL must still be provided**.

!!! example

    ```yaml
    services:
      mc:
        image: itzg/minecraft-server:latest
        pull_policy: daily
        environment:
          EULA: true
          MODPACK_PLATFORM: AUTO_CURSEFORGE
          # allocate from https://console.curseforge.com/ and set in .env file
          CF_API_KEY: ${CF_API_KEY}
          CF_MODPACK_MANIFEST: /manifests/manifest.json
          CF_SLUG: "custom"
        volumes:
          - ./manifests:/manifests:ro
    ```

    where an exported manifest file should look like:

    ```json
    {
      "minecraft": {
        "version": "1.20.4",
        "modLoaders": [
          {
            "id": "fabric-0.15.3",
            "primary": true
          }
        ]
      },
      "manifestType": "minecraftModpack",
      "manifestVersion": 1,
      "name": "Custom",
      "author": "",
      "files": [
        {
          "projectID": 351725,
          "fileID": 4973035,
          "required": true
        },
        {
          "projectID": 306612,
          "fileID": 5010374,
          "required": true
        }
      ],
      "overrides": "overrides"
    }
    ```

## Exclude client mods

Quite often there are mods that need to be excluded, such as ones that did not properly declare as a client mod via the file's game versions. Similarly, there are some mods that are incorrectly tagged as client only. The following describes some options to exclude/include mods:

Mods can be excluded by passing a comma or space delimited list of **project** slugs or IDs via `CF_EXCLUDE_MODS`. Similarly, there are some mods that are incorrectly tagged as client only. For those, pass the **project** slugs or IDs via `CF_FORCE_INCLUDE_MODS`. These lists will be combined with the content of the exclude/include file, if given. Alternatively, all mods can be excluded by setting `CF_EXCLUDE_ALL_MODS` to `true`

!!! note
    `CF_FORCE_INCLUDE_MODS` will not download additional mods.

    For additional mods, refer to [the `CURSEFORGE_FILES` variable](../../mods-and-plugins/curseforge-files.md).

A mod's project ID can be obtained from the right hand side of the project page:
![cf-project-id](../../img/cf-project-id.png)

For more complex scenarios, global and per modpack exclusions can be declared in a container-accessible JSON file and referenced with `CF_EXCLUDE_INCLUDE_FILE`. By default, [the file bundled with the image](https://raw.githubusercontent.com/itzg/docker-minecraft-server/master/files/cf-exclude-include.json) will be used, but can be disabled by setting this to an empty string. The schema of this file [is documented here](https://github.com/itzg/mc-image-helper#excludeinclude-file-schema).

If needing to iterate on the options above, set `CF_FORCE_SYNCHRONIZE` to "true" to ensure the exclude/includes are re-evaluated.

!!! important
    These options are provided to empower you to get your server up and running quickly. Please help out by reporting an issue with the respective mod project. Ideally mod developers should [use correct registrations for one-sided client mods](https://docs.minecraftforge.net/en/latest/concepts/sides/#writing-one-sided-mods). Understandably, those code changes may be non-trivial, so mod authors can also add "Client" to the game versions when publishing.

!!! tip "Embedded comments"

    Comments can be embedded in the list using the `#` character.

    ```yaml
          CF_EXCLUDE_MODS: |
            # Exclude client-side mods not published correctly
            creative-core
            default-options
    ```

## Excluding Overrides Files

Modpack zip files typically include an `overrides` subdirectory that may contain config files, world data, and extra mod files. All of those files will be extracted into the `/data` path of the container. If any of those files, such as incompatible mods, need to be excluded from extraction, then the `CF_OVERRIDES_EXCLUSIONS` variable can be set with a comma or newline delimited list of ant-style paths ([see below](#ant-style-paths)) to exclude, relative to the overrides (or `/data`) directory.

### Ant-style paths

Ant-style paths can include the following globbing/wildcard symbols:

| Symbol | Behavior                                                |
|--------|---------------------------------------------------------|
| `*`    | Matches zero, one, or many characters except a slash    |
| `**`   | Matches zero, one, or many characters including slashes |
| `?`    | Matches one character                                   |

!!! example

    The following compose `environment` entries show how to exclude Iris and Sodium mods from the overrides

    ```yaml
      CF_OVERRIDES_EXCLUSIONS: mods/iris*.jar,mods/sodium*.jar
    ```

    or using newline delimiter, which improves maintainability

    ```yaml
      CF_OVERRIDES_EXCLUSIONS: |
        mods/iris*.jar
        mods/sodium*.jar
    ```

## World/Level Data

Some modpacks come with world/save data via a worlds file and/or the overrides provided with the modpack. Either approach can be selected to set the `LEVEL` to the resulting saves directory by setting `CF_SET_LEVEL_FROM` to either:

- `WORLD_FILE`
- `OVERRIDES`

## Ignore missing files

Some mods use temporary files from the modpack and delete them when finished. Others will patch themselves and "disable" the original mod jar, such as gregtech. In order to avoid the installer from detecting the absent file(s) and re-installing, those files can be ignored by passing a comma, newline delimited list, or a file globbing pattern to `CF_IGNORE_MISSING_FILES`.

!!! hint

    A warning log will indicate what files were found to be missing from the previous installation run, such as

    ```
    Re-installing due to missing files from modpack: [mods/gregtech-2.6.2-beta.jar]
    ```

!!! example

    In a Compose file
    ```yaml
      environment:
        CF_IGNORE_MISSING_FILES: |
          mods/gregtech-2.6.2-beta.jar
          mods/*.jar
    ```


## Extra options

Other configuration available:

- `CF_PARALLEL_DOWNLOADS` (default is 4): specify how many parallel mod downloads to perform
- `CF_OVERRIDES_SKIP_EXISTING` (default is false): if set, files in the overrides that already exist in the data directory are skipped. **NOTE** world data is always skipped, if present.
- `CF_FORCE_REINSTALL_MODLOADER` (default is false): this can be set to `true` to force the modpack's declared modloader, such as Forge, to be reinstalled. This
Download .txt
gitextract_eezdj074/

├── .dockerignore
├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   ├── config.yml
│   │   └── enhancement.yml
│   ├── dependabot.yml
│   ├── release.yml
│   └── workflows/
│       ├── auto-release.yml
│       ├── build.yml
│       ├── discord.yml
│       ├── issue-label.yml
│       ├── stale-check.yml
│       └── verify-pr.yml
├── .gitignore
├── .readthedocs.yaml
├── Dockerfile
├── LICENSE
├── README.md
├── build/
│   ├── alpine/
│   │   ├── install-packages.sh
│   │   └── setup-user.sh
│   ├── ol/
│   │   ├── install-packages.sh
│   │   └── setup-user.sh
│   ├── run.sh
│   └── ubuntu/
│       ├── install-packages.sh
│       └── setup-user.sh
├── compose-dev.yml
├── compose-docs.yml
├── docker-compose.yml
├── docs/
│   ├── Dockerfile
│   ├── configuration/
│   │   ├── auto-rcon-commands.md
│   │   ├── interpolating.md
│   │   ├── jvm-options.md
│   │   ├── misc-options.md
│   │   └── server-properties.md
│   ├── css/
│   │   └── extra.css
│   ├── data-directory.md
│   ├── img/
│   │   ├── .gitignore
│   │   ├── Minecraft server containment.xml
│   │   └── docs-banner.txt
│   ├── index.md
│   ├── misc/
│   │   ├── autopause-autostop/
│   │   │   ├── autopause.md
│   │   │   └── autostop.md
│   │   ├── autoscale/
│   │   │   └── autoscale.md
│   │   ├── building.md
│   │   ├── contributing/
│   │   │   ├── development.md
│   │   │   └── docs.md
│   │   ├── deployment/
│   │   │   └── index.md
│   │   ├── examples.md
│   │   ├── healthcheck.md
│   │   ├── log4j.md
│   │   ├── raspberrypi.md
│   │   ├── related-projects.md
│   │   ├── troubleshooting.md
│   │   └── world-data.md
│   ├── mods-and-plugins/
│   │   ├── curseforge-files.md
│   │   ├── index.md
│   │   ├── modrinth.md
│   │   ├── packwiz.md
│   │   └── spiget.md
│   ├── requirements.txt
│   ├── sending-commands/
│   │   ├── commands.md
│   │   ├── ssh.md
│   │   └── websocket.md
│   ├── types-and-platforms/
│   │   ├── index.md
│   │   ├── mod-platforms/
│   │   │   ├── auto-curseforge.md
│   │   │   ├── curseforge.md
│   │   │   ├── ftb.md
│   │   │   ├── gtnh.md
│   │   │   └── modrinth-modpacks.md
│   │   └── server-types/
│   │       ├── bukkit-spigot.md
│   │       ├── fabric.md
│   │       ├── forge.md
│   │       ├── hybrids.md
│   │       ├── others.md
│   │       ├── paper.md
│   │       └── quilt.md
│   ├── variables.md
│   └── versions/
│       ├── java.md
│       └── minecraft.md
├── examples/
│   ├── .gitignore
│   ├── README.md
│   ├── apply-extra-configs/
│   │   ├── compose.yml
│   │   └── shared-configs/
│   │       └── LuckPerms/
│   │           └── config.yml
│   ├── auto-curseforge/
│   │   ├── aof7/
│   │   │   └── docker-compose.yml
│   │   ├── atm10/
│   │   │   └── docker-compose.yml
│   │   ├── atm8/
│   │   │   ├── docker-compose.yml
│   │   │   └── filebrowser.json
│   │   ├── atm9/
│   │   │   └── docker-compose.yml
│   │   ├── craftoria/
│   │   │   └── docker-compose.yml
│   │   ├── fabric-custom-loader/
│   │   │   └── docker-compose.yml
│   │   ├── ftb-evolution/
│   │   │   └── compose.yaml
│   │   ├── modpack-manifest/
│   │   │   ├── docker-compose.yml
│   │   │   └── manifests/
│   │   │       └── manifest.json
│   │   ├── one-block-modded/
│   │   │   ├── .gitignore
│   │   │   └── docker-compose.yml
│   │   ├── pixelmon/
│   │   │   └── docker-compose.yml
│   │   ├── prominence2/
│   │   │   └── docker-compose.yml
│   │   ├── rad2/
│   │   │   └── compose.yaml
│   │   ├── skyfactory4/
│   │   │   └── compose.yml
│   │   ├── skyfactory5/
│   │   │   └── compose.yml
│   │   ├── using-excludes/
│   │   │   └── docker-compose.yml
│   │   ├── valhesia5/
│   │   │   └── docker-compose.yml
│   │   └── vault-hunters-1-18-2/
│   │       └── docker-compose.yml
│   ├── autopause/
│   │   └── compose.yml
│   ├── autostop/
│   │   └── compose.yml
│   ├── bentobox/
│   │   └── compose.yml
│   ├── bettermc/
│   │   └── docker-compose.yml
│   ├── canyon/
│   │   └── compose.yml
│   ├── cleanroom/
│   │   └── compose.yml
│   ├── curseforge-files/
│   │   └── docker-compose.yml
│   ├── docker-compose-big.yml
│   ├── docker-compose-curseforge-atm7.yaml
│   ├── docker-compose-curseforge.yml
│   ├── docker-compose-forge-bettermcplus
│   ├── docker-compose-forge.yml
│   ├── docker-compose-magma.yml
│   ├── docker-compose-mods-mount.yml
│   ├── docker-compose-rconcmd.yml
│   ├── docker-compose-simple.yml
│   ├── docker-compose-spongeforge.yml
│   ├── docker-compose-world-download.yml
│   ├── docker-compose.yml
│   ├── fabric/
│   │   └── compose.yml
│   ├── fabric-cardboard/
│   │   └── compose.yml
│   ├── ftba/
│   │   ├── compose.yml
│   │   └── stoneblock4/
│   │       └── compose.yml
│   ├── generic-pack/
│   │   └── rlcraft/
│   │       └── compose.yml
│   ├── geyser/
│   │   └── docker-compose.yml
│   ├── gtnh/
│   │   ├── docker-compose-type-gtnh.yaml
│   │   └── docker-compose.yaml
│   ├── jline/
│   │   └── docker-compose.yml
│   ├── k8s/
│   │   ├── using-statefulset.yml
│   │   └── vanilla-deployment.yml
│   ├── ketting/
│   │   └── docker-compose.yml
│   ├── lazymc/
│   │   └── docker_compose.yml
│   ├── lazytainer/
│   │   └── docker_compose.yml
│   ├── mc-router-autoscale/
│   │   ├── compose-minimal.yml
│   │   └── compose.yml
│   ├── modrinth/
│   │   ├── bmc4/
│   │   │   └── compose.yml
│   │   ├── local-modpack/
│   │   │   └── docker-compose.yml
│   │   ├── modrinth-modpack/
│   │   │   └── compose.yml
│   │   ├── modrinth-paper/
│   │   │   └── compose.yml
│   │   ├── modrinth-projects/
│   │   │   └── compose.yml
│   │   └── version-from-modrinth-projects/
│   │       └── compose.yml
│   ├── mods-file/
│   │   ├── docker-compose.yml
│   │   └── mods.txt
│   ├── mohist/
│   │   └── compose.yml
│   ├── multi-project/
│   │   ├── README.md
│   │   ├── dbs/
│   │   │   └── docker-compose.yml
│   │   └── servers/
│   │       ├── docker-compose.yml
│   │       ├── mc-plugins/
│   │       │   └── LuckPerms/
│   │       │       └── config.yml
│   │       ├── velocity-config/
│   │       │   └── velocity.toml
│   │       └── waterfall-config/
│   │           ├── config.yml
│   │           └── waterfall.yml
│   ├── multiline-motd/
│   │   └── docker-compose.yml
│   ├── neoforge/
│   │   └── docker-compose.yml
│   ├── ngrok/
│   │   └── compose.yml
│   ├── optimized-server-config/
│   │   ├── README.md
│   │   └── docker-compose.yml
│   ├── packwiz/
│   │   └── compose.yml
│   ├── paper/
│   │   ├── compose.yml
│   │   ├── paper-build-plugins/
│   │   │   ├── Dockerfile
│   │   │   ├── docker-compose.yml
│   │   │   └── plugins/
│   │   │       ├── .gitignore
│   │   │       └── README.md
│   │   └── paper-proxy-protocol/
│   │       ├── config/
│   │       │   └── paper-global.yml
│   │       └── docker-compose.yml
│   ├── proxied/
│   │   └── compose.yml
│   ├── quilt/
│   │   └── docker-compose.yml
│   ├── rlcraft/
│   │   └── docker-compose.yml
│   ├── simple-voice-chat/
│   │   ├── fabric-compose.yaml
│   │   ├── neoforge-compose.yaml
│   │   └── paper-compose.yaml
│   ├── skript/
│   │   └── docker-compose.yml
│   ├── spiget/
│   │   └── docker-compose.yml
│   ├── spigot/
│   │   └── docker-compose.yml
│   ├── tailscale/
│   │   └── compose.yml
│   ├── valhelsia2/
│   │   └── docker-compose.yml
│   └── vanilla-tweaks/
│       ├── docker-compose.yml
│       ├── vanillatweaks-craftingtweaks.json
│       ├── vanillatweaks-datapacks.json
│       └── vanillatweaks-resourcepacks.json
├── files/
│   ├── cf-exclude-include.json
│   ├── knockd-config.cfg
│   ├── modrinth-exclude-include.json
│   ├── nanolimbo-settings-patch.json
│   ├── property-definitions.json
│   └── server.properties
├── images.json
├── kustomize/
│   ├── README.md
│   └── base/
│       ├── kustomization.yml
│       ├── service.yml
│       └── statefulset.yml
├── notes/
│   ├── .gitignore
│   ├── Minecraft server containment.xml
│   └── rbac-processing.mmd
├── renovate.json5
├── scripts/
│   ├── auto/
│   │   ├── autopause-daemon.sh
│   │   ├── autopause-fcns.sh
│   │   ├── autostop-daemon.sh
│   │   ├── pause.sh
│   │   ├── rcon-cmds-daemon.sh
│   │   ├── resume.sh
│   │   └── stop.sh
│   ├── shims/
│   │   ├── mc-health
│   │   ├── mc-send-to-console
│   │   └── mcstatus
│   ├── start
│   ├── start-autopause
│   ├── start-autostop
│   ├── start-configuration
│   ├── start-deployArcLight
│   ├── start-deployAutoCF
│   ├── start-deployBukkitSpigot
│   ├── start-deployCF
│   ├── start-deployCanyon
│   ├── start-deployCrucible
│   ├── start-deployCustom
│   ├── start-deployFTBA
│   ├── start-deployFabric
│   ├── start-deployFolia
│   ├── start-deployForge
│   ├── start-deployGTNH
│   ├── start-deployKetting
│   ├── start-deployLeaf
│   ├── start-deployLimbo
│   ├── start-deployMagma
│   ├── start-deployMagmaMaintained
│   ├── start-deployModrinth
│   ├── start-deployMohist
│   ├── start-deployNanoLimbo
│   ├── start-deployNeoForge
│   ├── start-deployPaper
│   ├── start-deployPoseidon
│   ├── start-deployPufferfish
│   ├── start-deployPurpur
│   ├── start-deployQuilt
│   ├── start-deploySpongeVanilla
│   ├── start-deployVanilla
│   ├── start-finalExec
│   ├── start-rconcmds
│   ├── start-setupDatapack
│   ├── start-setupEnvVariables
│   ├── start-setupModpack
│   ├── start-setupMounts
│   ├── start-setupRbac
│   ├── start-setupServerProperties
│   ├── start-setupWorld
│   ├── start-spiget
│   └── start-utils
├── tests/
│   ├── .gitignore
│   ├── fulltests/
│   │   ├── multi-part-motd/
│   │   │   └── docker-compose.yml
│   │   ├── test.sh
│   │   └── vanilla-latest/
│   │       └── docker-compose.yml
│   ├── setuponlytests/
│   │   ├── auto_curseforge/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── auto_curseforge_file/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── cf_files/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── listing.txt
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── conflicting_world_for_spigot_server/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── conflicting_world_for_vanilla_server/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── curseforge/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── defaults/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── generic-packs/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   └── verify.sh
│   │   ├── generic-packs-prefix/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── icon-file-exact/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── icon-file-scale/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   └── verify.sh
│   │   ├── icon-gif-multiframe/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── icon-png-atscale/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── icon-png-scale/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   └── verify.sh
│   │   ├── modrinth/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── mounts-custom/
│   │   │   ├── custom/
│   │   │   │   ├── config/
│   │   │   │   │   └── test.json
│   │   │   │   ├── mods/
│   │   │   │   │   └── mod.jar
│   │   │   │   └── plugins/
│   │   │   │       └── plugin.jar
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   └── verify.sh
│   │   ├── nanolimbo/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── ops_from_scratch/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── packwiz/
│   │   │   ├── docker-compose.yml
│   │   │   ├── fake.jar
│   │   │   ├── require.sh
│   │   │   ├── verify.sh
│   │   │   └── web/
│   │   │       ├── index.toml
│   │   │       ├── mods/
│   │   │       │   └── architectury-api.pw.toml
│   │   │       └── pack.toml
│   │   ├── pufferfish/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── quilt/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── spiget/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── spigot_world_for_spigot_server/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── spigot_world_for_vanilla_server/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── spongevanilla_version_compare/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── test.sh
│   │   ├── vanilla_world_for_spigot_server/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── vanilla_world_for_vanilla_server/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── vanillatweaks_file/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   ├── verify.sh
│   │   │   ├── vt-craftingtweaks.json
│   │   │   ├── vt-datapacks.json
│   │   │   └── vt-resourcepacks.json
│   │   ├── vanillatweaks_sharecode/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── whitelist_from_scratch/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── world_from_tar/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   └── verify.sh
│   │   ├── world_from_tarbz2/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   ├── verify.sh
│   │   │   └── worlds/
│   │   │       └── world-for-testing.tar.bz2
│   │   ├── world_from_targz/
│   │   │   ├── docker-compose.yml
│   │   │   └── verify.sh
│   │   ├── world_from_tarzst/
│   │   │   ├── docker-compose.yml
│   │   │   ├── require.sh
│   │   │   ├── verify.sh
│   │   │   └── worlds/
│   │   │       └── world-for-testing.tar.zst
│   │   └── world_from_zip/
│   │       ├── docker-compose.yml
│   │       └── verify.sh
│   └── test.sh
└── zensical.toml
Condensed preview — 370 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (690K chars).
[
  {
    "path": ".dockerignore",
    "chars": 47,
    "preview": "data\ntestdata\nexamples\nk8s-examples\n.idea\n.git\n"
  },
  {
    "path": ".editorconfig",
    "chars": 64,
    "preview": "[start-*]\nindent_size = 2\nindent_style = space\nend_of_line = lf\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 86,
    "preview": "github: itzg\ncustom:\n  - https://www.buymeacoffee.com/itzg\n  - https://paypal.me/itzg\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.yml",
    "chars": 1905,
    "preview": "name: Bug Report\ndescription: File a bug report\nlabels:\n  - bug\n  - status/needs triage\nbody:\n  - type: markdown\n    att"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 269,
    "preview": "contact_links:\n  - name: Ask a question in discussions\n    url: https://github.com/itzg/docker-minecraft-server/discussi"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/enhancement.yml",
    "chars": 830,
    "preview": "name: Enhancement Request\ndescription: Request an enhancement\nlabels:\n  - enhancement\n  - status/needs triage\nbody:\n  - "
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 443,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n  "
  },
  {
    "path": ".github/release.yml",
    "chars": 318,
    "preview": "changelog:\n  exclude:\n    authors:\n      - dependabot\n      - renovate\n  categories:\n    - title: Enhancements\n      lab"
  },
  {
    "path": ".github/workflows/auto-release.yml",
    "chars": 316,
    "preview": "name: Auto release\non:\n  schedule:\n    - cron: \"0 14 * * *\"\n  workflow_dispatch:\njobs:\n  auto-release:\n    runs-on: ubun"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 8774,
    "preview": "name: Build and Publish\non:\n  push:\n    branches:\n      - master\n      - test/**\n    tags:\n      - \"[0-9]+.[0-9]+.[0-9]+"
  },
  {
    "path": ".github/workflows/discord.yml",
    "chars": 1386,
    "preview": "name: Discord notifications\n\non:\n  release:\n    types:\n      - published\n  workflow_run:\n    workflows: [\"Build and Publ"
  },
  {
    "path": ".github/workflows/issue-label.yml",
    "chars": 332,
    "preview": "name: Issues notify\n\non:\n  issues:\n    types:\n      - opened\n      - labeled\n      - unlabeled\n      - closed\n\njobs:\n  n"
  },
  {
    "path": ".github/workflows/stale-check.yml",
    "chars": 681,
    "preview": "name: Stale Check\n\non:\n  schedule:\n    - cron: 0 2 * * *\n\njobs:\n  check:\n    runs-on: ubuntu-22.04\n    permissions:\n    "
  },
  {
    "path": ".github/workflows/verify-pr.yml",
    "chars": 3204,
    "preview": "name: Verify PR\non:\n  pull_request:\n    branches:\n      - master\n    paths-ignore:\n      - \"*.md\"\n      - \"docs/**\"\n    "
  },
  {
    "path": ".gitignore",
    "chars": 75,
    "preview": ".vscode\n/data/\n/.idea/\n*.iml\n/gh-md-toc\npersonal-build-and-develop.*\nsite/\n"
  },
  {
    "path": ".readthedocs.yaml",
    "chars": 487,
    "preview": "version: 2\n\nbuild:\n  os: ubuntu-24.04\n  tools:\n    python: \"3.14\"\n  jobs:\n    # We recommend using a requirements file f"
  },
  {
    "path": "Dockerfile",
    "chars": 4096,
    "preview": "ARG BASE_IMAGE=eclipse-temurin:25-jre\nFROM ${BASE_IMAGE}\n\n# hook into docker BuildKit --platform support\n# see https://d"
  },
  {
    "path": "LICENSE",
    "chars": 11323,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "README.md",
    "chars": 2461,
    "preview": "[![Docker Pulls](https://img.shields.io/docker/pulls/itzg/minecraft-server.svg?logo=docker)](https://hub.docker.com/r/it"
  },
  {
    "path": "build/alpine/install-packages.sh",
    "chars": 935,
    "preview": "#!/bin/sh\n\nset -e\nset -o pipefail\n\n# Install necessary packages\n# shellcheck disable=SC2086\napk add --no-cache -U \\\n    "
  },
  {
    "path": "build/alpine/setup-user.sh",
    "chars": 119,
    "preview": "#!/bin/sh\n\nset -e\n\naddgroup -g 1000 minecraft\nadduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft\n"
  },
  {
    "path": "build/ol/install-packages.sh",
    "chars": 2311,
    "preview": "#!/bin/bash\n\nexport TARGET\n\nset -euo pipefail\n\nos_major_version=$(awk -F'[= .\"]+' '/^VERSION_ID=/{ print $2 }' /etc/os-r"
  },
  {
    "path": "build/ol/setup-user.sh",
    "chars": 113,
    "preview": "groupadd --gid 1000 minecraft\nuseradd --system --shell /bin/false --uid 1000 -g minecraft --home /data minecraft\n"
  },
  {
    "path": "build/run.sh",
    "chars": 132,
    "preview": "#!/bin/sh\n\nset -e\n\ndistro=$(cat /etc/os-release | grep -E \"^ID=\" | cut -d= -f2 | sed -e 's/\"//g')\n\n\"$(dirname \"$0\")/${di"
  },
  {
    "path": "build/ubuntu/install-packages.sh",
    "chars": 1132,
    "preview": "#!/bin/bash\n\nexport TARGET\n\nset -euo pipefail\n\n# Update and install packages\napt-get update\n# shellcheck disable=SC2086\n"
  },
  {
    "path": "build/ubuntu/setup-user.sh",
    "chars": 195,
    "preview": "#!/bin/sh\n\nset -e\n\nif id ubuntu > /dev/null 2>&1; then\n  deluser ubuntu\nfi\n\naddgroup --gid 1000 minecraft\nadduser --syst"
  },
  {
    "path": "compose-dev.yml",
    "chars": 234,
    "preview": "services:\n  mc-dev:\n    build:\n      context: .\n    environment:\n      EULA: true\n    volumes:\n      - ./scripts:/image/"
  },
  {
    "path": "compose-docs.yml",
    "chars": 379,
    "preview": "# This composition can be used to serve up the rendered mkdocs for local authoring.\n#\n# docker compose -f compose-docs.y"
  },
  {
    "path": "docker-compose.yml",
    "chars": 245,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    environment:\r\n      EULA: \"true\"\r\n    ports:\r\n      - \"25565:255"
  },
  {
    "path": "docs/Dockerfile",
    "chars": 141,
    "preview": "FROM zensical/zensical\n\nRUN --mount=target=/build/requirements.txt,source=docs/requirements.txt \\\n    pip install -r /bu"
  },
  {
    "path": "docs/configuration/auto-rcon-commands.md",
    "chars": 1859,
    "preview": "\r\n# Auto-execute RCON commands\r\n\r\nRCON commands can be configured to execute when the server starts, a client connects, "
  },
  {
    "path": "docs/configuration/interpolating.md",
    "chars": 5193,
    "preview": "---\r\ntitle: Modifying config files\r\n---\r\n\r\n## Replacing variables inside configs\r\n\r\nSometimes you have mods or plugins t"
  },
  {
    "path": "docs/configuration/jvm-options.md",
    "chars": 4842,
    "preview": "# JVM Options\n\n## Memory Limit\n\nBy default, the image declares an initial and maximum Java memory-heap limit of 1 GB. Th"
  },
  {
    "path": "docs/configuration/misc-options.md",
    "chars": 11628,
    "preview": "## Running with a custom server JAR\n\nIf you would like to run a custom server JAR, set `-e TYPE=CUSTOM` and pass the cus"
  },
  {
    "path": "docs/configuration/server-properties.md",
    "chars": 28158,
    "preview": "To unify management of the Minecraft server container, all known [`server.properties`](https://minecraft.wiki/w/Server.p"
  },
  {
    "path": "docs/css/extra.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/data-directory.md",
    "chars": 3742,
    "preview": "Everything the container manages is located under the **container's** `/data` path, as shown here:\r\n\r\n![](img/level-vs-w"
  },
  {
    "path": "docs/img/.gitignore",
    "chars": 7,
    "preview": "/.*.bkp"
  },
  {
    "path": "docs/img/Minecraft server containment.xml",
    "chars": 947,
    "preview": "<mxfile userAgent=\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.29"
  },
  {
    "path": "docs/img/docs-banner.txt",
    "chars": 179,
    "preview": "Generated at https://textcraft.net/\r\n\r\nLine 1:\r\n\"Click here for\"\r\nSmall, none, Minecraftia\r\n\r\nLine 2:\r\n\"Documentation\"\r\n"
  },
  {
    "path": "docs/index.md",
    "chars": 4329,
    "preview": "# Intro\r\n\r\n[![Docker Pulls](https://img.shields.io/docker/pulls/itzg/minecraft-server.svg)](https://hub.docker.com/r/itz"
  },
  {
    "path": "docs/misc/autopause-autostop/autopause.md",
    "chars": 5499,
    "preview": "# Auto-Pause\r\n\r\n!!! important\r\n\r\n    As of [1.21.2](https://minecraft.wiki/w/Java_Edition_1.21.2) it is not recommend to"
  },
  {
    "path": "docs/misc/autopause-autostop/autostop.md",
    "chars": 1906,
    "preview": "# Auto-Stop\r\n\r\nAn option to stop the server after a specified time has been added for niche applications (e.g. billing s"
  },
  {
    "path": "docs/misc/autoscale/autoscale.md",
    "chars": 1619,
    "preview": "\n# Autoscaling (sleep when idle)\n\nAutoscaling (sometimes called *sleeping*, *scale to zero* or *wake on join*) is the pa"
  },
  {
    "path": "docs/misc/building.md",
    "chars": 3896,
    "preview": "\n## Simple image additions\n\nYou can easily build upon the base image using an inline Dockerfile.\n\n```yaml title=\"compose"
  },
  {
    "path": "docs/misc/contributing/development.md",
    "chars": 3456,
    "preview": "## Adding a server type\n\nAdding a new server `TYPE` can vary due to the complexity of obtaining and configuring each typ"
  },
  {
    "path": "docs/misc/contributing/docs.md",
    "chars": 1036,
    "preview": "# Site documentation\r\n\r\nThe documentation for this image/repository is written in markdown and built using [Zensical](ht"
  },
  {
    "path": "docs/misc/deployment/index.md",
    "chars": 4025,
    "preview": "# More Deployment Info \n\n## On Kubernetes\n\n### Using Helm\n\n- itzg Helm Chart:\n    - [GitHub repo](https://github.com/itz"
  },
  {
    "path": "docs/misc/examples.md",
    "chars": 6700,
    "preview": "# Examples\r\n\r\nVarious examples are [maintained in the repository](https://github.com/itzg/docker-minecraft-server/tree/m"
  },
  {
    "path": "docs/misc/healthcheck.md",
    "chars": 1863,
    "preview": "## Healthcheck\r\n\r\nThis image contains [mc-monitor](https://github.com/itzg/mc-monitor) and uses its `status` command to "
  },
  {
    "path": "docs/misc/log4j.md",
    "chars": 241,
    "preview": "**Please ensure you have pulled the latest image** since [all official mitigations](https://www.minecraft.net/en-us/arti"
  },
  {
    "path": "docs/misc/raspberrypi.md",
    "chars": 669,
    "preview": "# Running on RaspberryPi\r\n\r\nTo run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags [list in the"
  },
  {
    "path": "docs/misc/related-projects.md",
    "chars": 1274,
    "preview": "### [itzg/minecraft-bedrock-server](https://github.com/itzg/docker-minecraft-bedrock-server)\r\n\r\nDocker image that runs a"
  },
  {
    "path": "docs/misc/troubleshooting.md",
    "chars": 2147,
    "preview": "To troubleshoot the container initialization, such as when server files are pre-downloaded, set the environment variable"
  },
  {
    "path": "docs/misc/world-data.md",
    "chars": 5365,
    "preview": "\r\n## Downloadable world\r\n\r\nInstead of mounting the `/data` volume, you can instead specify the URL of a ZIP or compresse"
  },
  {
    "path": "docs/mods-and-plugins/curseforge-files.md",
    "chars": 3154,
    "preview": "# Auto-download from CurseForge\r\n\r\nMods and plugins can be auto-downloaded and upgraded from CurseForge by setting `CURS"
  },
  {
    "path": "docs/mods-and-plugins/index.md",
    "chars": 11511,
    "preview": "# Working with mods and plugins\n\n## Modpack platforms\n\nBy far the easiest way to work with mod and plugins, especially l"
  },
  {
    "path": "docs/mods-and-plugins/modrinth.md",
    "chars": 5858,
    "preview": "# Auto-download from Modrinth\n\n[Modrinth](https://modrinth.com/) is an open source modding platform with a clean, easy t"
  },
  {
    "path": "docs/mods-and-plugins/packwiz.md",
    "chars": 1157,
    "preview": "# Packwiz Modpacks\r\n\r\n[packwiz](https://packwiz.infra.link/) is a CLI tool for maintaining and providing modpack definit"
  },
  {
    "path": "docs/mods-and-plugins/spiget.md",
    "chars": 1262,
    "preview": "# Auto-download using Spiget\n\nThe `SPIGET_RESOURCES` variable can be set with a comma-separated list of SpigotMC resourc"
  },
  {
    "path": "docs/requirements.txt",
    "chars": 452,
    "preview": "click==8.3.1\ncolorama==0.4.6\ndeepmerge==2.0\nghp-import==2.1.0\ngriffe==2.0.0\nJinja2==3.1.6\nMarkdown==3.10.2\nMarkupSafe==3"
  },
  {
    "path": "docs/sending-commands/commands.md",
    "chars": 1944,
    "preview": "---\r\ntitle: With Docker\r\n---\r\n\r\n[RCON](http://wiki.vg/RCON) is enabled by default, so you can `exec` into the container "
  },
  {
    "path": "docs/sending-commands/ssh.md",
    "chars": 2394,
    "preview": "---\ntitle: Over SSH\n---\n\nThe container can host an SSH console. It is enabled by setting `ENABLE_SSH` to `true`.\nThe SSH"
  },
  {
    "path": "docs/sending-commands/websocket.md",
    "chars": 4099,
    "preview": "---\ntitle: With WebSocket\n---\n\nWith `WEBSOCKET_CONSOLE` set to `true`, logs can be streamed, and commands sent, over a W"
  },
  {
    "path": "docs/types-and-platforms/index.md",
    "chars": 1162,
    "preview": "# Server Types and Modpack Platforms\n\nServer types can be selected by setting the `TYPE` environment variable to one of "
  },
  {
    "path": "docs/types-and-platforms/mod-platforms/auto-curseforge.md",
    "chars": 14639,
    "preview": "# Auto CurseForge\n\nTo manage a CurseForge modpack automatically with upgrade support, pinned or latest version tracking,"
  },
  {
    "path": "docs/types-and-platforms/mod-platforms/curseforge.md",
    "chars": 2235,
    "preview": "# Manual CurseForge server packs\n\n!!! warning \"Deprecated\"\n\n    This mod platform type is deprecated. Please use [AUTO_C"
  },
  {
    "path": "docs/types-and-platforms/mod-platforms/ftb.md",
    "chars": 1990,
    "preview": "# Feed the Beast\r\n\r\n!!! note\r\n    Requires one of the Ubuntu with Hotspot images listed in [the Java versions section](."
  },
  {
    "path": "docs/types-and-platforms/mod-platforms/gtnh.md",
    "chars": 3519,
    "preview": "# Auto-setup GTNH server\n\n[GT New Horizons (GTNH)](https://www.gtnewhorizons.com/) is a Minecraft 1.7.10 modpack maintai"
  },
  {
    "path": "docs/types-and-platforms/mod-platforms/modrinth-modpacks.md",
    "chars": 5406,
    "preview": "# Modrinth Modpacks\n\n[Modrinth Modpacks](https://modrinth.com/modpacks) can automatically be installed along with the re"
  },
  {
    "path": "docs/types-and-platforms/server-types/bukkit-spigot.md",
    "chars": 2815,
    "preview": "# Bukkit/Spigot\r\n\r\n!!! failure \"GetBukkit site no longer supports automated downloads\"\r\n\r\n    The downloads provider <ht"
  },
  {
    "path": "docs/types-and-platforms/server-types/fabric.md",
    "chars": 2763,
    "preview": "A [Fabric server](https://fabricmc.net/) can be automatically downloaded, upgraded, and run by setting the environment v"
  },
  {
    "path": "docs/types-and-platforms/server-types/forge.md",
    "chars": 3782,
    "preview": "A [Forge server](http://www.minecraftforge.net/) can be automatically downloaded, upgraded, and run by setting the envir"
  },
  {
    "path": "docs/types-and-platforms/server-types/hybrids.md",
    "chars": 3441,
    "preview": "\r\n\r\n### Magma\r\n\r\nA [Magma](https://magmafoundation.org/) server, which is a combination of Forge and PaperMC, can be use"
  },
  {
    "path": "docs/types-and-platforms/server-types/others.md",
    "chars": 2833,
    "preview": "\r\n## SpongeVanilla\r\n\r\nEnable SpongeVanilla server mode by adding a `-e TYPE=SPONGEVANILLA` to your command-line.\r\n\r\nBy d"
  },
  {
    "path": "docs/types-and-platforms/server-types/paper.md",
    "chars": 6675,
    "preview": "A [PaperMC server](https://papermc.io/) can be automatically downloaded, upgraded, and run by setting the environment va"
  },
  {
    "path": "docs/types-and-platforms/server-types/quilt.md",
    "chars": 1419,
    "preview": "Enable [Quilt server](https://quiltmc.org/) mode by adding a `-e TYPE=QUILT` to your command-line.\r\n\r\n```shell\r\ndocker r"
  },
  {
    "path": "docs/variables.md",
    "chars": 25507,
    "preview": "\r\n!!! warning\r\n\r\n    The variables listed on this page are manually documented and may be out-of-date or inaccurate.\r\n\r\n"
  },
  {
    "path": "docs/versions/java.md",
    "chars": 6329,
    "preview": "## Image tags\r\n\r\nImage references can either omit the tag, which implies the tag `latest`, such as\r\n\r\n    itzg/minecraft"
  },
  {
    "path": "docs/versions/minecraft.md",
    "chars": 923,
    "preview": "To use a different Minecraft version, pass the `VERSION` environment variable (case sensitive), which can have the value"
  },
  {
    "path": "examples/.gitignore",
    "chars": 34,
    "preview": "data/\r\nmodpacks/\r\n.env\r\ndownloads/"
  },
  {
    "path": "examples/README.md",
    "chars": 168,
    "preview": "# Deployment Examples\n\nThis directory contains various deployment examples of the [itzg/minecraft-server](https://hub.do"
  },
  {
    "path": "examples/apply-extra-configs/compose.yml",
    "chars": 392,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: \"TRUE\"\n      TYPE: PAPER\n      MAX_MEMORY:"
  },
  {
    "path": "examples/apply-extra-configs/shared-configs/LuckPerms/config.yml",
    "chars": 37274,
    "preview": "####################################################################################################\n# LOCALLY MODIFIED\n"
  },
  {
    "path": "examples/auto-curseforge/aof7/docker-compose.yml",
    "chars": 766,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: true\n      MODPACK_PLATFORM: AUTO_CURSEFOR"
  },
  {
    "path": "examples/auto-curseforge/atm10/docker-compose.yml",
    "chars": 940,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      - \"25565:25565\"\n   "
  },
  {
    "path": "examples/auto-curseforge/atm8/docker-compose.yml",
    "chars": 1547,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server:java17\r\n    ports:\r\n      - \"25565:25565\"\r\n    environment:\r\n      EU"
  },
  {
    "path": "examples/auto-curseforge/atm8/filebrowser.json",
    "chars": 136,
    "preview": "{\r\n  \"port\": 80,\r\n  \"baseURL\": \"\",\r\n  \"address\": \"\",\r\n  \"log\": \"stdout\",\r\n  \"database\": \"/database/filebrowser.db\",\r\n  \""
  },
  {
    "path": "examples/auto-curseforge/atm9/docker-compose.yml",
    "chars": 757,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    ports:\r\n      - \"25565:25565\"\r\n    environment:\r\n      EULA: \"tr"
  },
  {
    "path": "examples/auto-curseforge/craftoria/docker-compose.yml",
    "chars": 572,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      - \"25565:25565\"\n   "
  },
  {
    "path": "examples/auto-curseforge/fabric-custom-loader/docker-compose.yml",
    "chars": 813,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: \"TRUE\"\n      MODPACK_PLATFORM: AUTO_CURSEF"
  },
  {
    "path": "examples/auto-curseforge/ftb-evolution/compose.yaml",
    "chars": 1103,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      # Game port\n      -"
  },
  {
    "path": "examples/auto-curseforge/modpack-manifest/docker-compose.yml",
    "chars": 701,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    environment:\r\n      EULA: true\r\n      MODPACK_PLATFORM: AUTO_CUR"
  },
  {
    "path": "examples/auto-curseforge/modpack-manifest/manifests/manifest.json",
    "chars": 492,
    "preview": "{\r\n  \"minecraft\": {\r\n    \"version\": \"1.20.4\",\r\n    \"modLoaders\": [\r\n      {\r\n        \"id\": \"fabric-0.15.3\",\r\n        \"pr"
  },
  {
    "path": "examples/auto-curseforge/one-block-modded/.gitignore",
    "chars": 5,
    "preview": "/.env"
  },
  {
    "path": "examples/auto-curseforge/one-block-modded/docker-compose.yml",
    "chars": 957,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    ports:\r\n      - \"25565:25565\"\r\n    environment:\r\n      EULA: \"tr"
  },
  {
    "path": "examples/auto-curseforge/pixelmon/docker-compose.yml",
    "chars": 677,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server:java8-multiarch\r\n    ports:\r\n      - \"25565:25565\"\r\n    environment:\r"
  },
  {
    "path": "examples/auto-curseforge/prominence2/docker-compose.yml",
    "chars": 687,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    ports:\n      - \"25565:25565\"\n    environment:\n      EULA: \"true\"\n  "
  },
  {
    "path": "examples/auto-curseforge/rad2/compose.yaml",
    "chars": 1191,
    "preview": "# This runs the most recent version of Roguelike Adventures and Dungeons 2. Version 1.11 as of writing.\nservices:\n  mc:\n"
  },
  {
    "path": "examples/auto-curseforge/skyfactory4/compose.yml",
    "chars": 343,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server:java8\r\n    environment:\r\n      EULA: \"true\"\r\n      MODPACK_PLATFORM: "
  },
  {
    "path": "examples/auto-curseforge/skyfactory5/compose.yml",
    "chars": 1014,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: true\n      # https://docker-minecraft-serv"
  },
  {
    "path": "examples/auto-curseforge/using-excludes/docker-compose.yml",
    "chars": 692,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server:java8\r\n    ports:\r\n      - \"25565:25565\"\r\n    environment:\r\n      EUL"
  },
  {
    "path": "examples/auto-curseforge/valhesia5/docker-compose.yml",
    "chars": 710,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    ports:\r\n      - \"25565:25565\"\r\n    environment:\r\n      EULA: \"tr"
  },
  {
    "path": "examples/auto-curseforge/vault-hunters-1-18-2/docker-compose.yml",
    "chars": 859,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server:java17\r\n    ports:\r\n      - \"25565:25565\"\r\n    environment:\r\n      EU"
  },
  {
    "path": "examples/autopause/compose.yml",
    "chars": 442,
    "preview": "services:\n  minecraft:\n    image: itzg/minecraft-server\n    ports:\n      - \"25565:25565\"\n    volumes:\n      - \"mc:/data\""
  },
  {
    "path": "examples/autostop/compose.yml",
    "chars": 392,
    "preview": "services:\n  minecraft:\n    image: itzg/minecraft-server\n    ports:\n      - \"25565:25565\"\n    volumes:\n      - \"mc:/data\""
  },
  {
    "path": "examples/bentobox/compose.yml",
    "chars": 816,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: \"TRUE\"\n      TYPE: PAPER\n      DEBUG: true"
  },
  {
    "path": "examples/bettermc/docker-compose.yml",
    "chars": 649,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    environment:\r\n      EULA: true\r\n      MODPACK_PLATFORM: AUTO_CUR"
  },
  {
    "path": "examples/canyon/compose.yml",
    "chars": 218,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server:java8\n    environment:\n      EULA: true\n      TYPE: canyon\n      VERSIO"
  },
  {
    "path": "examples/cleanroom/compose.yml",
    "chars": 452,
    "preview": "# Provides an example of running CleanroomMC from https://github.com/CleanroomMC/Cleanroom,\r\n# which is a Forge fork\r\nse"
  },
  {
    "path": "examples/curseforge-files/docker-compose.yml",
    "chars": 621,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: true\n      TYPE: FORGE\n      # Allocate AP"
  },
  {
    "path": "examples/docker-compose-big.yml",
    "chars": 488,
    "preview": "services:\n  minecraft:\n    ports:\n      - \"25565:25565\"\n    volumes:\n      - \"mcbig:/data\"\n    environment:\n      EULA: "
  },
  {
    "path": "examples/docker-compose-curseforge-atm7.yaml",
    "chars": 8864,
    "preview": "####################################################################\n#                         CURSEFORGE               "
  },
  {
    "path": "examples/docker-compose-curseforge.yml",
    "chars": 597,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server:${IMAGE_TAG:-java8}\n    volumes:\n    - ./modpacks:/modpacks:ro\n    - da"
  },
  {
    "path": "examples/docker-compose-forge-bettermcplus",
    "chars": 9513,
    "preview": "####################################################################\n#                       FORGE_GENERIC_PACK         "
  },
  {
    "path": "examples/docker-compose-forge.yml",
    "chars": 647,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    ports:\n    # expose the Minecraft server port outside of container\n"
  },
  {
    "path": "examples/docker-compose-magma.yml",
    "chars": 250,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server:java8\n    tty: true\n    stdin_open: true\n    ports:\n      - \"25565:2556"
  },
  {
    "path": "examples/docker-compose-mods-mount.yml",
    "chars": 271,
    "preview": "services:\r\n  minecraft:\r\n    image: itzg/minecraft-server\r\n    volumes:\r\n      - ./data:/data\r\n      - ./mods:/mods\r\n   "
  },
  {
    "path": "examples/docker-compose-rconcmd.yml",
    "chars": 1304,
    "preview": "services:\n  minecraft:\n    image: ${IMAGE_TO_TEST:-itzg/minecraft-server}\n    ports:\n      - \"25565:25565\"\n    volumes:\n"
  },
  {
    "path": "examples/docker-compose-simple.yml",
    "chars": 262,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      - \"25565:25565\"\n   "
  },
  {
    "path": "examples/docker-compose-spongeforge.yml",
    "chars": 922,
    "preview": "# Forge with Sponge API support. THIS REQUIRES DOWNLOADING SPONGEFORGE.\n# Place the SpongeForge jar file in /data/mods. "
  },
  {
    "path": "examples/docker-compose-world-download.yml",
    "chars": 217,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    ports:\n      - 25565:25565\n    environment:\n      EULA: \"TRUE\"\n    "
  },
  {
    "path": "examples/docker-compose.yml",
    "chars": 222,
    "preview": "services:\n  minecraft:\n    image: itzg/minecraft-server\n    stdin_open: true\n    tty: true\n    ports:\n      - \"25565:255"
  },
  {
    "path": "examples/fabric/compose.yml",
    "chars": 471,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: \"true\"\n      TYPE: FABRIC\n#      VERSION: "
  },
  {
    "path": "examples/fabric-cardboard/compose.yml",
    "chars": 395,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server:latest\r\n    tty: true\r\n    stdin_open: true\r\n    ports:\r\n      - \"255"
  },
  {
    "path": "examples/ftba/compose.yml",
    "chars": 732,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    ports:\n      # expose the Minecraft server port outside of containe"
  },
  {
    "path": "examples/ftba/stoneblock4/compose.yml",
    "chars": 311,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server:java25\n    tty: true\n    stdin_open: true\n    environment:\n      EULA: "
  },
  {
    "path": "examples/generic-pack/rlcraft/compose.yml",
    "chars": 665,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server:java8\n    volumes:\n    - data:/data\n    - ./modpacks:/modpacks:ro\n    e"
  },
  {
    "path": "examples/geyser/docker-compose.yml",
    "chars": 438,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    environment:\r\n      EULA: \"true\"\r\n      TYPE: \"PAPER\"\r\n      PLU"
  },
  {
    "path": "examples/gtnh/docker-compose-type-gtnh.yaml",
    "chars": 812,
    "preview": "services:\n  mc:\n    # make sure this java version matches with pack java version\n    image: itzg/minecraft-server:java25"
  },
  {
    "path": "examples/gtnh/docker-compose.yaml",
    "chars": 1496,
    "preview": "services:\n  mc:\n    # make sure this java version matches with pack java version\n    image: itzg/minecraft-server:java25"
  },
  {
    "path": "examples/jline/docker-compose.yml",
    "chars": 255,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    tty: true\r\n    stdin_open: true\r\n    environment:\r\n      EULA: t"
  },
  {
    "path": "examples/k8s/using-statefulset.yml",
    "chars": 1241,
    "preview": "---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n  labels:\n    app: mc-example\n  name: mc-example\nspec:\n  replicas: 1"
  },
  {
    "path": "examples/k8s/vanilla-deployment.yml",
    "chars": 1237,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  name: mc-vanilla\nspec:\n  type: NodePort\n  ports:\n  - port: 25565\n    nodePort: "
  },
  {
    "path": "examples/ketting/docker-compose.yml",
    "chars": 577,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: true\n      TYPE: KETTING\n      VERSION: 1."
  },
  {
    "path": "examples/lazymc/docker_compose.yml",
    "chars": 2168,
    "preview": "# Lazymc requires that the minecraft server have a static IP.\n#\n# To ensure that our servers have a static IP we need to"
  },
  {
    "path": "examples/lazytainer/docker_compose.yml",
    "chars": 940,
    "preview": "services:\n  lazytainer:\n    image: ghcr.io/vmorganp/lazytainer:master\n    environment:\n      VERBOSE: false\n    ports:\n "
  },
  {
    "path": "examples/mc-router-autoscale/compose-minimal.yml",
    "chars": 732,
    "preview": "# Source: https://github.com/itzg/mc-router/blob/main/examples/docker-autoscale/compose-minimal.yml\nservices:\n  router:\n"
  },
  {
    "path": "examples/mc-router-autoscale/compose.yml",
    "chars": 2050,
    "preview": "# Source: https://github.com/itzg/mc-router/blob/main/examples/docker-autoscale/compose.yml\n# This is a verbose example "
  },
  {
    "path": "examples/modrinth/bmc4/compose.yml",
    "chars": 545,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: true\n      MODPACK_PLATFORM: MODRINTH\n    "
  },
  {
    "path": "examples/modrinth/local-modpack/docker-compose.yml",
    "chars": 497,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    environment:\r\n      EULA: true\r\n      MODPACK_PLATFORM: MODRINTH"
  },
  {
    "path": "examples/modrinth/modrinth-modpack/compose.yml",
    "chars": 705,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      - \"25565:25565\"\n   "
  },
  {
    "path": "examples/modrinth/modrinth-paper/compose.yml",
    "chars": 254,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: \"true\"\n      TYPE: PAPER\n      VERSION: 1."
  },
  {
    "path": "examples/modrinth/modrinth-projects/compose.yml",
    "chars": 261,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      - \"25565:25565\"\n   "
  },
  {
    "path": "examples/modrinth/version-from-modrinth-projects/compose.yml",
    "chars": 303,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: true\n      TYPE: paper\n      MODRINTH_PROJ"
  },
  {
    "path": "examples/mods-file/docker-compose.yml",
    "chars": 311,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: \"true\"\n      TYPE: FORGE\n      VERSION: 1."
  },
  {
    "path": "examples/mods-file/mods.txt",
    "chars": 5767,
    "preview": "https://edge.forgecdn.net/files/2965/233/Bookshelf-1.15.2-5.6.40.jar\nhttps://edge.forgecdn.net/files/2926/27/Progressive"
  },
  {
    "path": "examples/mohist/compose.yml",
    "chars": 236,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    ports:\n      - \"25565:25565\"\n    environment:\n      EULA: \"TRUE\"\n  "
  },
  {
    "path": "examples/multi-project/README.md",
    "chars": 714,
    "preview": "This project demonstrates the use of two compose projects, `dbs` and `servers`, where the following capabilities are dem"
  },
  {
    "path": "examples/multi-project/dbs/docker-compose.yml",
    "chars": 411,
    "preview": "services:\r\n  mariadb:\r\n    image: mariadb:10\r\n    environment:\r\n      MARIADB_RANDOM_ROOT_PASSWORD: yes\r\n      MARIADB_D"
  },
  {
    "path": "examples/multi-project/servers/docker-compose.yml",
    "chars": 1074,
    "preview": "services:\r\n  proxy:\r\n    image: itzg/mc-proxy\r\n    environment:\r\n      TYPE: WATERFALL\r\n    ports:\r\n      - \"25565:25577"
  },
  {
    "path": "examples/multi-project/servers/mc-plugins/LuckPerms/config.yml",
    "chars": 36131,
    "preview": "####################################################################################################\r\n# +---------------"
  },
  {
    "path": "examples/multi-project/servers/velocity-config/velocity.toml",
    "chars": 6418,
    "preview": "# Config version. Do not change this\nconfig-version = \"2.6\"\n\n# What port should the proxy be bound to? By default, we'll"
  },
  {
    "path": "examples/multi-project/servers/waterfall-config/config.yml",
    "chars": 1207,
    "preview": "server_connect_timeout: 5000\r\nenforce_secure_profile: false\r\nremote_ping_cache: -1\r\nforge_support: true\r\nplayer_limit: -"
  },
  {
    "path": "examples/multi-project/servers/waterfall-config/waterfall.yml",
    "chars": 299,
    "preview": "plugin_channel_name_limit: 128\r\nuse_netty_dns_resolver: true\r\ndisable_modern_tab_limiter: true\r\nlog_initial_handler_conn"
  },
  {
    "path": "examples/multiline-motd/docker-compose.yml",
    "chars": 218,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: true\n      MOTD: |\n        A §l§cMinecraft"
  },
  {
    "path": "examples/neoforge/docker-compose.yml",
    "chars": 248,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    environment:\r\n      EULA: true\r\n      TYPE: NEOFORGE\r\n      VERS"
  },
  {
    "path": "examples/ngrok/compose.yml",
    "chars": 486,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    tty: true\r\n    stdin_open: true\r\n    ports:\r\n      - \"25565:2556"
  },
  {
    "path": "examples/optimized-server-config/README.md",
    "chars": 4616,
    "preview": "# Optimized Server Configuration (Paper, Purpur, Pufferfish)\n\nThis example demonstrates how to automatically download an"
  },
  {
    "path": "examples/optimized-server-config/docker-compose.yml",
    "chars": 391,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    container_name: paper\n    environment:\n      EULA: \"true\"\n      TYP"
  },
  {
    "path": "examples/packwiz/compose.yml",
    "chars": 479,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    environment:\n      EULA: true\n  "
  },
  {
    "path": "examples/paper/compose.yml",
    "chars": 274,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    environment:\n      EULA: \"true\"\n"
  },
  {
    "path": "examples/paper/paper-build-plugins/Dockerfile",
    "chars": 72,
    "preview": "FROM itzg/minecraft-server\n\nENV TYPE=PAPER\n\nCOPY plugins/*.jar /plugins/"
  },
  {
    "path": "examples/paper/paper-build-plugins/docker-compose.yml",
    "chars": 128,
    "preview": "services:\n  mc:\n    build: .\n    environment:\n      EULA: \"TRUE\"\n    ports:\n    - 25565:25565\n    stdin_open: true\n    t"
  },
  {
    "path": "examples/paper/paper-build-plugins/plugins/.gitignore",
    "chars": 5,
    "preview": "*.jar"
  },
  {
    "path": "examples/paper/paper-build-plugins/plugins/README.md",
    "chars": 327,
    "preview": "Download Bukkit/Spigot plugin jars, such as [WorldEdit](https://dev.bukkit.org/projects/worldedit/files) and place them "
  },
  {
    "path": "examples/paper/paper-proxy-protocol/config/paper-global.yml",
    "chars": 32,
    "preview": "proxies:\r\n  proxy-protocol: true"
  },
  {
    "path": "examples/paper/paper-proxy-protocol/docker-compose.yml",
    "chars": 310,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    environment:\r\n      EULA: true\r\n      TYPE: PAPER\r\n    ports:\r\n "
  },
  {
    "path": "examples/proxied/compose.yml",
    "chars": 234,
    "preview": "services:\n  mc:\n#    build: .\n    image: itzg/minecraft-server\n    ports:\n      - 25565:25565\n    environment:\n      EUL"
  },
  {
    "path": "examples/quilt/docker-compose.yml",
    "chars": 188,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: \"true\"\n      TYPE: QUILT\n    ports:\n      "
  },
  {
    "path": "examples/rlcraft/docker-compose.yml",
    "chars": 668,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server:java8-multiarch\r\n    environment:\r\n      EULA: true\r\n      MODPACK_PL"
  },
  {
    "path": "examples/simple-voice-chat/fabric-compose.yaml",
    "chars": 609,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      # Game port\n      -"
  },
  {
    "path": "examples/simple-voice-chat/neoforge-compose.yaml",
    "chars": 611,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      # Game port\n      -"
  },
  {
    "path": "examples/simple-voice-chat/paper-compose.yaml",
    "chars": 608,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    tty: true\n    stdin_open: true\n    ports:\n      # Game port\n      -"
  },
  {
    "path": "examples/skript/docker-compose.yml",
    "chars": 251,
    "preview": "services:\n  mc:\n    image: itzg/minecraft-server\n    environment:\n      EULA: true\n      TYPE: PAPER\n      PLUGINS: http"
  },
  {
    "path": "examples/spiget/docker-compose.yml",
    "chars": 470,
    "preview": "# NOTE\n# This file is purposely named spiget with an \"e\" since it provides an example of the\n# feature https://docker-mi"
  },
  {
    "path": "examples/spigot/docker-compose.yml",
    "chars": 222,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server\r\n    environment:\r\n      EULA: true\r\n      TYPE: SPIGOT\r\n      VERSIO"
  },
  {
    "path": "examples/tailscale/compose.yml",
    "chars": 1051,
    "preview": "services:\r\n  tailscale-client:\r\n    image: tailscale/tailscale:latest\r\n    container_name: tailscale\r\n    hostname: tail"
  },
  {
    "path": "examples/valhelsia2/docker-compose.yml",
    "chars": 390,
    "preview": "services:\r\n  mc:\r\n    image: itzg/minecraft-server:java8-multiarch\r\n    volumes:\r\n      - data:/data\r\n      - ./modpacks"
  },
  {
    "path": "examples/vanilla-tweaks/docker-compose.yml",
    "chars": 1544,
    "preview": "services:\n  vanillatweaks_file:\n    restart: \"no\"\n    image: itzg/minecraft-server\n    ports:\n      - \"25565:25565/tcp\"\n"
  },
  {
    "path": "examples/vanilla-tweaks/vanillatweaks-craftingtweaks.json",
    "chars": 229,
    "preview": "{\n    \"type\": \"craftingtweaks\",\n    \"version\": \"1.18\",\n    \"packs\": {\n        \"quality of life\": [\n            \"dropper "
  },
  {
    "path": "examples/vanilla-tweaks/vanillatweaks-datapacks.json",
    "chars": 368,
    "preview": "{\n    \"type\": \"datapacks\",\n    \"version\": \"1.18\",\n    \"packs\": {\n        \"survival\": [\n            \"graves\",\n           "
  },
  {
    "path": "examples/vanilla-tweaks/vanillatweaks-resourcepacks.json",
    "chars": 185,
    "preview": "{\n    \"type\": \"resourcepacks\",\n    \"version\": \"1.18\",\n    \"packs\": {\n        \"aesthetic\": [\"CherryPicking\", \"BlackNether"
  },
  {
    "path": "files/cf-exclude-include.json",
    "chars": 4883,
    "preview": "{\n  \"globalExcludes\": [\n    \"advancement-plaques\",\n    \"ambience-music-mod\",\n    \"ambientsounds\",\n    \"appleskin\",\n    \""
  },
  {
    "path": "files/knockd-config.cfg",
    "chars": 386,
    "preview": "[options]\n logfile = /dev/null\n[unpauseMCServer-server]\n sequence = 25565\n seq_timeout = 1\n command = /image/scripts/aut"
  },
  {
    "path": "files/modrinth-exclude-include.json",
    "chars": 2357,
    "preview": "{\n  \"globalExcludes\": [\n    \"3dskinlayers\",\n    \"ae2-emi-crafting\",\n    \"AmbientSounds\",\n    \"amecs\",\n    \"Animation_Ove"
  },
  {
    "path": "files/nanolimbo-settings-patch.json",
    "chars": 180,
    "preview": "{\n  \"file\": \"/data/settings.yml\",\n  \"ops\": [\n    {\n      \"$set\": {\n        \"path\": \"$.bind.port\",\n        \"value\": \"${SE"
  },
  {
    "path": "files/property-definitions.json",
    "chars": 4057,
    "preview": "{\r\n  \"accepts-transfers\": {\"env\": \"ACCEPTS_TRANSFERS\"},\r\n  \"allow-flight\": {\"env\": \"ALLOW_FLIGHT\"},\r\n  \"allow-nether\": {"
  },
  {
    "path": "files/server.properties",
    "chars": 1066,
    "preview": "op-permission-level=4\nallow-nether=true\nlevel-name=world\nenable-query=false\nallow-flight=false\nannounce-player-achieveme"
  },
  {
    "path": "images.json",
    "chars": 3818,
    "preview": "[\r\n  {\r\n    \"tag\": \"latest\",\r\n    \"notes\": \"Always tracks the most recent commit on the main branch\",\r\n    \"java\": \"25\","
  },
  {
    "path": "kustomize/README.md",
    "chars": 737,
    "preview": "This directory provides a base to use with [kubectl kustomize](https://kubernetes.io/docs/tasks/manage-kubernetes-object"
  },
  {
    "path": "kustomize/base/kustomization.yml",
    "chars": 106,
    "preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n- statefulset.yml\n- service.yml"
  },
  {
    "path": "kustomize/base/service.yml",
    "chars": 313,
    "preview": "apiVersion: v1\r\nkind: Service\r\nmetadata:\r\n  labels:\r\n    service: mc\r\n  annotations: {}\r\n  # Such as\r\n  #   mc-router.it"
  },
  {
    "path": "kustomize/base/statefulset.yml",
    "chars": 1158,
    "preview": "apiVersion: apps/v1\r\nkind: StatefulSet\r\nmetadata:\r\n  name: mc\r\nspec:\r\n  replicas: 1\r\n  serviceName: mc\r\n  selector:\r\n   "
  },
  {
    "path": "notes/.gitignore",
    "chars": 6,
    "preview": "/*.bkp"
  },
  {
    "path": "notes/Minecraft server containment.xml",
    "chars": 947,
    "preview": "<mxfile userAgent=\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.29"
  },
  {
    "path": "notes/rbac-processing.mmd",
    "chars": 1105,
    "preview": "[Scia Reto](https://sciareto.org) mind map   \r\n> __version__=`1.1`,showJumps=`true`\r\n---\r\n\r\n# RBAC processing\r\n\r\n## inpu"
  },
  {
    "path": "renovate.json5",
    "chars": 478,
    "preview": "{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"enabledManagers\": [\n    \"custom.regex\"\n  ],\n  \"cu"
  },
  {
    "path": "scripts/auto/autopause-daemon.sh",
    "chars": 3976,
    "preview": "#!/bin/bash\n\n. \"$(dirname \"$0\")/autopause-fcns.sh\"\n\n# shellcheck source=../start-utils\n. \"$(dirname \"$0\")/../start-utils"
  },
  {
    "path": "scripts/auto/autopause-fcns.sh",
    "chars": 1583,
    "preview": "#!/bin/bash\n\n# shellcheck source=../scripts/start-utils\n. \"$(dirname \"$0\")/../start-utils\"\ncurrent_uptime() {\n  awk '{pr"
  }
]

// ... and 170 more files (download for full content)

About this extraction

This page contains the full source code of the itzg/docker-minecraft-server GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 370 files (618.2 KB), approximately 174.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!