爷青回——运用Docker来部署Emulatorjs

人一忙就容易变懒,距离上次更新博文已经超过一年,在这一年里,无需赘言,我们都经历了太多。我逐渐感受到成长给人留下的印记,不但不再有什么个人追求,对于横空而来的各种负担,我们都习惯了坦然面对,连呻吟都是多余了。

Anyway,前段时间通过frps自托管了两台主机,内存插到满,一台装了个Kali,顺道部署了和孩子一起玩的Minecraft服务,另一台装了Ubuntu Server以后一直闲置,在逛一个叫做awesome-selfhosted的github的时候,发现了一个很不错的publisher,叫linuxserver,这个组织维护着大量docker镜像,主要为自建服务的用户提供方便,他们的一个容器瞬间引起了我的注意。

碉堡了有没有

于是立即着手pull,拖下来这个镜像以后,研究了一番文档,按照官方给的docker-cli运行:

docker run -d \
--name=emulatorjs \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Shanghai \
-e SUBFOLDER=/ #optional \
-p 3000:3000 \
-p 80:80 \
-p 4001:4001 #optional \
-v /path/to/config:/config \
-v /path/to/data:/data \
--restart unless-stopped \
lscr.io/linuxserver/emulatorjs:latest

跑起来了,注意那个80:80如果你没有国内备案主机的话,需要修改端口,登上3000的后台,要我通过内建的IPFS服务下载前端的美术素材,点了Download没有反应,一直卡在下载NDS.mp4这个文件,一开始怀疑是IPFS的问题,又去研究容器内科学上网,折腾一番以后容器里已经可以curl到科学IP,可是还是卡这个下载,于是用netstat看容器里的链接情况,连接各种peers没有问题,又在容器内部试了下IPFSdaemon的自测功能,发现可以抓下文件,映射的两个目录data和config也都通过chmod改了权限,PUID/PGID也调整过了,这就很费解么?去discord提问,无解,搜了半天发现只有一个人提问遇到有类似问题,但是似乎答案也不明确。继续回去爬官方文档,直到发现:

Umask for running applications
For all of our images we provide the ability to override the default umask settings for services started within the containers using the optional -e UMASK=022 setting. Keep in mind umask is not chmod it subtracts from permissions based on it's value it does not add. Please read up here before asking for support.

这段说明似乎每一个linuxserver的发行里都有,从来没有特别注意过,由于不是linux专业用户,对于这些复杂概念也没有了解,本着死马活马都能吃的原则,在docker-cli里加入这行参数,下载成功!Voila~~~

接下来是补充,这个容器本身没有身份校验的模块,如果担心好事者搞乱你辛苦肝来RPG的存档,你可以尝试自己在docker内置的nginx里加两行验证。

对于几乎在每一台客户端都部署retrogaming然而极少玩耍的我而言,这个host的意义是显而易见的,你终于可以整合你的碎片时间,交替利用各种不同的terminal,肝完对于过去,对于现在,包括将来而言都极为奢侈的RPG大作。

感谢linuxserver和原作ethanobrien,愿你和我永远年轻。

爷青回——运用Docker来部署Emulatorjs》有23个想法

  1. 张宝says

    您好,请问您可以同步一份main文件夹下的文件给我么,我不知道什么原因也卡在下载这里了,不知道是不是因为ipfs被墙的缘故,弄了一天也没有什么变化。
    谢谢您。

    Reply
    1. 樊彬says

      已邮件回复您。

      Reply
  2. jokersays

    我使用的群晖,已经出墙了,而且也加了umask 的环境变量,还是卡在下载mp4上

    Reply
    1. jokersays

      您好,可以共享一份下载文件嘛?

      Reply
      1. 樊彬says

        已发邮件给您。

        Reply
  3. mir wangsays

    群晖docker 能发一份安装方法吗

    Reply
  4. Benzsays

    大佬你好啊,我也是卡在了初始下载那了,可否同求一份data目录包?感谢大佬啊 ❤️

    Reply
    1. 樊彬says

      奔驰兄你好,发邮件的同学不少,大家很多都是遇到了和我一样的问题,我把之前的回复和大家的交流成果一起贴在下面:

      这个docker通过ipfs下载模拟器目录结构和美术素材,我目前已经在目录里移进ROM了,几十G超级大,发邮件发不动。

      您可以试试排错,必须解决这个卡住问题才能正常用,我想大概率是文件生成权限问题,和我遇到的一样,因为这个不解决,你就算直接拖进文件去也跑不起来,这个模拟器运行会生成新文件,包括你将来自己存档。

      您可以ssh到你运行的主机,用命令行进入你运行的docker,类似sudo docker exec -it emulatorjs /bin/bash,

      然后在里面运行ipfsdaemon有一个自测功能,打入ipfs init然后按照弹出的那个测试指令就可以查看ipfs节点上的一个测试文档,或者直接用netstat -nat看下有没有和ipfs的各种服务器握手,如果看到有和大量服务器的4001端口建立了连接,你的ipfs应该是正常的,这个我也是研究了才知道,ipfs目前是不被墙的。

      如果ipfs测试没问题,就请按上文加入docker运行的那个umask环境变量。

      我就尝试了这两种方法就出坑了。

      之前留言的网友提到,他从github里面发现了所需要下载的default文件的hash值,通过ipfs的公共网关下载下来了所需的文件,导入docker后可以继续进行了,这也是解决办法之一,遗憾不能帮到您,希望您顺利解决。

      Reply
      1. Benzsays

        感谢大佬提供了思路,我终于终于终于弄好了。真的是老费劲了。简单分享下心得吧。我的环境可能跟大佬们不太一样,我用了一台Win11系统的小盒子充当家庭服务器,安装了 docker desktop for windows。所以我这没有linux的文件权限问题,umask环境变量没有作用。很奇怪,如果我不在win11主机里挂个梯,ipfs就不会有任何4001端口的握手连接,而且还会在docker的log里打入一条错误“failed to bootstrap (no peers found)”。在win11挂了梯并必须开启tun模式后才正常。而即使ipfs正常了,下载初始文件的过程中也是偶尔报错,于是我不断重复刷新页面、重启container、点击Download,重复了无数次,最后还是剩下十几个文件,无论怎么重试都没有下载成功。

        最后我想起了大佬的最后提示:有网友从github里面发现了初始文件的hash值,用ipfs下载所需文件。于是我决定上github看看。反复查找后总算被我发现了hash表:

        https://github.com/linuxserver/emulatorjs/blob/master/metadata/default_files.json

        然后我下载安装了 ipfs desktop ,准备用它把剩下的文件下载下来。
        首先需要知道还剩下哪些文件没弄下来,这个简单,没弄下来的文件要么是0字节要么不存在。对于0字节的文件,直接用Win11资源管理器的搜索功能搜索 /data 目录就好了(这个data目录就是docker命令-v参数映射出来的目录,我这里映射到了我的D盘某处)。对于不存在的文件,我首先把上述的default_files.json下载下来,复制一份并改名为default_files.txt,然后用VSCode的查找替换功能把json内容变成每行一条路径这样:

        ./data/main/videos/nds.mp4
        ./data/main/videos/psx.mp4
        ./data/main/videos/pce.mp4
        。。。

        然后写一个批处理文件:

        @echo off
        for /f %%f in (default_files.txt) do if not exist %%f echo %%f
        pause

        执行这个批处理,就展示出来哪些文件没下载了。然后逐一从default_files.json拿到对应的hash贴到 ipfs desktop 里下载,下载后直接在Windows资源管理器里复制到对应目录。

        最后进入emulatorjs的后台页面,显示265个初始文件都有了。
        emulatorjs有一点比较笨,就是这时如果你手贱再点击“DL/Update”,之前额外下载的那些文件会被抹掉并重新下载,然后下载失败,那文件会再次丢失。因为ipfs的缓存里面没有这文件。
        为避免这个情况,我把 ipfs desktop 的缓存给复制到这个 docker 的ipfs缓存里,这样点击“DL/Update”也能很快出现“Downloaded All Files”了。

        ipfs desktop 的缓存在 C:\User\\.ipfs\blocks。
        docker的ipfs缓存在映射出来的 /data/.ipfs/blocks。

        直到现在,有个问题我还是没有搞懂。我的docker的ipfs还是没有搞通,但是 ipfs desktop 用着却是非常畅通,它们在同一台物理机器,使用同一条网线,就一个在docker里面一个在docker的宿主系统。不过,我觉得不搞懂也没关系了吧。虽然除了初始文件,游戏的截图和封面也要用ipfs下载,不过我玩的游戏基本是网友汉化版,老外的封面数据库是不会有数据的,所以即使ipfs正常也不会有封面。所以也就没有关系了。

        另外还有一个坑:我的rom全是在7z压缩包里的,7z文件名不能用中文,否则会提示“????.7z”解压错误。不压缩的游戏rom可以用中文。

        最后,我把 /data 目录打了个包,上传到了百度网盘,里面包含初始文件和 ipfs 的缓存文件,理论上其他网友下载解压到 /data 即可路过初始文件下载的步骤。方便一下大家吧。

        链接:https://pan.baidu.com/s/15bDDd92ZLzo0U-3VV4CXYQ?pwd=benz 提取码:benz 。

        Reply
        1. 樊彬says

          奔驰大佬,您的评论被反垃圾插件误伤了,我已经恢复,感谢您的宝贵教程!

          Reply
        2. 樊彬says

          我印象docker容器和宿主在科学上有区别,宿主科学了容器不一定,容器在路由看来像是宿主并列交换机上的另一个宿主,想起叫vswitch什么的,因为搞懂这些对我要求太高,我当时直接在容器里科学了,后来发现还是卡下载,我就觉得这个和科学无关了,这个和启动docker容器时的参数有关,从您的案例里,看来ipfs确实也被从启动阶段封锁了可能的节点列表。要不几乎所有英语文档和反馈都没有反映过这个问题。
          感谢您更进一步的探索和造福!

          Reply
      2. Benzsays

        感谢大会提供思路,为什么我写了很长一篇回复却不显示?

        Reply
      3. Benzsays

        大佬,我准备弃坑了。。。因为我刚刚试验了一下,发现有个关键点跟我想象的不一样。我以为游戏存档会往服务器上保存,但是我试了一个经典gbc游戏(精灵宝可梦水晶版),发现存档是保存在浏览器本地的IndexedDB……换个浏览器或者清除浏览器数据,存档就没有了。so对我个人而言,这个项目瞬间失去了意义。

        Reply
        1. 樊彬says

          这个可以在不同终端上同步存档,你到控制端口,新建一个用户,打游戏打一半save state然后印象右上角可以推档到服务器,还可以下载回来,下载了以后回到模拟器load state就行了。

          Reply
        2. 樊彬says

          你可以在一个电脑上save state了推挡到服务器,然后手机打开控制后台先下载,再到游戏前台装载这个游戏,再load state试下,我印象这些操作说明里好像有。

          Reply
          1. Benzsays

            原来如此!!啊哈哈哈哈哈!!于是我回到坑里了

          2. 樊彬says

            玩的开心,祝好!

  5. tonysays

    大佬您好,我想拿这个emulatorjs做一些改造,兜了一圈发现分为了emulatorjs helper(也就是linux-server这个)和emulatorjs两个工程,我想修改emulatorjs的代码,但没有找到emulatorjs源码构建的方式,只找到了setup_dev.sh中从https://github.com/thelamer/emulatorjs拉了混淆过的代码下来。想问问您是否有了解

    Reply
    1. 樊彬says

      大佬您好,小弟不是开发人员,有关emulatorjs的源码,github上有官方页面,请参阅github.com/EmulatorJS/EmulatorJS,希望能帮到您。

      Reply
  6. tonysays

    好的,谢谢大佬

    Reply
  7. Danielsays

    作为一个后来者,我也补一个下载文件的tips吧

    首先,前面已经有人评论了关键的文件目录: https://github.com/linuxserver/emulatorjs/blob/master/metadata/default_files.json

    为了按照cid下载文件,我们可以使用cloudflare提供的便捷服务:
    比如文件目录里的第一个文件:
    {
    “file”:”/data/main/videos/nds.mp4″,
    “cid”:”QmXX9BebDhPr2oMuv5L9SizTwsbhvR9J3sYPMSKaRAu11Y”
    },

    我们直接把 https://cloudflare-ipfs.com/ipfs/QmXX9BebDhPr2oMuv5L9SizTwsbhvR9J3sYPMSKaRAu11Y 下载到/path/to/data/main/videos/nds.mp4就可以了

    不管是用curl命令来下载文件还是怎么的,方法多种多样

    Reply
    1. 樊彬says

      谢谢您的分享

      Reply

张宝进行回复 取消回复

邮箱地址不会被公开。 必填项已用*标注