最近用上了华为云的ECS,基于aarch64(arm64)架构,而Minecraft使用Java编写,Java在各个平台都有虚拟机,通过Docker直接运行一个Minecraft server很简单。本文所实现的则是通过docker compose将Minecraft和Blessing Skin(附带yggdrasil-api插件)的相关容器编排到一起进行运行和管理。

介绍

开始之前,先分别介绍本文所涉及的几个名词。

Minecraft:《我的世界》(英语:Minecraft,港台译作“当个创世神”)是一款沙盒游戏,最初由瑞典游戏设计师马库斯·阿列克谢·泊松(别名Notch)单独开发,随后由2009年成立的瑞典公司Mojang开发并发行。玩家可以在一个随机生成的3D世界内,以带材质贴图的立方体为基础进行游戏。游戏中的其他特色包括探索世界、采集资源、合成物品及生存冒险等。游戏有多种模式,生存模式中玩家必须维持生命并采集资源来打造自己的世界;创造模式中玩家拥有无限的资源并可飞行,大多数玩家会使用此模式来建造大型建筑;冒险模式中玩家可在其他玩家定制的地图中游玩。游戏的Java版以其强大的第三方拓展模块(mod)而知名,它们可为游戏添加各种新的对象、角色和功能。(来源:维基百科)

Blessing Skin: Blessing Skin 是一款能让用户上传、管理和分享 Minecraft 皮肤和披风的皮肤站Web 应用程序。与修改游戏材质包不同的是,所有人都能在游戏中看到各自的皮肤和披风(当然,前提是玩家们要使用同一个皮肤站)。Blessing Skin 是一个开源的 PHP 项目,这意味着可以自由地在你的服务器上部署它。(来源:Blessing Skin GitHub主页 项目作者:@printempw)

authlib-injector:简单来讲,就是通过运行时修改 authlib 实现游戏外登录,并为 Yggdrasil 服务端的实现提供规范。Mojang(开发Minecraft的公司)在代码中写死了登录中必须要访问他们的官方服务器,authlib-injector通过在Minecraft服务器运行时替换相关的字节码为自己的服务器地址,让用户可以访问自己的私有服务器。(来源:authlib-injector GitHub主页

Yggdrasil API for Blessing Skin:是Blessing Skin的一个插件,基本实现了 Yggdrasil API 规范,可与 authlib-injector 等 authlib hook 配合使用实现外置登录系统。(来源:Yggdrasil API for Blessing Skin GitHub主页

编排

镜像

因为服务器是aarch64架构,也要考虑Docker镜像的架构,否则在错误的架构上运行容器就会出现类似exec format error的提示。

经过测试,编排中可以直接使用的Docker Hub aarch64架构镜像有以下几个,其中itzg/minecraft-server:multiarch镜像其实有很多配置项,具体配置可以参考它的项目主页,本文仅以运行原生Minecraft Server为例。 mariadb:latestredis:4.0用于存储皮肤站的相关数据:

  • itzg/minecraft-server:multiarch
  • mariadb:latest
  • redis:4.0

皮肤站使用了php的相关依赖,在Docker Hub上翻了翻,并没有现成的镜像可以使用,于是根据已有的nginx-php-fpm镜像edofede/nginx-php-fpm:latest自己构建了一个,Dockerfile如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
FROM edofede/nginx-php-fpm:latest

RUN sed -i "s@http://dl-cdn.alpinelinux.org/@https://repo.huaweicloud.com/@g" /etc/apk/repositories \
  && apk update \
  && apk --no-cache add \
    php7-pdo \
    php7-openssl \
    php7-mbstring \
    php7-tokenizer \
    php7-gd \
    php7-ctype \
    php7-fileinfo \
    php7-zip \
    php7-session \
    php7-pdo_mysql \
    php7-iconv

EXPOSE 80

保存好Dockerfile之后在同一目录构建镜像koi/nginx-php-fpm:latest

1
docker build -t koi/nginx-php-fpm .

数据和配置

数据目录结构如下:

1
2
3
4
5
6
7
$ tree -L 1  
.
├── blessing-skin-server
├── data
├── docker-compose.yml
├── mysql
└── nginx

blessing-skin-server:从项目Release页面下载所需版本发布包,并解压到此目录。需要说明的是,Yggdrasil API插件可以不用先安装,可以等配置好服务启动之后在皮肤站的插件市场中在线安装。

皮肤站默认配置文件为.env,可以复制一份模板文件

1
cp .env.example .env

配置mysql的用户、密码、数据库等相关数据。

data:Minecraft Server运行时挂载,存储相关配置。需要提前下载好authlib-injector-1.1.26-41a7a47.jarminecraft_server.1.15.2.jar到data目录,注意需要对应两个jar包在下文中docker-compose.yml中的名称。

mysql:存储皮肤站的用户数据库。

nginx:存储皮肤站的nginx配置,配置文件名为default,不可修改文件名称(nginx容器通过软链使用此配置)。详细配置内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/public;
        index index.html index.htm index.php;

        server_name _;

        location / {
                try_files $uri $uri/ /index.php?$query_string;
                autoindex on;
        }

        location ~ \.php$ {
                fastcgi_split_path_info ^(.+?\.php)(/.*)$;
                if (!-f $document_root$fastcgi_script_name) {
                        return 404;
                }
                fastcgi_pass unix:/run/php/php7.0-fpm.sock;
                fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
                include fastcgi_params;
        }

        location ~ /\.ht {
                deny all;
        }

        location = /404.html {
                internal;
        }
}

这里没有使用域名,也没有启用HTTPS,有需要的话可以自己修改。

docker-compose.yml

直接上yaml配置文件,一目了然。

Minecraft service的JVM_XX_OPTS环境变量中有个host:porthost修改成你自己的服务器地址就好,port对应skin-website service中的port,另外修改mysql的用户密码为你配置在.env中的用户和密码。

注意修改服务器的安全策略,放通皮肤站(port端口)和Minecraft Server(25565端口)的访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
version: '3'

services:
  db:
    image: mariadb
    restart: always
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: xxx
      MYSQL_DATABASE: blessingskin
      MYSQL_USER: koi
      MYSQL_PASSWORD: xxx
  redis:
    image: redis:4.0
    restart: always
  skin-website:
    image: koi/nginx-php-fpm:latest
    ports:
      - "port:80"
    volumes:
      - ./nginx:/etc/nginx/sites-available
      - ./blessing-skin-server:/var/www
    restart: always
    links:
      - db
      - redis
    depends_on:
      - db
      - redis
  minecraft:
    image: itzg/minecraft-server:multiarch
    ports:
      - "25565:25565"
    volumes:
      - ./data:/data
    environment:
      EULA: "TRUE"
      VERSION: "1.15.2"
      TYPE: "CUSTOM"
      CUSTOM_SERVER: "/data/minecraft_server.1.15.2.jar"
      JVM_XX_OPTS: "-javaagent:/data/authlib-injector-1.1.26-41a7a47.jar=http://host:port/api/yggdrasil"
    restart: always
    links:
      - skin-website

运行

根据Blessing Skin的安装指南,首次运行时需要生成app key,在docker-compose.yml文件所在目录执行以下命令

1
docker run -it --rm -v ./blessing-skin-server:/blessing-skin-server koi/nginx-php-fpm:latest cd /blessing-skin-server && php artisan key:generate

即可生成app key.

进入到docker-compose.yml文件所在目录,执行

1
docker-compose up -d

查看服务状态:

1
2
3
4
5
6
7
$ docker-compose ps
          Name                        Command                  State                      Ports               
--------------------------------------------------------------------------------------------------------------
minecraft_db_1             docker-entrypoint.sh mysqld      Up             3306/tcp                           
minecraft_minecraft_1      /start                           Up (healthy)   0.0.0.0:25565->25565/tcp, 25575/tcp
minecraft_redis_1          docker-entrypoint.sh redis ...   Up             6379/tcp                           
minecraft_skin-website_1   /entrypoint.sh                   Up             0.0.0.0:8080->80/tcp  

容器minecraft_minecraft_1的State为Up (healthy)时,说明Minecraft服务器已经正常启动。

此时没有问题的话,就能进入皮肤站主页(即host:port),确认相关配置并注册用户和你的Minecraft角色了,同时也不要忘了在插件市场中启用Yggdrasil API插件。

Play

使用支持authlib-injector登录的客户端,比如HMCL,添加对应的api地址,如下图所示:

添加认证服务器

进入游戏后,就可以添加你的Server,进入属于“你的世界”,快去通知朋友们一起玩耍吧!