gonic Docker Compose 部署实战

gonic v0.23.0 从零部署实录:编排文件逐项详解、演示曲库准备、首次启动日志三段证据(72 条迁移/配置回显/首扫 6 轨)、admin 改密、Subsonic API 明文与 token 双认证连通(含 stream md5 比特级校验)、客户端接入与排障实录。

gonicgonic音乐流媒体音频流媒体2026/10/28

gonic Docker Compose 部署实战

目标:在一台真实服务器上,用 Docker Compose 从零把 gonic v0.23.0 跑起来——准备曲库目录、编写编排文件、启动并验证首次扫描、初始化 admin 管理账号、用 Subsonic API 完成明文与 token 双认证连通性实测、触发扫描,最后给出 Web jukebox 与第三方客户端的接入说明和排障实录。本文全部命令与输出均为 2026-10-28 在 Ubuntu 24.04 服务器上的逐行实测照抄。产品介绍与选型背景见本专栏《gonic 介绍与选型指南》,逐项参数说明见《gonic 配置参数详解》,日常运维操作见《gonic 常用命令与运维实战(核心篇)》。

一、部署前置条件

本章先确认服务器的软硬件环境与端口、目录规划,避免「抄完编排文件却起不来」的返工。

1.1 运行环境

本次实测服务器的基线环境如下(逐行实测输出):

$ grep PRETTY /etc/os-release
PRETTY_NAME="Ubuntu 24.04.5 LTS"
$ uname -m
x86_64
$ docker version --format 'Engine {{.Server.Version}}'
Engine 29.9.2
$ docker compose version
Docker Compose version v5.6.1
$ df -h / | tail -1
/dev/sda2       443G  179G  246G  43% /

gonic 是 Go 编写的单二进制程序,官方制品 sentriz/gonic:v0.23.0 内已自带 ffmpeg 与 mpv,对宿主机几乎没有额外依赖——只要 Docker Engine 与 Compose 插件可用即可。磁盘方面,程序本体极小,真正占空间的是你的音乐文件与转码/封面缓存,实测机上剩余 246 GB 绰绰有余。

1.2 端口与目录规划

gonic 实例内默认监听 80 端口,需要映射到宿主机一个空闲端口。先用 ss 确认候选端口没被占用:

$ ss -ltn | grep -E '8133|8136|8137|8138|8140'
LISTEN 0      5            0.0.0.0:8133       0.0.0.0:*
LISTEN 0      4096         0.0.0.0:8136       0.0.0.0:*
LISTEN 0      4096         0.0.0.0:8137       0.0.0.0:*

本次规划使用 8137 端口对外提供服务(若你的机器上 8137 被占,可在 8138/8140 等空闲端口中任选一个,同步改编排文件即可)。

目录统一放在 /opt/data/quzuo/tmp/gonic/ 下,规划如下:

目录实例内挂载点用途
data//dataSQLite 数据库(曲库索引、用户、播放统计等全部状态)
music//music(只读)音乐文件目录
podcast//podcast播客下载目录
playlists//playlistsm3u 播放列表目录
cache//cache封面与转码产物缓存

💡 说明:把「数据库、音乐、播客、播放列表、缓存」拆成五个独立挂载点是官方推荐做法。其中音乐目录建议以只读(:ro)方式挂载——gonic 只消费音乐文件、从不改写它们,只读挂载能从机制上杜绝误操作;而播客、播放列表、缓存目录需要程序写入,必须保持可写。

二、编排文件详解

本章给出本次实测使用的完整编排文件,并逐段说明每个配置项的作用。在 /opt/data/quzuo/tmp/gonic/ 下新建 docker-compose.yml:

name: gonic-0230-stack

networks:
  gonic-net:
    external: true

services:
  gonic:
    image: sentriz/gonic:v0.23.0
    container_name: gonic-0.23.0-app
    restart: unless-stopped
    ports:
      - "8137:80"
    environment:
      - TZ=Asia/Shanghai
      - GONIC_MUSIC_PATH=/music
      - GONIC_PLAYLISTS_PATH=/playlists
      - GONIC_PODCAST_PATH=/podcast
      - GONIC_CACHE_PATH=/cache
      - GONIC_DB_PATH=/data/gonic.db
      - GONIC_SCAN_AT_START_ENABLED=true
    volumes:
      - ./data:/data
      - ./music:/music:ro
      - ./podcast:/podcast
      - ./playlists:/playlists
      - ./cache:/cache
    networks:
      gonic-net:
        ipv4_address: 10.89.57.10

逐段解读:

  • image: sentriz/gonic:v0.23.0:锁定官方制品的具体版本号,不用 latest——生产环境锁版本才能保证升级是「主动行为」而不是「重启抽奖」;
  • ports: 8137:80:把实例内 80 端口映射到宿主机 8137,后续 Web 管理界面与 Subsonic API 都走这个端口;
  • GONIC_* 环境变量:gonic 的全部配置项都支持「命令行参数 / 环境变量 / 配置文件」三通道,环境变量规则是把参数名大写、短横线换下划线、加 GONIC_ 前缀(如 scan-at-start-enabled → GONIC_SCAN_AT_START_ENABLED),完整对照表见《gonic 配置参数详解》;
  • GONIC_SCAN_AT_START_ENABLED=true:启动后立即做一次全量扫描,新部署时免去手动触发;
  • restart: unless-stopped:异常退出自动拉起,机器重启后服务自动恢复;
  • networks: gonic-net:使用预先创建的外部网络 gonic-net(10.89.57.0/24)并固定 IP 10.89.57.10;没有多服务互联需求时这段可以整段删掉,用默认网络即可。

💡 说明:GONIC_DB_PATH=/data/gonic.db 显式指定了 SQLite 数据库文件位置。gonic 的全部运行状态(曲库索引、用户账号、播放列表、播放计数、播客订阅)都在这一个文件里,这也意味着备份 gonic 约等于备份这一个文件,具体备份手法在《gonic 常用命令与运维实战(核心篇)》实测。

三、准备演示曲库

本章准备一个小型演示曲库,用于验证扫描、浏览与播放链路。gonic 对目录结构有一条硬约束:同一专辑的文件必须放在同一目录、同一目录的文件必须属于同一专辑——按「流派/艺术家/(年份) 专辑/音轨」组织即可稳稳满足。

本次实测曲库如下(2 位艺术家、3 张专辑、6 首音轨,覆盖 flac/mp3/opus/ogg 四种格式,逐行实测输出):

$ cd /opt/data/quzuo/tmp/gonic
$ find music -type f -printf '%10s  %p\n' | sort -k2
    413210  music/Electronic/Test Artist Two/(2023) Synth Waves/01 Neon Test.opus
    100995  music/Electronic/Test Artist Two/(2023) Synth Waves/02 Pulse Test.ogg
      2390  music/Electronic/Test Artist Two/(2023) Synth Waves/folder.jpg
    368150  music/Rock/Test Artist One/(2024) First Album/01 Sunrise Test.flac
    371324  music/Rock/Test Artist One/(2024) First Album/02 Midnight Test.flac
      2390  music/Rock/Test Artist One/(2024) First Album/folder.jpg
    481259  music/Rock/Test Artist One/(2025) Second Album/01 Echo Test.mp3
    481264  music/Rock/Test Artist One/(2025) Second Album/02 Starlight Test.mp3

💡 技术拓展:每张专辑目录里那张 folder.jpg 是专辑封面。gonic 找封面有两条路径——优先读音频文件的内嵌封面(由 scan-embedded-cover-enabled 控制,默认开启),其次认目录里的封面图片文件(folder.jpg、cover.jpg 等常见命名)。对已有音乐库做「目录封面补全」时,往专辑目录丢一张 folder.jpg 是最省事的做法。

四、启动与首次扫描实录

本章执行启动并逐段解读首次启动日志——这是判断「部署是否成功」的核心证据链。

4.1 启动服务

$ cd /opt/data/quzuo/tmp/gonic
$ docker compose up -d
 Container gonic-0.23.0-app Creating
 Container gonic-0.23.0-app Created
 Container gonic-0.23.0-app Starting
 Container gonic-0.23.0-app Started
$ docker compose ps
NAME               IMAGE                   COMMAND                 SERVICE   CREATED         STATUS         PORTS
gonic-0.23.0-app   sentriz/gonic:v0.23.0   "/sbin/tini -- gonic"   gonic     4 seconds ago   Up 3 seconds   0.0.0.0:8137->80/tcp, [::]:8137->80/tcp

服务已在后台运行,宿主机 8137 端口已映射到实例内 80 端口。

4.2 解读首次启动日志

执行 docker logs gonic-0.23.0-app,首次启动日志分三段证据:

第一段:数据库迁移。空数据库首次启动会连续执行 72 条 schema 迁移(实测从 202002192100 一路跑到 202610221200):

2026/10/28 21:11:46 migration '202002192100' finished
2026/10/28 21:11:46 migration '202002192019' finished
……(共 72 条 migration 记录,此处省略)
2026/10/28 21:11:46 migration '202610221200' finished

第二段:生效配置全量回显。gonic 会把本次启动的全部参数值打印出来,排障时先核对这一段:

2026/10/28 21:11:47 starting gonic v0.23.0
2026/10/28 21:11:47 provided config
2026/10/28 21:11:47     cache-path                     /cache
2026/10/28 21:11:47     db-path                        /data/gonic.db
2026/10/28 21:11:47     http-log                       true
2026/10/28 21:11:47     jukebox-enabled                false
2026/10/28 21:11:47     listen-addr                    :80
2026/10/28 21:11:47     music-path                     /music
2026/10/28 21:11:47     playlists-path                 /playlists
2026/10/28 21:11:47     podcast-path                   /podcast
2026/10/28 21:11:47     scan-at-start-enabled          true
2026/10/28 21:11:47     scan-embedded-cover-enabled    true
2026/10/28 21:11:47     scan-interval                  0
2026/10/28 21:11:47     scan-watcher-enabled           false
……(其余参数略,完整逐项说明见[《gonic 配置参数详解》](https://www.quzuo.net/document/cYSGfodmnQf2))

第三段:启动即扫描。因为开了 GONIC_SCAN_AT_START_ENABLED,服务一起来就自动扫描曲库:

2026/10/28 21:11:47 starting job "scan at start"
2026/10/28 21:11:47 starting scan
2026/10/28 21:11:47 processing folder "/music"
2026/10/28 21:11:47 processing folder "/music/Electronic"
2026/10/28 21:11:47 processing folder "/music/Electronic/Test Artist Two"
2026/10/28 21:11:47 processing folder "/music/Electronic/Test Artist Two/(2023) Synth Waves"
2026/10/28 21:11:47 processing folder "/music/Rock"
2026/10/28 21:11:47 processing folder "/music/Rock/Test Artist One"
2026/10/28 21:11:47 processing folder "/music/Rock/Test Artist One/(2024) First Album"
2026/10/28 21:11:47 processing folder "/music/Rock/Test Artist One/(2025) Second Album"
2026/10/28 21:11:47 finished clean tracks in 50µs, 0 removed
2026/10/28 21:11:47 finished scan in 221.18ms, +6/6 tracks (0 err)
2026/10/28 21:11:47 stopped job "scan at start"

关键结论:finished scan in 221.18ms, +6/6 tracks (0 err)——6 首音轨全部入库、0 错误,与第三章准备的文件数精确吻合。同时日志里还能看到 podcast refresh、session clean、http 等后台任务一并启动。至此部署本体完成。

五、初始化管理账号

本章完成首次登录与改密。gonic 首次启动会自动创建默认管理账号 admin/admin,官方明确要求登录后立即改密。

5.1 登录 Web 管理界面

浏览器访问 http://<服务器IP>:8137/ 会跳转到登录页。用 curl 模拟整个表单提交流程(实测回显):

$ curl -s -c ck.txt -b ck.txt 'http://127.0.0.1:8137/admin/login' -o login_page.html -w 'HTTP %{http_code}\n'
HTTP 200
$ grep -oE 'action="[^"]*"|name="(username|password)"' login_page.html
action="/admin/login_do"
name="username"
name="password"
$ curl -s -c ck.txt -b ck.txt -X POST 'http://127.0.0.1:8137/admin/login_do' -d 'username=admin&password=admin' -o /dev/null -w 'HTTP %{http_code} -> %{redirect_url}\n'
HTTP 303 -> http://127.0.0.1:8137/admin/home

HTTP 303 跳转到 /admin/home 即登录成功,会话凭据保存在 cookie 里。注意登录表单的真实提交地址是 /admin/login_do(不是 /admin/login),用脚本对接时容易踩坑。

5.2 修改 admin 密码为 q1w2e3r4

管理首页有「change password」入口,先解析改密表单的字段名,再提交(实测回显):

$ curl -s -c ck.txt -b ck.txt 'http://127.0.0.1:8137/admin/change_password?user=admin' -o chpw.html -w 'HTTP %{http_code}\n'
HTTP 200
$ grep -oE 'action="[^"]*"|name="password[^"]*"' chpw.html
action="/admin/change_password_do?user=admin"
name="password_one"
name="password_two"
$ curl -s -c ck.txt -b ck.txt -X POST 'http://127.0.0.1:8137/admin/change_password_do?user=admin' -d 'password_one=q1w2e3r4&password_two=q1w2e3r4' -o /dev/null -w 'HTTP %{http_code} -> %{redirect_url}\n'
HTTP 303 -> http://127.0.0.1:8137/admin/home

303 跳回首页即改密成功。表单要求两次输入(password_one/password_two),只传一个字段会返回 400——这是脚本化操作时第二个容易踩的坑。

5.3 验证新旧密码切换

用 Subsonic API 的 ping 端点分别验证(实测回显):

$ curl -s 'http://127.0.0.1:8137/rest/ping.view?u=admin&p=admin&v=1.16.1&c=curltest&f=json'
{"subsonic-response":{"status":"failed","version":"1.16.1","type":"gonic","serverVersion":"0.23.0","openSubsonic":true,"error":{"code":40,"message":"invalid password"}}}
$ curl -s 'http://127.0.0.1:8137/rest/ping.view?u=admin&p=q1w2e3r4&v=1.16.1&c=curltest&f=json'
{"subsonic-response":{"status":"ok","version":"1.16.1","type":"gonic","serverVersion":"0.23.0","openSubsonic":true}}

旧密码 admin 返回错误码 40(invalid password),新密码 q1w2e3r4 返回 status:"ok"——改密即时生效,无需重启服务。

💡 技术拓展:gonic 同时存在两套认证体系。Web 管理界面(/admin/*)走「用户名密码登录 → 会话 cookie」模式,与浏览器交互一致;Subsonic API(/rest/*)走「每次请求带认证参数」的无状态模式,且同时支持老式明文密码(u+p)与新式盐令牌(u+t+s)两种形态,下一章逐一实测。两边改密是联动的——Web 界面改的密码,API 侧立即用新密码校验。

六、Subsonic API 连通性实测

本章用 curl 把核心 API 全部打通:认证、浏览、搜索、流媒体、封面、扫描。所有请求都带 v=1.16.1(API 版本)与 c=curltest(客户端标识)两个约定参数,f=json 指定 JSON 响应(默认 XML)。

6.1 明文密码认证 ping

$ curl -s 'http://127.0.0.1:8137/rest/ping.view?u=admin&p=q1w2e3r4&v=1.16.1&c=curltest&f=json'
{"subsonic-response":{"status":"ok","version":"1.16.1","type":"gonic","serverVersion":"0.23.0","openSubsonic":true}}

status:"ok" 即链路通畅。响应头信息还透露了服务端身份:type:"gonic"、serverVersion:"0.23.0"、openSubsonic:true(表示支持 OpenSubsonic 扩展)。

6.2 token+salt 认证 ping

$ SALT=7a7f39ca
$ TOKEN=$(printf '%s' "q1w2e3r4${SALT}" | md5sum | awk '{print $1}')
$ echo "salt=$SALT token=$TOKEN"
salt=7a7f39ca token=db4d1a45d03f4d115a034684fd5f929b
$ curl -s "http://127.0.0.1:8137/rest/ping.view?u=admin&t=${TOKEN}&s=${SALT}&v=1.16.1&c=curltest&f=json"
{"subsonic-response":{"status":"ok","version":"1.16.1","type":"gonic","serverVersion":"0.23.0","openSubsonic":true}}

💡 技术拓展:Subsonic 的 token 认证机制是为了「不在 URL 里暴露明文密码」设计的——客户端随机生成 salt,计算 token = md5(password + salt),请求只带 u/t/s 三个参数;服务端用同一算法校验。这样即使 URL 被访问日志、反向代理记录下来,泄露的也只是一次性的 token 而非密码本体。老式 u+p 明文模式仅建议在 localhost 或 TLS 之内使用。本文后续 API 调用统一使用 token 认证。

6.3 艺术家与专辑浏览

$ AT="u=admin&t=db4d1a45d03f4d115a034684fd5f929b&s=7a7f39ca&v=1.16.1&c=curltest&f=json"
$ curl -s "http://127.0.0.1:8137/rest/getArtists.view?$AT"
{"subsonic-response":{...,"artists":{"ignoredArticles":"","index":[{"name":"t","artist":[{"id":"ar-2","name":"Test Artist One","coverArt":"al-7","albumCount":2,..."roles":["albumartist","artist"]},{"id":"ar-1","name":"Test Artist Two","coverArt":"al-4","albumCount":1,...}]}]}}}
$ curl -s "http://127.0.0.1:8137/rest/getAlbum.view?$AT&id=al-7"
{"subsonic-response":{...,"album":{"id":"al-7","artist":"Test Artist One","title":"First Album","songCount":2,"duration":60,"genre":"Rock","year":2024,"song":[{"id":"tr-3",..."title":"Sunrise Test","track":1,"suffix":"flac",...},{"id":"tr-4",..."title":"Midnight Test","track":2,...}]}}}

两位艺术家、专辑 al-7(First Album)下两首 flac 音轨,与第三章的目录树完全对应。gonic 的资源 ID 带可读前缀:ar- 艺术家、al- 专辑、tr- 音轨,排障时一眼可辨资源类型。

6.4 全文检索 search3

$ curl -s "http://127.0.0.1:8137/rest/search3.view?$AT&query=Test&songCount=10"
{"subsonic-response":{...,"searchResult3":{"artist":[{"id":"ar-1","name":"Test Artist Two",...},{"id":"ar-2","name":"Test Artist One",...}],"song":[{"id":"tr-1","title":"Neon Test",...},{"id":"tr-2","title":"Pulse Test",...},{"id":"tr-3","title":"Sunrise Test",...},{"id":"tr-4","title":"Midnight Test",...},{"id":"tr-5","title":"Echo Test",...},{"id":"tr-6","title":"Starlight Test",...}]}}}

关键词 Test 命中 2 位艺术家与全部 6 首音轨。v0.23.0 的搜索端点还支持 * 前缀通配(如 query=*Test)。

6.5 流媒体下载与比特级校验

stream 端点是客户端播放的实际链路。本次下载 tr-3 并与源文件做 md5 比对(实测回显):

$ curl -s "http://127.0.0.1:8137/rest/stream.view?$AT&id=tr-3" -o tr3.stream -w 'HTTP %{http_code} | %{content_type} | %{size_download} bytes\n'
HTTP 200 | audio/flac | 368150 bytes
$ md5sum tr3.stream 'music/Rock/Test Artist One/(2024) First Album/01 Sunrise Test.flac'
a743d0e6fccfbfe87c5be41303a85b6a  tr3.stream
a743d0e6fccfbfe87c5be41303a85b6a  music/Rock/Test Artist One/(2024) First Album/01 Sunrise Test.flac

两个 md5 完全一致——默认配置下 gonic 对源文件做比特级透传,不触碰音质。只有当你在客户端/服务端设置了转码偏好(如限码率出 Opus)时,ffmpeg 实时转码链路才会介入。

6.6 专辑封面

$ curl -s "http://127.0.0.1:8137/rest/getCoverArt.view?$AT&id=al-7" -o cover_al7.jpg -w 'HTTP %{http_code} | %{content_type} | %{size_download} bytes\n'
HTTP 200 | image/jpeg | 6373 bytes

封面取自专辑目录里的 folder.jpg(原始 2390 字节,服务端按客户端请求的默认尺寸缩放后输出 6373 字节,产物会落到 /cache 复用)。

6.7 触发扫描与状态查询

新增/删除音乐文件后需要重新扫描。用 API 触发并查状态(实测回显):

$ curl -s "http://127.0.0.1:8137/rest/getScanStatus.view?$AT"
{"subsonic-response":{...,"scanStatus":{"scanning":false,"count":6}}}
$ curl -s "http://127.0.0.1:8137/rest/startScan.view?$AT"
{"subsonic-response":{...,"scanStatus":{"scanning":false,"count":6}}}

对应服务日志同步出现一次增量扫描(无任何变更,7.89ms 完成):

2026/10/28 21:14:44 starting scan
2026/10/28 21:14:44 finished scan in 7.89ms, +0/6 tracks (0 err)

count 字段是曲库音轨总数,scanning 表示是否有扫描进行中。除了 API,Web 管理首页也有「start scan」按钮,效果相同。

七、客户端接入说明

本章说明各类客户端如何接入刚部署好的 gonic。接入三要素统一为:服务器地址 http://<服务器IP>:8137、用户名 admin、密码 q1w2e3r4(支持 token 的客户端会自动使用 token 认证,无需手工配置)。

  • Web 管理界面:http://<服务器IP>:8137/ 本身是管理后台(用户、Last.fm/ListenBrainz、触发扫描),也内置一个简易播放器可直接试听曲库;
  • Jukebox 模式:服务端把音频输出到本机声卡(适合「服务器接音响当客厅播放器」场景),需要配置项 jukebox-enabled=true 并把宿主机声卡设备映射进运行实例;官方制品已内置 mpv,无需额外安装播放组件。本次实测机无声卡设备(实例内 /dev/snd 不存在),仅验证开关生效,实际外放需在有声卡的机器上进行;
  • 移动/桌面客户端:gonic 官方实测兼容 Symfonium、DSub、Ultrasonic、Tempus(Android),Amperfy、play:Sub(iOS),Sublime Music、Strawberry(桌面),stmp、termsonic(终端)等 Subsonic 生态客户端。以 Symfonium 为例:添加媒体源 → 选 Subsonic → 填上述三要素 → 连接即出曲库。

八、排障实录

本章把本次实测中真实触发过的异常逐一记录,附定位手法。

8.1 认证类错误(错误码 40 与 10)

# 密码错误
$ curl -s 'http://127.0.0.1:8137/rest/ping.view?u=admin&p=wrongpass&v=1.16.1&c=curltest&f=json'
{"subsonic-response":{...,"error":{"code":40,"message":"invalid password"}}}
# 完全不带认证参数(默认 XML 响应)
$ curl -s 'http://127.0.0.1:8137/rest/ping.view'
<subsonic-response status="failed" version="1.16.1" xmlns="http://subsonic.org/restapi" type="gonic" serverVersion="0.23.0" openSubsonic="true">
    <error code="10" message="please provide a &#34;u&#34; parameter"></error>
</subsonic-response>

错误码 40 = 凭证无效;错误码 10 = 缺少必需参数。同时可见:不带 f=json 时默认返回 XML,解析脚本别忘了统一格式参数。

8.2 资源不存在与参数缺失

$ curl -s "http://127.0.0.1:8137/rest/getAlbum.view?$AT&id=al-9999"
{"subsonic-response":{...,"error":{"code":70,"message":"couldn't find an album with that id"}}}
$ curl -s "http://127.0.0.1:8137/rest/getAlbum.view?$AT"
{"subsonic-response":{...,"error":{"code":10,"message":"please provide an `id` parameter"}}}

错误码 70 = 资源不存在(典型场景:客户端拿着旧缓存里的 ID 访问已重扫删除的专辑)。

8.3 访问非 API 路径被 303 重定向

$ curl -s -o /dev/null -w 'HTTP %{http_code}\n' 'http://127.0.0.1:8137/nonexistent'
HTTP 303

未登录访问非 API 路径会 303 跳转到登录页,而不是返回 404——用「HTTP 状态码」做健康检查时要认 200(API 带认证)或 303(Web 跳转),不能只认 200。

8.4 通用定位手法

# 看实时日志(默认打印每个 HTTP 请求,由 http-log 控制)
$ docker logs -f gonic-0.23.0-app
2026/10/28 21:14:44 response  200  GET /startScan?u=admin&t=...
# 核对生效配置(启动日志的 provided config 段)
$ docker logs gonic-0.23.0-app 2>&1 | grep -A40 'provided config'
# 进实例内自查(如确认文件是否挂载进来)
$ docker exec gonic-0.23.0-app ls /music
Electronic
Rock

经验排序:先看 HTTP 请求日志确认请求到没到 → 再看启动配置回显确认参数对不对 → 最后进实例确认文件挂载与权限。更多日志开关(如 SQL 级 log-db)的实测见《gonic 配置参数详解》与《gonic 常用命令与运维实战(核心篇)》。

九、小结

本文完成了 gonic v0.23.0 的 0→1 部署全实录:环境与目录规划 → 编排文件 → 演示曲库 → 启动日志三段证据(72 条迁移 / 配置回显 / 首扫 6/6 轨)→ admin 改密(旧密码即时失效)→ Subsonic API 六端点连通(含 stream 比特级 md5 校验)→ 客户端接入 → 四类排障实录。后续深入阅读:逐项参数改值见《gonic 配置参数详解》,备份恢复与升级流程见《gonic 常用命令与运维实战(核心篇)》,产品定位与同类对比见《gonic 介绍与选型指南》。