<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>安雨落的小站</title><description>记录技术与生活</description><link>https://blog.anyul.cn/</link><language>zh_CN</language><item><title>失落的龙约私服部署教程</title><link>https://blog.anyul.cn/posts/dragalia-private-server/</link><guid isPermaLink="true">https://blog.anyul.cn/posts/dragalia-private-server/</guid><description>使用开源项目 Dawnshard 与 Docker Compose，在自己的服务器上部署失落的龙约私服：服务端、网页前端、反向代理与客户端连接的完整流程。</description><pubDate>Thu, 03 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;《失落的龙约》（Dragalia Lost）是任天堂与 Cygames 合作推出的手游，已于 2022 年 11 月 30 日停服。社区通过逆向工程实现了服务器模拟器，让这款游戏能在私人服务器上继续运行。目前主要的模拟器项目是 &lt;a href=&quot;https://github.com/SapiensAnatis/Dawnshard&quot;&gt;Dawnshard&lt;/a&gt;（C# / ASP.NET Core，MIT 协议），配套的账号认证服务是 &lt;a href=&quot;https://github.com/DragaliaLostRevival/DragaliaBaasServer&quot;&gt;DragaliaBaas&lt;/a&gt;，客户端改版工具是 LukeFZ 的 &lt;a href=&quot;https://github.com/LukeFZ/DragaliPatch&quot;&gt;Dragalipatch&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;本文基于上述项目的官方自托管文档，介绍在一张 VPS 上部署完整私服的流程：最小服务端 → 网页前端与反向代理 → 域名与 HTTPS → 客户端连接 → 日常维护。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING] 免责声明
失落的龙约的商标与全部游戏资源归任天堂、Cygames 所有。部署私服仅供个人学习与 Preservation 研究用途，请勿将服务对公众开放运营、不要分发游戏客户端与资源文件。由此产生的一切后果自行承担。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
游戏服务端需要真实的服务器（VPS 或家用机）运行 Docker。本文示例中的域名 &lt;code&gt;dl.example.com&lt;/code&gt; 与 IP &lt;code&gt;203.0.113.10&lt;/code&gt; 均为占位符，部署时替换成自己的值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;准备工作&lt;/h2&gt;
&lt;p&gt;开始之前，确认以下条件全部满足：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;要求&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;服务器&lt;/td&gt;
&lt;td&gt;1 台 VPS，2 核 2G 起&lt;/td&gt;
&lt;td&gt;游戏资源默认走社区公共 CDN，服务器本身压力不大&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;操作系统&lt;/td&gt;
&lt;td&gt;Ubuntu 22.04 / Debian 12 等&lt;/td&gt;
&lt;td&gt;能装 Docker 即可&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;Docker Engine + Compose 插件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker compose version&lt;/code&gt; 能输出版本号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;域名（可选）&lt;/td&gt;
&lt;td&gt;一个解析到服务器的子域名&lt;/td&gt;
&lt;td&gt;公网部署强烈建议，配 HTTPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;客户端&lt;/td&gt;
&lt;td&gt;Android 设备或模拟器&lt;/td&gt;
&lt;td&gt;配合 Dragalipatch 改服务器地址&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;安装 Docker（以 Debian/Ubuntu 为例，已安装可跳过）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -fsSL https://get.docker.com | sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建工作目录，后续所有文件都放在这里：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p ~/dragalia &amp;amp;&amp;amp; cd ~/dragalia
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第一步：最小可用服务端&lt;/h2&gt;
&lt;p&gt;这一步启动三个容器：游戏 API（&lt;code&gt;dragaliaapi&lt;/code&gt;）、PostgreSQL 数据库、Redis 缓存。&lt;/p&gt;
&lt;p&gt;新建 &lt;code&gt;docker-compose.yml&lt;/code&gt;，内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;volumes:
  pgdata:
services:
  dragaliaapi:
    image: ghcr.io/sapiensanatis/dragalia-api:4.0.59
    environment:
      - ConnectionStrings__Postgres=Host=postgres;User ID=${POSTGRES_USER};Password=${POSTGRES_PASSWORD};Database=${POSTGRES_DB}
      - ConnectionStrings__Redis=redis
    ports:
      - &quot;80:8080&quot; # 监听 80 端口；公网 HTTP 入口
    env_file:
      - .env
  postgres:
    hostname: postgres
    image: postgres:17
    env_file:
      - .env
    volumes:
      - pgdata:/var/lib/postgresql/data
  redis:
    hostname: redis
    image: redis:8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;镜像 tag &lt;code&gt;4.0.59&lt;/code&gt; 是写作时的版本。官方更新较频繁，部署前到 &lt;a href=&quot;https://github.com/SapiensAnatis/Dawnshard/pkgs/container/dragalia-api&quot;&gt;package 页面&lt;/a&gt;确认最新 tag 并替换。&lt;/p&gt;
&lt;p&gt;在同目录新建 &lt;code&gt;.env&lt;/code&gt;，填入自己的凭据：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# PostgreSQL 连接密码（必填）
POSTGRES_PASSWORD=&amp;lt;自定义强密码&amp;gt;
# PostgreSQL 用户名
POSTGRES_USER=postgres
# PostgreSQL 数据库名
POSTGRES_DB=DragaliaAPI
# 管理端点（如手动导入存档）的 Bearer Token
DEVELOPER_TOKEN=&amp;lt;自定义随机 Token&amp;gt;
# 日志上下文中的主机名，可留空
HOSTNAME=
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;code&gt;.env&lt;/code&gt; 里的密码和 Token 必须改成自己的随机值，不要照抄任何文档里的示例值，也不要把 &lt;code&gt;.env&lt;/code&gt; 提交到公开仓库。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;启动服务：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;验证部署结果。浏览器访问 &lt;code&gt;http://203.0.113.10/health&lt;/code&gt;，三个检查项均为 &lt;code&gt;Healthy&lt;/code&gt; 即为成功：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;status&quot;: &quot;Healthy&quot;,
  &quot;results&quot;: {
    &quot;self&quot;: { &quot;status&quot;: &quot;Healthy&quot; },
    &quot;ApiContext&quot;: { &quot;status&quot;: &quot;Healthy&quot; },
    &quot;Redis&quot;: { &quot;status&quot;: &quot;Healthy&quot; }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;任何一项不是 &lt;code&gt;Healthy&lt;/code&gt;，先用 &lt;code&gt;docker compose logs dragaliaapi&lt;/code&gt; 查看日志，再按文末「故障排查」处理。&lt;/p&gt;
&lt;h2&gt;第二步：网页前端 + 反向代理&lt;/h2&gt;
&lt;p&gt;第一步的裸 API 只适合本机验证。公网部署需要再加两个组件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Caddy&lt;/strong&gt; 反向代理：API 不支持 CORS，网页前端和游戏 API 必须从同一个域名、同一个端口对外服务，由 Caddy 按路径分发；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dawnshard-website&lt;/strong&gt;：官方网页前端，提供公告、排行、存档管理等页面。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;修改 &lt;code&gt;docker-compose.yml&lt;/code&gt;：删掉 &lt;code&gt;dragaliaapi&lt;/code&gt; 的 &lt;code&gt;ports&lt;/code&gt; 段（80 端口让给 Caddy），加入 &lt;code&gt;caddy&lt;/code&gt; 和 &lt;code&gt;website&lt;/code&gt; 两个服务：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;volumes:
  pgdata:
  caddydata:
services:
  caddy:
    image: docker.io/caddy:2
    ports:
      - &quot;80:80&quot;
    volumes:
      - ./config:/etc/caddy  # Caddyfile
      - caddydata:/data      # 证书等持久化数据

  dragaliaapi:
    image: ghcr.io/sapiensanatis/dragalia-api:4.0.59
    environment:
      - ConnectionStrings__Postgres=Host=postgres;User ID=${POSTGRES_USER};Password=${POSTGRES_PASSWORD};Database=${POSTGRES_DB}
      - ConnectionStrings__Redis=redis
    env_file:
      - .env

  website:
    image: ghcr.io/sapiensanatis/dawnshard-website:1.0.138
    environment:
      - DAWNSHARD_API_URL_SSR=http://dragaliaapi:8080

  postgres:
    hostname: postgres
    image: postgres:17
    env_file:
      - .env
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    hostname: redis
    image: redis:8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建 Caddy 配置文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p ./config &amp;amp;&amp;amp; touch ./config/Caddyfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Caddyfile&lt;/code&gt; 内容如下。游戏客户端请求的路径前缀是固定的，必须逐条转发给 API，其余流量交给网页前端：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:80 {
	# 屏蔽健康检查端点的外部访问
	respond /health 404
	respond /ping 404
	respond /metrics 404
	reverse_proxy /api/* dragaliaapi:8080               # 网页前端调用的 API
	reverse_proxy /2.19.0_20220714193707/* dragaliaapi:8080  # 安卓客户端
	reverse_proxy /2.19.0_20220719103923/* dragaliaapi:8080  # iOS 客户端
	reverse_proxy /dragalipatch/config dragaliaapi:8080      # Dragalipatch 配置
	reverse_proxy website:3000                          # 其余流量给网页前端
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重启整套服务：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;浏览器访问 &lt;code&gt;http://203.0.113.10&lt;/code&gt;，能看到网页前端即为成功。前端「新闻」页面此时内容为空是正常现象（数据库还没有公告数据）；只要页面能正常渲染，就说明前端、API、数据库的链路已通。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
API 与网页前端的镜像版本没有兼容性保证。升级时把两个镜像都更到同期发布的最新版，是最稳妥的做法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;第三步：域名与 HTTPS&lt;/h2&gt;
&lt;p&gt;公网开放时，务必启用 HTTPS。Caddy 内置 ACME 客户端，可以自动签发 Let&apos;s Encrypt 证书，共四步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在域名服务商处添加 A 记录，把 &lt;code&gt;dl.example.com&lt;/code&gt; 解析到 &lt;code&gt;203.0.113.10&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;把 &lt;code&gt;Caddyfile&lt;/code&gt; 第一行的 &lt;code&gt;:80&lt;/code&gt; 改成 &lt;code&gt;dl.example.com&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;docker-compose.yml&lt;/code&gt; 的 &lt;code&gt;caddy&lt;/code&gt; 服务中追加 &lt;code&gt;- &quot;443:443&quot;&lt;/code&gt; 端口映射；&lt;/li&gt;
&lt;li&gt;重启服务：&lt;code&gt;docker compose up -d&lt;/code&gt;，等待 Caddy 自动完成 ACME 验证（日志出现 certificate obtained 即可）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;完成后访问 &lt;code&gt;https://dl.example.com&lt;/code&gt; 确认证书生效。使用自签证书、已购证书或套 Cloudflare 代理等场景的配置方式不同，参考 &lt;a href=&quot;https://caddyserver.com/docs&quot;&gt;Caddy 官方文档&lt;/a&gt;调整。&lt;/p&gt;
&lt;h2&gt;第四步：客户端连接&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在 Android 设备（或模拟器）上安装原版游戏与 &lt;a href=&quot;https://github.com/LukeFZ/DragaliPatch/releases/latest&quot;&gt;Dragalipatch&lt;/a&gt;；&lt;/li&gt;
&lt;li&gt;打开 Dragalipatch，服务器地址填 &lt;code&gt;https://dl.example.com&lt;/code&gt;（必须带 &lt;code&gt;http://&lt;/code&gt; 或 &lt;code&gt;https://&lt;/code&gt; 前缀，不带前缀时 Dragalipatch 默认按 HTTPS 处理）；&lt;/li&gt;
&lt;li&gt;资源 CDN 保持默认的公共源即可，自建资源服务属于进阶内容（见文末）；&lt;/li&gt;
&lt;li&gt;启动游戏，注册账号并登录。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;账号认证由 BaaS 服务负责。本文的部署方式不包含自建 BaaS，客户端默认使用社区托管的公共实例；如果希望账号体系完全自托管，参考 &lt;a href=&quot;https://github.com/DragaliaLostRevival/DragaliaBaasServer&quot;&gt;DragaliaBaasServer&lt;/a&gt; 项目自行部署，属于进阶内容。&lt;/p&gt;
&lt;h2&gt;日常维护&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;升级版本&lt;/strong&gt;：到 package 页面确认 &lt;code&gt;dragalia-api&lt;/code&gt; 与 &lt;code&gt;dawnshard-website&lt;/code&gt; 的最新 tag，更新 &lt;code&gt;docker-compose.yml&lt;/code&gt; 中的镜像 tag，然后：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose down
docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;备份数据&lt;/strong&gt;：玩家数据全部存放在 &lt;code&gt;pgdata&lt;/code&gt; 卷中。定期执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose exec postgres pg_dump -U postgres DragaliaAPI &amp;gt; backup_$(date +%F).sql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;查看日志&lt;/strong&gt;：&lt;code&gt;docker compose logs -f dragaliaapi&lt;/code&gt;。正常的 API 请求日志形如 &lt;code&gt;HTTP GET /api/news responded 200&lt;/code&gt;，出现 500 或持续重启再排查。&lt;/p&gt;
&lt;h2&gt;故障排查&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;80 端口绑定失败&lt;/strong&gt;。Linux 上以 rootless 模式运行 Docker 时，绑定 1024 以下端口会被拒绝，报错包含 &lt;code&gt;cannot expose privileged port 80&lt;/code&gt;。两种解法任选其一：把 compose 里的端口映射改成 &lt;code&gt;8080:80&lt;/code&gt;（Caddy 对外仍走反代或改由外层网关承接），或按官方文档把 &lt;code&gt;net.ipv4.ip_unprivileged_port_start=80&lt;/code&gt; 写入 &lt;code&gt;/etc/sysctl.d/&lt;/code&gt; 后执行 &lt;code&gt;sudo sysctl --system&lt;/code&gt;。修改内核参数前先确认自己了解安全影响。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;健康检查不通过&lt;/strong&gt;。&lt;code&gt;/health&lt;/code&gt; 中 &lt;code&gt;ApiContext&lt;/code&gt; 不健康时，通常是数据库连接信息有误：检查 &lt;code&gt;.env&lt;/code&gt; 中的 &lt;code&gt;POSTGRES_*&lt;/code&gt; 三项与 compose 中连接字符串是否一致。&lt;code&gt;Redis&lt;/code&gt; 不健康时，检查 redis 容器是否启动、&lt;code&gt;ConnectionStrings__Redis&lt;/code&gt; 是否为 &lt;code&gt;redis&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;客户端连不上&lt;/strong&gt;。按顺序检查：域名解析是否生效（&lt;code&gt;ping dl.example.com&lt;/code&gt; 返回服务器 IP）、Caddy 是否拿到证书、&lt;code&gt;Caddyfile&lt;/code&gt; 中两条版本号路径转发是否原样保留（路径中的版本号不是占位符，不能改）。&lt;/p&gt;
&lt;h2&gt;已知边界&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;联机（共斗）&lt;/strong&gt;：需要额外部署 Photon Server，官方授权费用较高，个人部署通常只玩单机内容；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自建资源 CDN&lt;/strong&gt;：全量资源约 10 GB，含历史活动资源超过 50 GB，且分发游戏资源存在版权风险，默认公共 CDN 不可用时再考虑，方案见官方 Wiki 的 Assets 一节；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;版本兼容&lt;/strong&gt;：API 不遵循语义化版本，升级前留意官方公告，保留旧镜像 tag 以便回滚。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/SapiensAnatis/Dawnshard&quot;&gt;Dawnshard 仓库&lt;/a&gt; · &lt;a href=&quot;https://github.com/SapiensAnatis/Dawnshard/wiki&quot;&gt;自托管指南（Wiki）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/DragaliaLostRevival/DragaliaBaasServer&quot;&gt;DragaliaBaasServer&lt;/a&gt; · &lt;a href=&quot;https://github.com/LukeFZ/DragaliPatch&quot;&gt;Dragalipatch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://caddyserver.com/docs&quot;&gt;Caddy 文档&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后，感谢 Dawnshard 及社区逆向团队的持续维护。&lt;/p&gt;
</content:encoded></item></channel></rss>