在威联通 QNAP NAS 上让 Container Station(Docker)支持代理拉取镜像
背景
设备是我一直在用的一台 NAS:
- 型号:TS-532X
- CPU:Annapurna Labs AL324
- 内存:8GB
- 系统:QTS 5.2.8
平时主要跑一些 Docker 服务,都是通过 Container Station 管理的。
Container Station 本质上就是 QNAP 把 Docker + LXD 包了一层 UI,方便用户直接从镜像仓库拉应用。
问题也出在这里: 一切“看起来很简单”的东西,一旦出问题,就不太好查。
问题
最开始只是一个很普通的报错:
Error response from daemon: Get "https://registry-1.docker.io/...": timeout
或者更直接一点:
context deadline exceeded
表现其实很统一:
- docker pull 卡住
- Container Station 里部署应用失败
- 镜像下载极慢甚至直接超时
但 NAS 本身网络是正常的:
- 能 ping 外网
- 能访问网页
- 其他服务没问题
这时候就很容易误判成 DNS 或网络问题。
分析
Container Station ≠ 标准 Docker
很多教程会告诉你:
修改
/etc/docker/daemon.json,加 registry mirror 或 proxy
但在 QNAP 上,这一套基本是无效的。
原因很简单:
- Container Station 是 QNAP 自己改过的一套 Docker 运行环境
- 配置路径和启动方式都不完全遵循标准 Linux
比如:
/etc/config/docker.json
这个文件确实存在,但它的用途更偏向:
镜像加速(registry mirror)
而不是代理。
真正的问题在“守护进程层”
这里要区分两个完全不同的概念:
守护进程(Docker Daemon)
- 执行
docker pull - 负责和 docker.io / ghcr.io 通信
容器内部
- 运行你的应用(比如 Immich / Nginx / etc)
- 有自己独立的网络环境
这次的问题,只发生在第一层。
也就是说:
Docker 引擎本身访问不了外网,而不是容器的问题。
为什么 UI 里没法解决?
Container Station 的 UI 并没有提供:
- HTTP_PROXY 设置入口
- Docker daemon 级代理配置
这点其实挺反直觉的,但也能理解:
官方更倾向你用“镜像仓库加速”,而不是代理
本质原因
问题的核心可以归纳成一句话:
Docker daemon 启动时,没有任何代理环境变量。
而在 Linux 里:
http_proxy / https_proxy
这种东西,本质是进程级环境变量。
也就是说:
必须在 Docker 启动之前注入
解决方案
最后选择的是一个比较“底层”的方案:
直接修改 Container Station 的启动脚本
修改启动脚本
vi /etc/init.d/container-station.sh
找到 start) 分支(或者 main() 里的 start),在最前面插入:
export http_proxy="http://192.168.2.20:7890"
export https_proxy="http://192.168.2.20:7890"
export no_proxy="localhost,127.0.0.1,database,redis"
这里有几个细节:
- 不能用
127.0.0.1 - 必须写代理设备的局域网 IP
- 如果你用的是圈 X / 旁路由,要开启 LAN 访问
- 编辑语法:按
i进入编辑,按Esc退出编辑,输入:wq保存退出,输入:q!不保存强制退出
重启服务
/etc/init.d/container-station.sh restart
验证是否生效
docker info | grep -i proxy
如果能看到:
HTTP Proxy: http://192.168.2.20:7890
基本就通了。
一个容易踩的坑
很多人做到这一步会以为:
“已经全局代理了”
其实不是。
Docker 代理分两层
守护进程级(刚刚改的)
作用:
- docker pull
- 下载镜像
解决的是:
拉不下来镜像的问题
容器级
作用:
- 容器内部访问外网
- 比如:
- 下载 AI 模型
- 请求 API
- 地图服务
这个不会自动继承上面的 proxy。
如果需要,还要在 docker-compose.yml 里写:
environment:
- HTTP_PROXY=http://192.168.2.20:7890
- HTTPS_PROXY=http://192.168.2.20:7890
稳定性问题
这个方案不是没有代价。
重启 NAS:不会丢
因为:
/etc/init.d/container-station.sh
通常是一个软链接,实际指向硬盘上的 .qpkg 目录。
所以:
修改是持久的
更新 Container Station:会丢
只要你:
- 在 App Center 更新 Container Station
系统会:
- 覆盖整个
.qpkg/container-station目录
也就是说:
你改的脚本会被还原
我的处理方式
没有搞复杂的自动化,反而是最简单的:
- 把这几行 export 存下来
- 每次更新后重新打一次补丁
原因也很现实:
QNAP 更新频率不高,这种操作成本其实很低