feat(auth): Blessing Skin variant as Drasl alternative
Override stack that swaps Drasl for Blessing Skin Server + MariaDB, talking to Minecraft via the yggdrasil-api plugin (authlib endpoint /api/yggdrasil, ONLINE_MODE=TRUE). Caddy auth.* repointed to blessing-skin:80; Drasl left idle (compose merges depends_on). Run: docker compose -f docker-compose.yml -f docker-compose.blessingskin.yml up -d Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
10
.env.example
10
.env.example
@@ -17,3 +17,13 @@ ENABLE_MDNS=false
|
||||
RCON_PASSWORD=change-me-to-something-random
|
||||
# Only needed if using CurseForge-exclusive mods:
|
||||
# CF_API_KEY=your-curseforge-api-key
|
||||
|
||||
# ── Blessing Skin auth variant (docker-compose.blessingskin.yml) ──────
|
||||
# Only needed when running the Blessing Skin override instead of Drasl.
|
||||
BS_DB_NAME=blessingskin
|
||||
BS_DB_USER=blessingskin
|
||||
BS_DB_PASSWORD=change-me-bs-db
|
||||
BS_DB_ROOT_PASSWORD=change-me-bs-root
|
||||
# Generate once and paste here so it survives container recreates:
|
||||
# docker run --rm azusamikan/blessing-skin-server-docker:latest php artisan key:generate --show
|
||||
BS_APP_KEY=base64:replace-with-generated-key
|
||||
|
||||
14
caddy/conf.d/00-core-blessingskin.caddy
Normal file
14
caddy/conf.d/00-core-blessingskin.caddy
Normal file
@@ -0,0 +1,14 @@
|
||||
# Core ingress — Blessing Skin variant. Replaces 00-core.caddy when the
|
||||
# docker-compose.blessingskin.yml override is in play (mounted at the same
|
||||
# target path). auth.* now points at Blessing Skin instead of Drasl.
|
||||
#
|
||||
# Blessing Skin serves BOTH its web UI (/) and the Yggdrasil API (/api/yggdrasil)
|
||||
# on the same vhost, so a single reverse_proxy covers everything.
|
||||
http://auth.{$BASE_DOMAIN} {
|
||||
reverse_proxy blessing-skin:80
|
||||
}
|
||||
|
||||
http://pack.{$BASE_DOMAIN} {
|
||||
root * /srv/pack
|
||||
file_server browse
|
||||
}
|
||||
103
docker-compose.blessingskin.yml
Normal file
103
docker-compose.blessingskin.yml
Normal file
@@ -0,0 +1,103 @@
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Blessing Skin auth variant — use INSTEAD of Drasl.
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Layer this over the base file:
|
||||
#
|
||||
# docker compose -f docker-compose.yml -f docker-compose.blessingskin.yml up -d
|
||||
#
|
||||
# What it does vs the base stack:
|
||||
# - drasl → left running but UNUSED + unreachable (Caddy no longer
|
||||
# routes to it; it has no host port). Compose merges
|
||||
# depends_on, so it can't be removed from an override —
|
||||
# idling it is the clean option. `docker compose ... stop
|
||||
# drasl` after up if you want it down.
|
||||
# - caddy → auth.* now reverse-proxies blessing-skin:80
|
||||
# - mariadb → new; Blessing Skin's datastore (no SQLite support)
|
||||
# - blessing-skin → new; PHP skin server + yggdrasil-api plugin
|
||||
# - minecraft → authlib-injector now points at /api/yggdrasil,
|
||||
# ONLINE_MODE=TRUE (real session validation against BSS)
|
||||
#
|
||||
# First-run is a WEB WIZARD — see plan/03b-blessing-skin.md. The yggdrasil-api
|
||||
# plugin must be installed + enabled from the BSS admin panel before the
|
||||
# /api/yggdrasil endpoint (and thus Minecraft login) works.
|
||||
#
|
||||
# DB creds + APP_KEY come from .env (see .env.example: BS_* vars).
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
|
||||
services:
|
||||
caddy:
|
||||
# Swap the core ingress conf for the Blessing Skin one (same mount target,
|
||||
# so it shadows the base 00-core.caddy). volumes is a full replacement here.
|
||||
volumes:
|
||||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- ./caddy/conf.d/00-core-blessingskin.caddy:/etc/caddy/conf.d/00-core.caddy:ro
|
||||
- ./pack:/srv/pack:ro
|
||||
depends_on:
|
||||
- blessing-skin
|
||||
|
||||
mariadb:
|
||||
image: mariadb:11
|
||||
container_name: mariadb
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MARIADB_DATABASE: ${BS_DB_NAME}
|
||||
MARIADB_USER: ${BS_DB_USER}
|
||||
MARIADB_PASSWORD: ${BS_DB_PASSWORD}
|
||||
MARIADB_ROOT_PASSWORD: ${BS_DB_ROOT_PASSWORD}
|
||||
TZ: "Europe/Madrid"
|
||||
volumes:
|
||||
- bs_db:/var/lib/mysql
|
||||
healthcheck:
|
||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
networks:
|
||||
- mcnet
|
||||
|
||||
blessing-skin:
|
||||
image: azusamikan/blessing-skin-server-docker:latest
|
||||
container_name: blessing-skin
|
||||
restart: unless-stopped
|
||||
# Internal-only — reached via Caddy at auth.${BASE_DOMAIN}.
|
||||
environment:
|
||||
APP_URL: "http://auth.${BASE_DOMAIN}"
|
||||
# Persist APP_KEY across recreates (else sessions/encryption break).
|
||||
# Generate once: docker run --rm azusamikan/blessing-skin-server-docker:latest php artisan key:generate --show
|
||||
APP_KEY: ${BS_APP_KEY}
|
||||
DB_DRIVER: "mysql"
|
||||
DB_HOST: "mariadb"
|
||||
DB_PORT: "3306"
|
||||
DB_DATABASE: ${BS_DB_NAME}
|
||||
DB_USERNAME: ${BS_DB_USER}
|
||||
DB_PASSWORD: ${BS_DB_PASSWORD}
|
||||
TZ: "Europe/Madrid"
|
||||
volumes:
|
||||
- bs_storage:/app/storage # uploaded skins/capes + textures
|
||||
- bs_plugins:/app/plugins # yggdrasil-api plugin lives here
|
||||
depends_on:
|
||||
mariadb:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- mcnet
|
||||
|
||||
minecraft:
|
||||
environment:
|
||||
# authlib-injector API root for Blessing Skin's yggdrasil-api plugin
|
||||
# is <site>/api/yggdrasil (NOT /authlib-injector like Drasl).
|
||||
JVM_OPTS: "-javaagent:/extras/authlib-injector.jar=http://auth.${BASE_DOMAIN}/api/yggdrasil"
|
||||
# authlib-injector needs real auth: online-mode TRUE so the server
|
||||
# validates sessions against Blessing Skin. (Drasl variant used FALSE.)
|
||||
ONLINE_MODE: "TRUE"
|
||||
# Keep FALSE for safety on 1.21+. The yggdrasil-api plugin DOES sign
|
||||
# profile keys, so you MAY flip this to TRUE if signed chat is wanted.
|
||||
ENFORCE_SECURE_PROFILE: "FALSE"
|
||||
# Merged with the base depends_on (drasl, caddy); just adds blessing-skin so
|
||||
# Minecraft starts after the skin server is up.
|
||||
depends_on:
|
||||
- blessing-skin
|
||||
|
||||
volumes:
|
||||
bs_db:
|
||||
bs_storage:
|
||||
bs_plugins:
|
||||
80
plan/03b-blessing-skin.md
Normal file
80
plan/03b-blessing-skin.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Blessing Skin — auth + skin server (Drasl alternative)
|
||||
|
||||
## Summary
|
||||
|
||||
Drop-in alternative to Drasl (`plan/03-drasl.md`). Blessing Skin Server (BSS) is
|
||||
a PHP skin station; the **yggdrasil-api plugin** gives it a Yggdrasil API that
|
||||
authlib-injector talks to — same end result as Drasl, different internals.
|
||||
|
||||
Run it as an override **instead of** Drasl:
|
||||
|
||||
```
|
||||
docker compose -f docker-compose.yml -f docker-compose.blessingskin.yml up -d
|
||||
```
|
||||
|
||||
The override (`docker-compose.blessingskin.yml`) repoints Caddy's `auth.*` vhost
|
||||
at `blessing-skin:80`, adds `mariadb` + `blessing-skin`, and switches the
|
||||
Minecraft authlib endpoint to `/api/yggdrasil`. Drasl stays defined but idle and
|
||||
unreachable (compose merges `depends_on`, so an override can't remove it);
|
||||
`docker compose … stop drasl` after up if you want it down.
|
||||
|
||||
## Drasl vs Blessing Skin — what changes
|
||||
|
||||
| | Drasl | Blessing Skin |
|
||||
|---|---|---|
|
||||
| Backend | single Go binary | PHP app + **MariaDB** (no SQLite) |
|
||||
| Config | rendered `config.toml` | **web install wizard** + DB |
|
||||
| Yggdrasil API | built in | **yggdrasil-api plugin** (install + enable) |
|
||||
| authlib endpoint | `…/authlib-injector` | `…/api/yggdrasil` |
|
||||
| OIDC/Keycloak | supported (future) | not native (OAuth plugins exist) |
|
||||
| Server online-mode | repo used FALSE | **TRUE** (real session validation) |
|
||||
|
||||
## Setup (first run)
|
||||
|
||||
1. `cp .env.example .env`, fill the `BS_*` vars. Generate `BS_APP_KEY`:
|
||||
```
|
||||
docker run --rm azusamikan/blessing-skin-server-docker:latest \
|
||||
php artisan key:generate --show
|
||||
```
|
||||
2. Bring the stack up with the override (command above).
|
||||
3. Open `http://auth.${BASE_DOMAIN}` → BSS install wizard. DB host = `mariadb`,
|
||||
port `3306`, name/user/pass = the `BS_*` values. Create the admin account.
|
||||
4. Admin panel → **Plugins → Plugin Market** → install **yggdrasil-api** →
|
||||
enable it. (Needs internet; for air-gap, pre-place the plugin jar/zip into
|
||||
the `bs_plugins` volume.) After enabling, the API root is live at
|
||||
`http://auth.${BASE_DOMAIN}/api/yggdrasil`.
|
||||
5. Each player: register on the BSS site, add a character whose name == their
|
||||
in-game player name, upload a skin.
|
||||
6. Restart minecraft if it came up before the plugin was enabled.
|
||||
|
||||
## Client (Prism / authlib-injector)
|
||||
|
||||
- authlib-injector URL: `http://auth.${BASE_DOMAIN}/api/yggdrasil`
|
||||
- Login = BSS **email + password** (BSS uses email as the account id).
|
||||
- Must match the server's `-javaagent` arg exactly (same host + path).
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **`/api/yggdrasil`, not `/authlib-injector`.** Wrong path → silent "Invalid
|
||||
session". Server `JVM_OPTS` and every client must agree.
|
||||
- **ONLINE_MODE=TRUE.** authlib-injector only authenticates when online-mode is
|
||||
on; the server then validates the join against BSS. (The Drasl variant in this
|
||||
repo set FALSE — do not copy that here.)
|
||||
- **Secure profile (1.21+).** Override ships `ENFORCE_SECURE_PROFILE=FALSE` for
|
||||
safety. yggdrasil-api *does* sign profile keys, so TRUE may work — flip and
|
||||
test if signed chat matters; revert on "Invalid signature".
|
||||
- **APP_KEY must persist.** Set `BS_APP_KEY` in `.env`. Losing it invalidates
|
||||
all sessions and breaks encrypted data.
|
||||
- **DB is the source of truth.** `bs_db` volume holds accounts; `bs_storage`
|
||||
holds skins; `bs_plugins` holds the yggdrasil-api plugin. Back these up.
|
||||
- **Air-gap:** the plugin market needs internet. Install + enable yggdrasil-api
|
||||
while online (it persists in `bs_plugins`), or stage the plugin manually.
|
||||
|
||||
## Image note
|
||||
|
||||
`azusamikan/blessing-skin-server-docker:latest` is a community image and the
|
||||
env-var names (`DB_*`, `APP_KEY`) may differ slightly by tag — if auto-config
|
||||
doesn't take, the web wizard is the reliable path. Official source:
|
||||
https://github.com/bs-community/blessing-skin-server ,
|
||||
plugin: https://github.com/bs-community/yggdrasil-api , authlib-injector setup:
|
||||
https://github.com/bs-community/blessing-skin-manual/blob/master/man/yggdrasil-api/authlib-injector.md
|
||||
Reference in New Issue
Block a user