bs-community/blessing-skin-server
Blessing Skin Server is an open-source Minecraft skin hosting platform built on Laravel. It offers user registration, skin and cape uploads, an admin panel, API support, and a plugin ecosystem for customizing your community site.
Blessing Skin Server is a Laravel application, not a Composer library you add to an existing app. The practical first step is to treat it as a self-hosted service.
Minimal local setup:
git clone https://github.com/bs-community/blessing-skin-server.git
cd blessing-skin-server
composer install --no-dev --optimize-autoloader
cp .env.example .env
php artisan key:generate
Then configure .env for your database and public URL, especially APP_URL, and complete the installer flow documented for your version. After installation, create an admin account and log in to the admin panel.
Where to look first:
routes/ — web, API, and Yggdrasil-compatible endpoints.app/Http/Controllers/ — skin upload, user, admin, and API behavior.resources/views/ — Blade templates and theme override points.plugins/ and themes/ — extension surfaces.config/ and .env — storage, database, cache, and app URL settings.composer.json — PHP/Laravel version constraints; check this before deploying on modern PHP.First real use case: host a skin site for a small offline Minecraft community, upload skins through the web UI, then point clients at the site using authlib-injector. Verify the Yggdrasil endpoints with curl before involving Minecraft clients.
Standalone service deployment. Run Nginx/Apache + PHP-FPM + MySQL/PostgreSQL/SQLite behind TLS. Persist both the database and storage/; skin textures and generated assets live on disk. If using Docker, treat the container as ephemeral and mount persistent volumes.
Configure clients through authlib-injector. The day-to-day integration is usually:
java -javaagent:authlib-injector.jar=https://skins.example.com/api/yggdrasil \
-jar server.jar
Confirm the exact Yggdrasil path from routes/api.php in your version. Keep APP_URL and HTTPS correct, because texture URLs are generated from the app URL.
Extend with plugins, not core edits. Put custom behavior in plugins/ so upgrades remain tractable. Use the plugin event/hook system for uploads, user registration, and rendering changes. If you need custom routes or admin pages, register them from a plugin rather than editing routes/web.php.
Theme through Blade overrides. Build themes in themes/ and override views/assets rather than editing resources/views directly. This keeps upstream updates mergeable.
Use the app as an internal API. For custom launchers or dashboards, call the Yggdrasil-compatible endpoints and skin texture URLs. For internal tooling, add authenticated JSON routes via a plugin and reuse Laravel models/controllers.
Automate operations. Use php artisan optimize in production, php artisan optimize:clear after config/plugin/theme changes, and scheduled database + storage backups. Monitor storage/logs/laravel.log.
composer require-able. Do not try to embed it into another Laravel app; namespaces, routes, migrations, and assets assume it owns the application.composer.json, run composer audit, and stage upgrades carefully. If you need long-term maintenance, expect to fork or pin dependencies.APP_URL mistakes break skins. Wrong scheme/host produces broken texture URLs and confusing authlib-injector failures. Behind a proxy, configure trusted proxies and HTTPS correctly.storage/ and bootstrap/cache/. Do not expose .env or storage internals via web server config.php artisan optimize:clear locally and after deployments.upload_max_filesize and post_max_size; validate skin/cape dimensions and image formats. Large texture libraries need storage planning and possibly CDN/cache headers.APP_DEBUG=true in development, never in production. Use storage/logs/laravel.log and failed-job tables for diagnosis.How can I help you explore Laravel packages today?