【实用的开源工具】ConvertX:自己搭一个万能文件格式转换站
「实用的开源工具」系列:我只收集值得用的开源项目,写清楚它能做什么、怎么部署、有哪些坑,并在文末标明出处。内容整理自官方文档,核对日期 2026-10-31,具体版本以官方为准。命令和配置都摘自官方 README、Dockerfile 和 Docker Hub 页面,本文没有做实机测试,请先在测试环境里走一遍。
项目信息卡
| 项目 | 说明 |
|---|---|
| 名称 | ConvertX |
| 做什么 | 自托管的在线文件转换器,官方称支持一千多种格式;用 TypeScript、Bun 和 Elysia 写成 |
| 许可证 | AGPL-3.0 |
| 仓库 | github.com/C4illin/ConvertX |
| 最近版本 | v0.20.0(2026-10-28 发布,查询于 2026-10-31)。版本号还在 0.x,官方 SECURITY.md 写明只支持最新版本 |
| 维护状态 | 未归档,最近一次推送 2026-10-28 |
| 运行方式 | 单个容器,默认端口 3000,数据放在容器内 /app/data |
| 镜像 | ghcr.io/c4illin/convertx 和 Docker Hub 的 c4illin/convertx;官方 README 的示例用 :latest(跟随发布版),:main 是最新提交 |
| 安全提示 | 官方文档警告:不要在公网开启 ALLOW_UNAUTHENTICATED 或 ACCOUNT_REGISTRATION |
它能做什么
- 一个网页转多种格式:背后调用现成的转换工具。官方 README 列出的有 FFmpeg(音视频)、ImageMagick、GraphicsMagick、Vips(图片)、LibreOffice、Pandoc(文档)、Calibre(电子书)、Inkscape(矢量图)、Assimp(3D 模型)等二十多个。
- 一次处理多个文件。
- 密码保护和多账号:官方功能列表里写的是 Password protection 和 Multiple accounts。
- 自动清理:环境变量
AUTO_DELETE_EVERY_N_HOURS默认 24,会定期删除超过这个时长的文件。
适合的场景:不想把文件上传到不认识的在线转换网站,自己有一台服务器,想有个随时能用的转换入口。
不适合的场景:服务器内存、磁盘很小。官方 Dockerfile 以 debian:testing-slim 为基础,装了 LibreOffice、Calibre、Inkscape、TeX Live、FFmpeg 等一大批软件,镜像不会小,转换大文件时也吃资源(这是我读 Dockerfile 后的判断,我没有查具体镜像体积)。
部署
先建目录:
mkdir -p /opt/convertx && cd /opt/convertxcompose.yaml(结构来自官方 README 的示例,我改了三处:固定版本、端口只绑本机、去掉写死的密钥):
services:
convertx:
image: c4illin/convertx:v0.20.0
container_name: convertx
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
environment:
- PUID=1000
- PGID=1000
- JWT_SECRET=把这里换成你自己生成的长随机字符串
volumes:
- ./data:/app/data几点说明:
- 镜像标签:官方 README 的示例是不带标签的
ghcr.io/c4illin/convertx(即:latest)。我写成c4illin/convertx:v0.20.0,是因为在 Docker Hub 上能查到这个标签;用之前请自己再确认一次,必要时换成更新的版本。想用 GitHub 镜像库的话,写成ghcr.io/c4illin/convertx,同样建议加上版本标签。 JWT_SECRET:官方示例里是一串写死的字符,并注明不设置的话每次会用randomUUID()。README 说所有环境变量都是可选的,但建议设置它。生成随机串的办法是通用做法,比如openssl rand -hex 32。PUID/PGID:官方说要和宿主机上用户的 ID 一致(用id -u、id -g查),避免映射目录的权限问题。- 端口:官方示例是
3000:3000,对所有网卡开放。这里绑定127.0.0.1,由反向代理对外。
启动:
docker compose up -d
docker compose logs -f convertx不用 Compose 的话,官方 README 给的单行命令是:
docker run -p 3000:3000 -e PUID=1000 -e PGID=1000 -v ./data:/app/data ghcr.io/c4illin/convertx第一次使用
- 浏览器打开
http://localhost:3000(远程服务器可以先用 SSH 端口转发)。官方提示:如果登不上,请确认你是通过 localhost 或 https 访问;否则需要设置HTTP_ALLOWED=true,但官方示例里的注释说这样不安全,只应该在本机使用。 - 按官方说法,访问后先创建你的账号。官方特别提醒:别让它在未配置的情况下裸露在外,因为任何人都能注册第一个账号。所以服务一启动就先注册好。
- 之后上传文件、选目标格式转换即可。具体按钮文字我没有逐个核对,以你看到的界面为准。
环境变量速查
下面都来自官方 README 的表格,全部可选:
| 名称 | 默认值 | 说明 |
|---|---|---|
JWT_SECRET | 未设置时用 randomUUID() | 签名用的长随机字符串,建议设置 |
PUID / PGID | 0(root) | 运行应用的用户和组 ID |
UMASK | 设置了 PUID 时为 002 | 文件创建掩码 |
ACCOUNT_REGISTRATION | false | 是否允许注册账号 |
HTTP_ALLOWED | false | 是否允许 HTTP 连接,官方说只在本机设为 true |
ALLOW_UNAUTHENTICATED | false | 是否允许不登录就使用,官方说只在本机设为 true |
AUTO_DELETE_EVERY_N_HOURS | 24 | 每隔 n 小时检查并删除超过 n 小时的文件,0 表示关闭 |
WEBROOT | 空 | 站点根路径,设成 /convert 则服务在 example.com/convert/ |
MAX_CONVERT_PROCESS | 0 | 同时进行的转换进程数上限,0 为不限 |
HIDE_HISTORY | false | 隐藏历史页面 |
PORT | 3000 | 监听端口 |
另外还有 BRANDING、FFMPEG_ARGS、FFMPEG_OUTPUT_ARGS、LANGUAGE、UNAUTHENTICATED_USER_SHARING 等,见官方 README。
反向代理(Nginx)
官方 README 没有给反向代理的示例配置,所以下面是通用的反代写法,不是官方模板。我没有核对 ConvertX 对代理头有没有额外要求:
server {
listen 443 ssl;
server_name convert.example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# 转换的文件可能很大,Nginx 默认只允许 1M 上传,按需调大
client_max_body_size 500M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
}
}client_max_body_size 和 proxy_read_timeout 的数值是我随手给的,请按你要转换的文件大小和耗时来定。
想挂在子路径(比如 example.com/convert/)而不是单独域名,官方的做法是设 WEBROOT=/convert。反代的路径写法官方没有说明,需要自己试。
更新与卸载
更新:改 compose.yaml 里的版本标签(先确认新标签真的存在),然后:
cd /opt/convertx
cp -a data data.bak-$(date +%F) # 通用做法:升级前先备份
docker compose pull
docker compose up -d如果你用的是 :latest,不用改标签,直接 pull 再 up -d 即可。官方 SECURITY.md 说只支持最新版本,所以别长期停在旧版上。
卸载:
cd /opt/convertx
docker compose down这只会删除容器,./data 目录还在。确定不再需要里面的账号和转换记录时,才手动删除它:
rm -rf /opt/convertx/data # 不可恢复,确认后再执行踩坑清单
- 第一个账号谁先注册就是谁的。 官方明确提醒,别让未配置的实例暴露在公网。部署完立刻自己注册。
- 登不上先看访问方式。 官方说明:不是 localhost 也不是 https 时,需要
HTTP_ALLOWED=true。正确的做法是走 https(反向代理加证书),而不是对公网开这个开关。 - 不要在公网开
ALLOW_UNAUTHENTICATED或ACCOUNT_REGISTRATION。 官方 README 里有明确警告,只应让你信任的人使用这个服务。 - 设置
JWT_SECRET。 不设的话,每次启动都会用新的随机值,官方 README 没有说明后果,我推测已登录状态可能失效,这一点我没有验证。 - 映射目录的权限。
PUID、PGID要和宿主机用户一致。官方写了:遇到unable to open database file,检查目录权限,或对挂载路径执行chown -R $USER:$USER path。 - 自动删除默认 24 小时。
AUTO_DELETE_EVERY_N_HOURS默认会清理超时文件,想长期保留转换结果的话,要自己调大或下载后另存;设成0则永不自动清理,磁盘要自己留意。 - 限制并发。
MAX_CONVERT_PROCESS默认0即不限制。小服务器上同时转几个视频就可能占满资源,可以设成一个较小的数。这是通用的资源管理建议。 - 仓库里的
compose.yaml别直接拿来用。 它文件开头注明是给开发和测试用的,里面有pull_policy: build、ACCOUNT_REGISTRATION=true、写死的密钥和TZ=Europe/Stockholm,生产部署请按 README。 - 转换的是各种格式的文件,解析器多、攻击面大。 这是通用提醒:不要让不可信的人上传,保持更新,必要时限制容器资源。
- Docker 发布的端口会绕过 ufw 之类的防火墙。 所以示例绑定到
127.0.0.1,只让反向代理访问。这是 Docker 的通用行为,不是 ConvertX 特有的。 - 许可证是 AGPL-3.0。 自己用不改代码一般没什么负担;如果改了代码并以网络服务形式提供给别人,请先读许可证条款。这是通用提醒,不是法律意见。
出处
有想法或问题?去留言板留言 →