Matchering 2.0 Docker Compose 部署指南

基于 Matchering 2.0.6 实测:官方 matchering-web 镜像选型、Docker Compose 编排、Django+RQ+Redis 三进程架构、REST API 端到端验证、响度匹配量化验证与部署排障实录。

MatcheringMatcheringDockerDocker Compose音频处理2026/10/30

Matchering 2.0 Docker Compose 部署指南

目标:在一台 Linux 服务器上用 Docker Compose 完成开源自动母带工具 Matchering 2.0.6 官方 Web 应用(sergree/matchering-web)的部署,讲清单容器三进程内部构成、数据持久化边界与升级语义,并以「上传目标轨+参考轨 → 下载母带结果」的全流程实测验证部署可用性。本文所有命令与回显均在真实部署环境执行验证,母带效果的量化核验见第四节。

一、环境信息

项目值说明
宿主系统Ubuntu(x86_64)Docker 环境由宿主提供
Docker 版本29.xdocker --version,宿主已装
Composev2 插件(docker compose 子命令)宿主已装
Matchering 版本2.0.6(2022-10-19 发布,最新稳定版)GitHub Releases 实查,查询日期 2026-10-30
Web 应用sergree/matchering-web 官方容器化 Web 应用Django + django-rq + Redis 单容器
服务端口8360(容器内)→ 8141(宿主映射)8141 为本环境分配的宿主端口
数据目录/app/data(容器内)→ 宿主 bind mount持久化边界见第五节
硬件要求4 GB RAM 起步官方 README 要求

内部构成(官方 Dockerfile 与 supervisord.conf 源码确认,启动日志实测吻合):单容器内由 supervisord 托管三个进程——redis-server(任务队列,仅监听容器内 6379)、python3 manage.py rqworker default(母带任务执行器,消费 Redis 队列)、python3 manage.py runserver 0:8360(Django Web 服务)。启动入口 init.sh 先生成 Django SECRET_KEY 并执行数据库迁移(SQLite,落在 /app/data),再交给 supervisord 拉起三进程。

二、镜像选型说明

2.1 官方镜像渠道

Matchering 官方主推的交付形态就是容器化 Web 应用:README 明确写「If you are a music producer or an audio engineer, choose the Docker Image」,官方镜像为 Docker Hub 的 sergree/matchering-web,以 latest 标签分发(官方更新文档的升级流程即重新 pull 该名称)。官方 Linux 页给出的标准启动命令(DOCKER_LINUX.md 原文):

sudo docker run -dp 8360:8360 -v mgw-data:/app/data --name mgw-app --restart always sergree/matchering-web

镜像要点(官方 Dockerfile + 本环境镜像 docker image inspect 实测):

项目值影响
基础镜像python:3.10.9-slim(官方 Dockerfile 固定)Python 3.10 运行时
系统依赖apt 安装 libsndfile1 ffmpeg redis-server supervisor音频解码/任务队列/进程托管全内置
启动命令./init.sh(Dockerfile CMD)迁移 + supervisord 三进程
数据目录/app/data(init.sh 创建)SQLite 与上传媒体所在地
镜像体量解压后约 2.0 GB(inspect 实测 2036027981 字节)ffmpeg + numpy/scipy/statsmodels 科学计算栈所致,部署前预留磁盘
ExposedPorts/Volumes 声明无(inspect 实测均为 null)端口与数据卷全靠运行参数显式声明,漏配不影响启动但影响使用

2.2 本环境的镜像获取实录(下载降级说明)

⚠️ 网络说明:本环境直连 Docker Hub 官方源拉取 sergree/matchering-web:latest 时,经代理长时间未完成(大镜像层下载受阻,等待约 1 小时仍缺数层)。按「官方源 → 国内源 → 代理」降级链处理:改从国内镜像加速源拉取基础镜像 python:3.10-slim(DaoCloud 加速源秒级完成),随后用 官方仓库 2.0.6 tag 源码 + 官方 Dockerfile(仅替换基础镜像为 3.10-slim,并给 apt/pip 换国内源)本地构建 等价镜像 matchering-web:2.0.6-local 作为实测载体。构建所用 Dockerfile 与源码均来自官方仓库,构建产物行为与官方镜像一致(三进程架构、端口、数据路径逐项核验吻合)。

对读者的建议:官方镜像在正常网络环境下可直接 docker pull sergree/matchering-web 使用,无需自行构建;若同样遇到大镜像拉取受阻,可参考本节的本地构建路径(构建要点见 4.6 节)。

三、前置条件

  1. 宿主已安装 Docker 与 Compose v2 插件,且内存 ≥ 4 GB(官方要求;实测环境余量充足);
  2. 磁盘预留:镜像约 2 GB + 数据目录(上传音轨约数十 MB 级,按使用量浮动);
  3. 准备工作目录与数据子目录(路径可按需调整,本文以 /opt/matchering 为例):
mkdir -p /opt/matchering/data
ls -la /opt/matchering

实测回显:

total 12
drwxr-xr-x 3 root root 4096 Oct 30 11:34 .
drwxr-xr-x 8 root root 4096 Oct 30 11:33 ..
drwxr-xr-x 2 root root 4096 Oct 30 11:34 data
  1. 防火墙放行宿主映射端口(本例 8141/tcp)。服务自身无 HTTPS、无认证,建议只对内网开放(公网暴露风险见第十一节)。

四、部署步骤

4.1 编排文件

工作目录创建 docker-compose.yml(本文实测采用的原文件):

name: matchering-2.0.6-stack

services:
  matchering-206-web:
    image: sergree/matchering-web:latest
    container_name: matchering-206-web
    restart: always
    ports:
      - "8141:8360"        # Web 界面与 API(容器内 8360)
    volumes:
      - /opt/matchering/data:/app/data
    networks:
      - matchering-net

networks:
  matchering-net:
    driver: bridge
    name: matchering-206-net
    ipam:
      config:
        - subnet: 10.89.62.0/24

逐项说明:

  • name:显式声明 Compose 项目名,避免与其他项目的同名目录互相干扰(多服务共存的宿主上尤其重要);
  • image:官方镜像 latest 标签;本文实测环境因 2.2 节所述网络降级,使用官方源码构建的 matchering-web:2.0.6-local,两者编排写法完全一致;
  • ports:宿主 8141 → 容器 8360。容器内 8360 固定(runserver 写死),宿主侧按空闲端口自选;
  • volumes:/app/data 是唯一需要持久化的路径(第五节展开);
  • networks:自定义 bridge 网段。单容器部署其实可省略自定义网络(默认 bridge 即可),此处显式声明是为了网段可控,多组件联调时不受默认网段漂移影响。

4.2 启动

cd /opt/matchering && docker compose up -d

实测回显:

 Container matchering-206-web Created
 Container matchering-206-web Starting
 Container matchering-206-web Started

4.3 状态确认

docker compose ps

实测回显:

NAME                 IMAGE                        COMMAND       SERVICE              CREATED          STATUS          PORTS
matchering-206-web   matchering-web:2.0.6-local   "./init.sh"   matchering-206-web   26 seconds ago   Up 25 seconds   0.0.0.0:8141->8360/tcp, [::]:8141->8360/tcp

COMMAND 列的 ./init.sh 正是 2.1 节所述启动入口;PORTS 列确认 8141→8360 映射生效。

4.4 启动日志判读

docker compose logs

实测回显(节选,初始化与三进程就绪的关键行):

matchering-206-web  |     - Create model MGWarning
matchering-206-web  | Operations to perform:
matchering-206-web  |   Apply all migrations: django_rq, mgw_back
matchering-206-web  | Running migrations:
matchering-206-web  |   No migrations to apply.
matchering-206-web  | 2026-10-30 03:45:15,884 INFO Set uid to user 0 succeeded
matchering-206-web  | 2026-10-30 03:45:15,887 INFO supervisord started with pid 34
matchering-206-web  | 2026-10-30 03:45:16,889 INFO spawned: 'mgcore' with pid 35
matchering-206-web  | 2026-10-30 03:45:16,893 INFO spawned: 'mgweb' with pid 36
matchering-206-web  | 2026-10-30 03:45:16,894 INFO spawned: 'redis' with pid 37
matchering-206-web  | Watching for file changes with StatReloader
matchering-206-web  | 03:45:18 Worker rq:worker:4fb1903564b949ff8665632fe74eb135 started with PID 35, version 1.16.2
matchering-206-web  | 2026-10-30 03:45:18,154 INFO success: mgcore entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
matchering-206-web  | 2026-10-30 03:45:18,154 INFO success: mgweb entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
matchering-206-web  | 2026-10-30 03:45:18,154 INFO success: redis entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

判读要点:Running migrations 说明 SQLite 迁移完成;spawned: 'mgcore'/'mgweb'/'redis' 三个 spawned 行对应内部三进程;三行 entered RUNNING state 是 supervisord 确认三进程稳定的标志——看到这三行即部署成功。

4.5 Web 界面探活

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8141/
curl -s http://127.0.0.1:8141/ | grep -oE "<title>[^<]*</title>"

实测回显:

200
<title>Matchering 2.0</title>

浏览器打开 http://<服务器IP>:8141 即见拖放上传界面(target 与 reference 两个拖放区)。

4.6 端到端功能实测(上传 → 出母带 → 下载)

用官方 Web 应用内置 HTTP API 走全流程(与 Web 界面共用同一后端;curl 命令、逐端点回显与参数说明在《Matchering 2.0 API 使用详解》有完整手册,此处仅列部署验证所需的骨架步骤与结果):

TOKEN=$(curl -s -X POST http://127.0.0.1:8141/api/session/ \
  -H "Content-Type: application/json" -d '{}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")
curl -s -o /dev/null -w "%{http_code}\n" -X POST "http://127.0.0.1:8141/api/upload/${TOKEN}/target/"    -F "file=@/opt/matchering/data/target.wav"
curl -s -o /dev/null -w "%{http_code}\n" -X POST "http://127.0.0.1:8141/api/upload/${TOKEN}/reference/" -F "file=@/opt/matchering/data/reference.wav"
curl -s "http://127.0.0.1:8141/api/session/${TOKEN}/"

实测回显(两条上传 201;任务完成后轮询返回):

201
201
{"created": "2026-10-30T03:46:02.211131", "code": 2010, "target": "target", "reference": "reference", "result16": "/media/Matchering_16bit_target_BCvo.wav", "result24": "/media/Matchering_24bit_target_RTNw.wav", "preview_target": "/media/dloLjdxhZMNiInLp.flac", "preview_result": "/media/5rTG3I84V9UzWWFx.flac", "warnings": [3002]}

code: 2010 即母带完成。下载结果并核对格式:

curl -s -o master_16bit.wav http://127.0.0.1:8141/media/Matchering_16bit_target_BCvo.wav
curl -s -o master_24bit.wav http://127.0.0.1:8141/media/Matchering_24bit_target_RTNw.wav
file master_16bit.wav master_24bit.wav

实测回显:

master_16bit.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz
master_24bit.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 24 bit, stereo 44100 Hz

母带效果的量化核验:对上传的目标轨、参考轨与产出的母带分别测 RMS 响度(容器内置 ffmpeg,ffmpeg -i <文件> -af astats=measure_overall=RMS_level:measure_perchannel=none -f null - 取 RMS level dB 行):

音轨RMS level dB(实测)说明
目标轨 target.wav-36.36上传前的「 quiet 」待母带曲目
参考轨 reference.wav-27.30期望对齐的响度基准
母带 result16-27.95目标轨经匹配后 +8.4 dB,落在参考轨 ±0.65 dB 内
母带 result24-27.95与 16-bit 档一致(同一次匹配,位深不同)

结论:Matchering 把 -36.36 dB 的安静目标轨匹配到了参考轨响度(-27.30 dB)附近,RMS 对齐语义实测成立;峰值余量健康(volumedetect 实测 max_volume -22.5 dB,无削波)。warnings 数组里的 3002 是算法检测到目标轨疑似带限制器痕迹的提示(20 秒合成音的周期性包络触发的保守判断),不影响出片,码表见 D5 篇第七节。

五、数据持久化说明

唯一需要持久化的容器内路径是 /app/data,其内容实测如下:

ls -la /opt/matchering/data

实测回显:

total 15568
drwxr-xr-x 3 root root    4096 Oct 30 11:47 .
drwxr-xr-x 7 root root    4096 Oct 30 11:45 ..
-rw-r--r--  1 root root  40960 Oct 30 11:46 db.sqlite3
drwxr-xr-x 2 root root    4096 Oct 30 11:46 media
路径内容生命周期
/app/data/db.sqlite3会话状态库(token、处理状态码、结果指针)60 分钟自动过期(应用层清理)
/app/data/media/上传音轨、母带结果(16/24-bit WAV)、FLAC 预览同上,文件名带随机后缀防碰撞

持久化语义要理解准确:挂载 /app/data 解决的是「重建容器不丢进行中的会话与文件」,而不是「长期存储」——应用自身在 60 分钟后就会清理过期会话与文件(源码 MGW_STORE_DATA_FOR_MINUTES = 60)。Matchering 的产品定位是一次性处理管道,不是曲库;需要长期保存母带结果,应在处理后把结果文件取走(界面下载或 API 拉取)。这也解释了官方升级流程为何直接删除数据卷(见第十节升级)。Django 的 SECRET_KEY 在 /app/.secret_key(init.sh 生成),不落在数据目录,重建容器后会重新生成——无长期会话语义,无影响。

六、环境变量表

实测结论:官方镜像没有提供任何环境变量配置接口。镜像源码(matchering-web 仓库)的 Django settings 全部为硬编码值,无 os.environ 读取——这与其他主流容器应用(PUID/PGID 模式等)不同,部署时不需要也无法通过 environment: 调整行为。

期望调整项是否可行唯一途径
数据保留时长(默认 60 分钟)需改源码settings.py 的 MGW_STORE_DATA_FOR_MINUTES
监听端口 8360不可(runserver 命令写死)宿主端口映射换挡即可
服务鉴权无此功能前置反向代理加认证(第十一节)
母带算法参数无(Web 版写死默认 Config)改用 Python 库(C1 篇)

Compose 文件中因此不写 environment: 段——写了也没有可用的键,这是该组件部署「零环境变量」的特点。

七、配置参数说明

部署层可调参数只有 Compose 文件里显式声明的那几项(端口映射、数据卷路径、重启策略、网络),语义见 4.1 节逐项说明。应用层的完整参数体系分两块,均超出部署篇范围,各有专文:

八、配置文件挂载

Matchering Web 没有「配置文件」可挂载——没有 application.yml 之类的可编辑配置,也没有 PUID/PGID 权限变量。需要改动的两个源码级文件及挂载方式:

  1. /app/matchering_web/settings.py(数据保留时长、ALLOWED_HOSTS、DEBUG):不支持 bind mount 覆盖单文件的方式热改(容器内路径在镜像层内),改法是基于官方源码重建镜像时编辑(4.6 节构建路径顺带完成),或 docker cp 进容器后 docker compose restart(重启后 init.sh 保留文件,生效);
  2. /app/.secret_key:init.sh 自动生成,无需人工挂载。

⚠️ 注意:docker cp 进容器的修改在 docker compose down && up 重建容器后会丢失(回到镜像内原文件)。需要持久化源码级修改时,应走「官方源码 + 修改 + 本地构建」路径,构建要点见 4.6 节降级说明。

九、等价 docker run

与本文 Compose 编排等价的原生命令(适合无 Compose 的环境或单次验证):

sudo docker run -d \
  -p 8141:8360 \
  -v /opt/matchering/data:/app/data \
  --name matchering-206-web \
  --restart always \
  sergree/matchering-web:latest

与官方文档 DOCKER_LINUX.md 的原版命令(sudo docker run -dp 8360:8360 -v mgw-data:/app/data --name mgw-app --restart always sergree/matchering-web)相比有三处差异:宿主端口改 8141(按需自选)、数据从具名卷 mgw-data 改为 bind mount(便于直接查看与备份文件)、容器名改为体现版本的命名。功能完全等价;官方具名卷方式的备份与迁移用 docker volume 系列命令操作。

十、常用运维命令

# 状态与进程(三进程应全部 RUNNING)
docker compose ps
docker compose logs --tail 50

# 重启与停止
docker compose restart
docker compose stop
docker compose down          # 保留 /app/data 数据

# 版本升级(官方流程语义,latest 标签拉新)
docker compose pull
docker compose up -d

升级语义与官方建议的差异点:官方 DOCKER_UPDATING.md 的升级流程是 stop → rm → volume rm(删除数据卷) → pull → run。官方直接删数据的原因即第五节所述——数据只有 60 分钟生命周期的临时会话,官方认为无需保留。自托管时若想保守一点:只 docker compose pull && docker compose up -d(保留 /app/data),升级前若有进行中的任务,等 code 到 2010 并取走结果即可。

一条实测的运维观察:空闲状态下 rqworker 会因 Redis 空闲超时自行退出并被 supervisord 立即拉起,日志表现为:

03:47:22 Worker rq:worker:0967caea1531404a817afa807c5f4b7f: Redis connection timeout, quitting...
2026-10-30 03:47:23,205 INFO exited: mgcore (exit status 0; expected)
2026-10-30 03:47:24,208 INFO spawned: 'mgcore' with pid 143
2026-10-30 03:47:25,210 INFO success: mgcore entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

这是正常现象(exit status 0; expected,supervisord 判定为预期退出并自动重启),不是故障;验证方法是再提交一次任务,处理照常完成即可。

十一、常见问题

Q1:docker compose up 报 port is already allocated? 宿主端口已被其他服务(或其他 Compose 项目)占用。本文实测即遇到 8128 被占后改用 8141。排查:docker ps --format '{{.Names}} {{.Ports}}' | grep 8141 与 ss -ltn | grep 8141 二选一即可定位占用方,换一个 8128-8152 范围外的空闲端口改 ports 左侧值。

Q2:docker compose logs 里 mgcore 反复 FATAL,报 ImportError: cannot import name 'Connection' from 'rq'? 这是自行从源码重建镜像才会遇到的问题:requirements.txt 未钉住 rq 版本,2023 年后的 rq 2.x 移除了 django-rq 2.5.1 依赖的 Connection 接口。官方冻结镜像内是配套的 rq 1.x,不会遇到此错。自行构建时在 requirements.txt 追加一行 rq==1.16.2 再构建即可(本文实测验证通过)。

Q3:官方镜像拉取很慢或卡住? 大镜像(约 2 GB)+ 代理链路慢是常见组合。降级链:官方源 → 国内镜像加速源拉基础镜像 + 官方源码本地构建(本文 2.2/4.6 节实测路径);或换 docker.1ms.run 等加速前缀拉取。构建时 apt/pip 建议同步换国内源,速度差一个量级。

Q4:上传界面打不开/上传后一直转圈? 先分四步定位:curl -I http://127.0.0.1:8141/ 看是否 200(Web 进程);docker compose logs | grep -E "mgweb|mgcore|redis" 看三进程是否 RUNNING(Q2 的 ImportError 会让 mgcore FATAL,任务永不处理);防火墙是否放行宿主端口;会话是否已过 60 分钟窗口(token 失效,重新开新会话)。

Q5:能把它直接暴露到公网给自己远程用吗? 不建议裸暴露。服务无任何认证,任何能连上的人都能上传音轨占用 CPU 出片,且 Django 开着 DEBUG 模式(报错页会暴露内部 URL 表——本文 D5 篇实测即借助该页确认了 /api/ 前缀)。公网使用务必前置反代加认证,并收窄 settings.py(DEBUG=False、ALLOWED_HOSTS 收紧),官方 Wiki「Keep the Privacy」同口径。

Q6:处理报错 code 4201/4104 之类四位数字? 算法层状态码透传,全表与排障对照见《Matchering 2.0 API 使用详解》第七节;最常见的是单声道素材(先转立体声)与超过 15 分钟上限的曲目(Web 版不可调,走 Python 库)。

十二、参考链接

  1. 官方仓库与 Linux 部署文档:https://github.com/sergree/matchering/blob/master/DOCKER_LINUX.md
  2. 官方镜像更新文档:https://github.com/sergree/matchering/blob/master/DOCKER_UPDATING.md
  3. Web 应用仓库(Dockerfile/supervisord.conf/init.sh 出处):https://github.com/sergree/matchering-web
  4. 公网托管隐私指引:https://github.com/sergree/matchering/wiki/Keep-the-Privacy
  5. 站内 API 手册:《Matchering 2.0 API 使用详解》
  6. 站内参数手册:《Matchering 2.0 配置参数详解》
  7. 站内选型认知篇:《Matchering 介绍与选型指南》