-
Notifications
You must be signed in to change notification settings - Fork 92
Add New Service: Minecraft Server #262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+211
−12
Merged
Changes from 3 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
9e613f7
feat: minecraft service
LaijieJi bd8c972
chore: defaulted server type to vanilla
LaijieJi c5a233d
chore: lint markdown
LaijieJi bb22a52
chore: solve issues with files
LaijieJi e9be6bf
Merge branch 'main' into main
jackspiering 6276560
Update README.md
jackspiering f031519
Merge branch 'main' into main
jackspiering 3be51a1
docs(contributors): update README contributors
github-actions[bot] 25a915c
Merge branch 'main' into main
crypt0rr 44f9feb
docs(contributor): contrib-readme-action has updated readme
github-actions[bot] 4e5aa13
Merge branch 'main' into main
jackspiering 12b62e0
docs(contributor): contrib-readme-action has updated readme
github-actions[bot] 29bc5a6
Update
crypt0rr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
jackspiering marked this conversation as resolved.
Outdated
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,274 @@ | ||
| # Claude Code Instructions: ScaleTail Minecraft Service Contribution | ||
|
|
||
| You are helping contribute a new service to the ScaleTail repository | ||
| (https://github.com/tailscale-dev/ScaleTail). ScaleTail is a collection | ||
| of Docker Compose configurations that run self-hosted services alongside | ||
| a Tailscale sidecar container, making them accessible privately over a | ||
| Tailnet without port forwarding. | ||
|
|
||
| Your task is to create a complete, contribution-ready Minecraft server | ||
| entry following the exact structure and conventions of existing services | ||
| in the repo. | ||
|
|
||
| --- | ||
|
|
||
| ## CONTEXT: How ScaleTail services are structured | ||
|
|
||
| Every service in ScaleTail lives at `services/<service-name>/` and | ||
| contains exactly these files: | ||
|
|
||
| - `docker-compose.yml` — the main compose file with Tailscale sidecar | ||
| - `README.md` — documentation for the service | ||
| - `.env` — environment variable defaults (committed with placeholder values) | ||
| - `config/serve.json` — Tailscale Serve config (only for HTTP services) | ||
|
|
||
| The sidecar pattern is always the same: | ||
|
|
||
| 1. A `tailscale-<service>` container runs the Tailscale client | ||
| 2. The actual service container uses `network_mode: service:tailscale-<service>` | ||
| to route all traffic through the Tailscale interface | ||
| 3. The Tailscale container has a healthcheck on `http://127.0.0.1:41234/healthz` | ||
| 4. Credentials go in a `.env` file; `TS_AUTHKEY` is always required | ||
|
|
||
| **IMPORTANT technical difference from HTTP services:** Minecraft Java Edition | ||
| uses TCP port 25565. Tailscale Serve only supports HTTP/HTTPS proxying, | ||
| so a `serve.json` is NOT needed or appropriate here. Players connect | ||
| directly to the Tailscale node at `minecraft.<tailnet-name>.ts.net:25565`. | ||
| Do NOT create a `config/serve.json` file for this service. | ||
|
|
||
| --- | ||
|
|
||
| ## TASK: Create the following files | ||
|
|
||
| ### 1. `services/minecraft/docker-compose.yml` | ||
|
|
||
| Use `itzg/minecraft-server:latest` as the Minecraft image (it's the | ||
| community standard with 1B+ pulls, supports Java Edition with Paper, | ||
| Fabric, Forge, Vanilla, etc.). | ||
|
|
||
| The compose file must follow this exact structure pattern (derived from | ||
| existing ScaleTail services like radarr, vaultwarden, forgejo): | ||
|
|
||
| ```yaml | ||
| services: | ||
| tailscale-minecraft: | ||
| image: tailscale/tailscale:latest | ||
| container_name: tailscale-minecraft | ||
| hostname: minecraft # becomes the Tailnet device name | ||
| environment: | ||
| - TS_AUTHKEY=${TS_AUTHKEY} | ||
| - TS_STATE_DIR=/var/lib/tailscale | ||
| - TS_USERSPACE=false | ||
| # NO TS_SERVE_CONFIG — Minecraft uses raw TCP, not HTTP | ||
| volumes: | ||
| - ./config:/config | ||
| - ts-minecraft-data:/var/lib/tailscale | ||
| devices: | ||
| - /dev/net/tun:/dev/net/tun | ||
| cap_add: | ||
| - NET_ADMIN | ||
| - SYS_MODULE | ||
| # Optional DNS override block (commented out by default): | ||
| # dns: | ||
| # - 1.1.1.1 | ||
| healthcheck: | ||
| test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:41234/healthz"] | ||
| interval: 1m | ||
| timeout: 10s | ||
| retries: 3 | ||
| restart: unless-stopped | ||
|
|
||
| minecraft: | ||
| image: itzg/minecraft-server:latest | ||
| container_name: minecraft | ||
| network_mode: service:tailscale-minecraft | ||
| environment: | ||
| - EULA=TRUE # Required — accepted by the user | ||
| - TYPE=${SERVER_TYPE} # VANILLA, PAPER, FABRIC, FORGE, etc. | ||
| - VERSION=${MINECRAFT_VERSION} # e.g. LATEST or 1.21.4 | ||
| - DIFFICULTY=${DIFFICULTY} | ||
| - MAX_PLAYERS=${MAX_PLAYERS} | ||
| - MOTD=${MOTD} | ||
| - MEMORY=${MEMORY} | ||
| - ONLINE_MODE=${ONLINE_MODE} # set false for cracked/offline servers | ||
| # Uncomment to also bind to the local network (outside Tailnet): | ||
| # ports: | ||
| # - "0.0.0.0:25565:25565" | ||
| volumes: | ||
| - minecraft-data:/data | ||
| depends_on: | ||
| tailscale-minecraft: | ||
| condition: service_healthy | ||
| restart: unless-stopped | ||
|
|
||
| volumes: | ||
| ts-minecraft-data: | ||
| minecraft-data: | ||
| ``` | ||
|
|
||
| All environment variables must come from the `.env` file. Add inline | ||
| comments explaining non-obvious fields, matching the style of other | ||
| ScaleTail services (see the radarr compose for reference tone). | ||
|
|
||
| --- | ||
|
|
||
| ### 2. `services/minecraft/.env` | ||
|
|
||
| Include all variables referenced in the compose file with sensible | ||
| defaults and a comment for each line: | ||
|
|
||
| ``` | ||
| # Tailscale auth key — get one from https://login.tailscale.com/admin/settings/keys | ||
| TS_AUTHKEY= | ||
|
|
||
| # Minecraft server type: VANILLA, PAPER, FABRIC, FORGE, SPIGOT, BUKKIT | ||
| SERVER_TYPE=PAPER | ||
|
|
||
| # Minecraft version: LATEST or a specific version like 1.21.4 | ||
| MINECRAFT_VERSION=LATEST | ||
|
|
||
| # Server difficulty: peaceful, easy, normal, hard | ||
| DIFFICULTY=normal | ||
|
|
||
| # Maximum number of concurrent players | ||
| MAX_PLAYERS=10 | ||
|
|
||
| # Message of the day shown in the server list | ||
| MOTD=A Minecraft Server on Tailscale | ||
|
|
||
| # JVM memory allocation (increase for larger servers or more players) | ||
| MEMORY=2G | ||
|
|
||
| # Online mode: true = requires valid Minecraft account, false = allows offline/cracked clients | ||
| ONLINE_MODE=true | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### 3. `services/minecraft/README.md` | ||
|
|
||
| Write a complete README following the exact style of other ScaleTail | ||
| service READMEs (see forgejo and vaultwarden for tone and structure). | ||
|
|
||
| The README must include the following sections: | ||
|
|
||
| **Header section:** | ||
| - A brief description of what Minecraft is | ||
| - A brief description of what this Docker Compose config does | ||
| (Tailscale sidecar, private Tailnet access, no port forwarding needed) | ||
|
|
||
| **Key features section** (bullet list): | ||
| - Private multiplayer without opening router ports | ||
| - Friends connect using the Tailscale MagicDNS hostname | ||
| - Supports multiple server types (Vanilla, Paper, Fabric, Forge) | ||
| - Persistent world data in a named Docker volume | ||
| - Configurable via environment variables | ||
|
|
||
| **Technical note on networking:** | ||
| Explain clearly that this service uses raw TCP on port 25565, NOT | ||
| Tailscale Serve/Funnel (which are for HTTP only). Players connect at | ||
| `minecraft.<tailnet-name>.ts.net:25565`. This is the key distinction | ||
| from web-based services in the repo. | ||
|
|
||
| **How it works section:** | ||
| Explain the sidecar pattern briefly — the tailscale container runs the | ||
| Tailscale client, the Minecraft container shares its network stack via | ||
| `network_mode: service:tailscale-minecraft`, and all traffic is routed | ||
| over the Tailnet. | ||
|
|
||
| **Setup instructions:** | ||
| 1. Clone the repo and navigate to `services/minecraft/` | ||
| 2. Edit `.env` and paste in your Tailscale auth key (from https://login.tailscale.com/admin/settings/keys) | ||
| 3. (Optional) Adjust SERVER_TYPE, MEMORY, MAX_PLAYERS in `.env` | ||
| 4. Run `docker compose up -d` | ||
| 5. Find your Tailnet name in the Tailscale admin console | ||
| 6. Connect in Minecraft: Multiplayer → Add Server → `minecraft.<tailnet-name>.ts.net` | ||
|
|
||
| **Connecting section:** | ||
| - All players must be on the same Tailnet (or have been shared access to the node) | ||
| - ONLINE_MODE=false allows offline/non-premium accounts but reduces security | ||
| - Bedrock Edition uses UDP port 19132, which is not proxied through Tailscale Serve. | ||
| Bedrock players can still connect directly via the Tailscale IP on port 19132, | ||
| but this requires using the Bedrock edition of itzg/minecraft-server (set TYPE=BEDROCK) | ||
| and is outside the scope of this configuration. | ||
|
|
||
| **Environment variables table:** | ||
| A markdown table documenting every variable in `.env`: | ||
|
|
||
| | Variable | Default | Description | | ||
| |---|---|---| | ||
| | TS_AUTHKEY | _(empty)_ | Tailscale auth key from the admin console | | ||
| | SERVER_TYPE | PAPER | Server software: VANILLA, PAPER, FABRIC, FORGE, SPIGOT, BUKKIT | | ||
| | MINECRAFT_VERSION | LATEST | Game version: LATEST or a pinned version like 1.21.4 | | ||
| | DIFFICULTY | normal | Game difficulty: peaceful, easy, normal, hard | | ||
| | MAX_PLAYERS | 10 | Maximum concurrent players | | ||
| | MOTD | A Minecraft Server on Tailscale | Message shown in the server browser | | ||
| | MEMORY | 2G | JVM heap size — increase for larger worlds or player counts | | ||
| | ONLINE_MODE | true | Require valid Minecraft accounts (set false for offline/LAN play) | | ||
|
|
||
| **Useful links section:** | ||
| - itzg/minecraft-server on Docker Hub: https://hub.docker.com/r/itzg/minecraft-server | ||
| - itzg/minecraft-server documentation: https://docker-minecraft-server.readthedocs.io | ||
| - Tailscale Serve docs: https://tailscale.com/kb/1242/tailscale-serve | ||
| - Tailscale Funnel docs: https://tailscale.com/kb/1223/funnel | ||
| - Tailscale Docker guide: https://tailscale.com/blog/docker-tailscale-guide | ||
|
|
||
| --- | ||
|
|
||
| ### 4. Update the root `README.md` | ||
|
|
||
| Open the root `README.md` of the repository. Find the table of available | ||
| services. Check whether a `### 🎮 Gaming` section already exists. | ||
|
|
||
| - **If a Gaming section exists:** add the Minecraft row to its table. | ||
| - **If no Gaming section exists:** create a new section immediately before | ||
| `### 📱 Utilities` (or wherever makes sense alphabetically/thematically) | ||
| with the following header and table: | ||
|
|
||
| ```markdown | ||
| ### 🎮 Gaming | ||
|
|
||
| | 🎮 Service | 📝 Description | 🔗 Link | | ||
| | --- | --- | --- | | ||
| | 🎮 **Minecraft** | A self-hosted Minecraft Java Edition server accessible privately over your Tailnet — no port forwarding required. | [Details](/services/minecraft) | | ||
| ``` | ||
|
|
||
| Match the column order and formatting of existing tables exactly | ||
| (emoji + bold name | description | link). | ||
|
|
||
| --- | ||
|
|
||
| ## CONSTRAINTS | ||
|
|
||
| - Do NOT create a `config/serve.json` — this is a TCP game server, | ||
| not an HTTP service. Tailscale Serve is for HTTP proxying only. | ||
| - Do NOT include `TS_SERVE_CONFIG` in the compose environment. | ||
| - Use named volumes (not bind mounts) for both `minecraft-data` and | ||
| `ts-minecraft-data` — this is consistent with other ScaleTail services | ||
| and avoids file permission issues on different host systems. | ||
| - The `./config` bind mount for the Tailscale container is correct and | ||
| intentional — it stores the Tailscale config files that persist the | ||
| node identity across container restarts. | ||
| - Match the comment style and density of existing ScaleTail services — | ||
| helpful but not excessive. | ||
| - The contribution must be self-contained inside `services/minecraft/`. | ||
| The only other file to modify is the root `README.md`. | ||
|
|
||
| --- | ||
|
|
||
| ## VALIDATION CHECKLIST | ||
|
|
||
| After creating all files, verify the following before finishing: | ||
|
|
||
| - [ ] `docker-compose.yml` references only variables defined in `.env` | ||
| - [ ] No `serve.json` file exists anywhere under `services/minecraft/` | ||
| - [ ] No `TS_SERVE_CONFIG` appears anywhere in the Minecraft service files | ||
| - [ ] The Tailscale healthcheck uses `http://127.0.0.1:41234/healthz` | ||
| (this is Tailscale's built-in health endpoint used by all services) | ||
| - [ ] The `minecraft` container has `depends_on` pointing to | ||
| `tailscale-minecraft` with `condition: service_healthy` | ||
| - [ ] The root `README.md` table row matches the column structure of | ||
| adjacent rows exactly | ||
| - [ ] All `.env` variables have a comment explaining their purpose | ||
| - [ ] The README networking section explicitly states this is TCP/raw | ||
| socket, NOT Tailscale Serve/Funnel |
|
jackspiering marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Tailscale auth key — get one from https://login.tailscale.com/admin/settings/keys | ||
| TS_AUTHKEY= | ||
|
|
||
| # Minecraft server type: VANILLA, PAPER, FABRIC, FORGE, SPIGOT, BUKKIT | ||
| SERVER_TYPE=VANILLA | ||
|
|
||
| # Minecraft version: LATEST or a specific version like 1.21.4 | ||
| MINECRAFT_VERSION=LATEST | ||
|
|
||
| # Server difficulty: peaceful, easy, normal, hard | ||
| DIFFICULTY=normal | ||
|
|
||
| # Maximum number of concurrent players | ||
| MAX_PLAYERS=10 | ||
|
|
||
| # Message of the day shown in the server list | ||
| MOTD=A Minecraft Server on Tailscale | ||
|
|
||
| # JVM memory allocation (increase for larger servers or more players) | ||
| MEMORY=2G | ||
|
|
||
| # Online mode: true = requires valid Minecraft account, false = allows offline/cracked clients | ||
| ONLINE_MODE=true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| # Minecraft Server with Tailscale Sidecar Configuration | ||
|
|
||
| This Docker Compose configuration sets up a [Minecraft Java Edition](https://www.minecraft.net/) server with Tailscale as a sidecar container, enabling private multiplayer access over your Tailnet. No port forwarding or public IP required — only players on your Tailscale network can connect. | ||
|
|
||
| ## Minecraft | ||
|
|
||
| [Minecraft](https://www.minecraft.net/) is one of the most popular sandbox games in the world, offering open-ended survival, building, and exploration gameplay. This configuration uses the [itzg/minecraft-server](https://hub.docker.com/r/itzg/minecraft-server) Docker image, the community standard with support for Vanilla, Paper, Fabric, Forge, and other server types. | ||
|
|
||
| ## Key Features | ||
|
|
||
| * **Private multiplayer** — no router ports need to be opened; all traffic stays on your Tailnet. | ||
| * **MagicDNS hostname** — players connect using `minecraft.<tailnet-name>.ts.net:25565`. | ||
| * **Multiple server types** — switch between Vanilla, Paper, Fabric, Forge, Spigot, and Bukkit via an environment variable. | ||
| * **Persistent world data** — world files and server config are stored in a named Docker volume. | ||
| * **Fully configurable** — server type, version, difficulty, player limit, MOTD, and memory are all set through `.env`. | ||
|
|
||
| ## Networking Note | ||
|
|
||
| Unlike web-based services in this repository, Minecraft uses **raw TCP on port 25565**. Tailscale Serve and Funnel only proxy HTTP/HTTPS traffic, so they are **not used here**. Instead, the Minecraft server listens directly on the Tailscale interface and players connect at: | ||
|
|
||
| ```text | ||
| minecraft.<tailnet-name>.ts.net:25565 | ||
| ``` | ||
|
|
||
| No `serve.json` configuration is needed for this service. | ||
|
|
||
| ## Configuration Overview | ||
|
|
||
| In this setup, the `tailscale-minecraft` service runs the Tailscale client to join your private mesh network. The `minecraft` service is configured with `network_mode: service:tailscale-minecraft`, so all network traffic for the game server is routed through the Tailscale container. The Minecraft server binds TCP port 25565, which is reachable only from devices on your Tailnet. | ||
|
|
||
| ## Setup | ||
|
|
||
| 1. Clone the repository and navigate to the service directory: | ||
|
|
||
| ```bash | ||
| git clone https://github.com/tailscale-dev/ScaleTail.git | ||
| cd ScaleTail/services/minecraft | ||
| ``` | ||
|
|
||
| 2. Edit `.env` and paste in your Tailscale auth key (from [https://login.tailscale.com/admin/settings/keys](https://login.tailscale.com/admin/settings/keys)). | ||
|
|
||
| 3. (Optional) Adjust `SERVER_TYPE`, `MEMORY`, `MAX_PLAYERS`, or other variables in `.env`. | ||
|
|
||
| 4. Start the stack: | ||
|
|
||
| ```bash | ||
| docker compose up -d | ||
| ``` | ||
|
|
||
| 5. Find your Tailnet name in the [Tailscale admin console](https://login.tailscale.com/admin/machines). | ||
|
|
||
| 6. Connect in Minecraft: **Multiplayer** → **Add Server** → `minecraft.<tailnet-name>.ts.net` | ||
|
|
||
| ## Connecting | ||
|
|
||
| * All players must be on the same Tailnet (or have been shared access to the node). | ||
| * `ONLINE_MODE=false` allows offline/non-premium accounts but reduces security — only use this on trusted networks. | ||
| * Bedrock Edition uses UDP port 19132, which is not proxied through Tailscale Serve. Bedrock players can still connect directly via the Tailscale IP on port 19132, but this requires using the Bedrock edition of itzg/minecraft-server (set `TYPE=BEDROCK`) and is outside the scope of this configuration. | ||
|
|
||
| ## Environment Variables | ||
|
|
||
| | Variable | Default | Description | | ||
| | --- | --- | --- | | ||
| | `TS_AUTHKEY` | _(empty)_ | Tailscale auth key from the admin console | | ||
| | `SERVER_TYPE` | `PAPER` | Server software: VANILLA, PAPER, FABRIC, FORGE, SPIGOT, BUKKIT | | ||
| | `MINECRAFT_VERSION` | `LATEST` | Game version: LATEST or a pinned version like 1.21.4 | | ||
| | `DIFFICULTY` | `normal` | Game difficulty: peaceful, easy, normal, hard | | ||
| | `MAX_PLAYERS` | `10` | Maximum concurrent players | | ||
| | `MOTD` | `A Minecraft Server on Tailscale` | Message shown in the server browser | | ||
| | `MEMORY` | `2G` | JVM heap size — increase for larger worlds or player counts | | ||
| | `ONLINE_MODE` | `true` | Require valid Minecraft accounts (set false for offline/LAN play) | | ||
|
|
||
| ## Useful Links | ||
|
|
||
| * [itzg/minecraft-server on Docker Hub](https://hub.docker.com/r/itzg/minecraft-server) | ||
| * [itzg/minecraft-server documentation](https://docker-minecraft-server.readthedocs.io) | ||
| * [Tailscale Serve docs](https://tailscale.com/kb/1242/tailscale-serve) | ||
| * [Tailscale Funnel docs](https://tailscale.com/kb/1223/funnel) | ||
| * [Tailscale Docker guide](https://tailscale.com/blog/docker-tailscale-guide) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.