Deepin上想装个新软件,结果官方源里没有,搜了一圈,网上来来回回就一句话——“加个Ubuntu源就行了”。这句话轻飘飘的,真正操作起来,坑比想象中多。我自己在Deepin 20和Deepin 23上折腾过好几轮,踩过签名错误、踩过依赖冲突、也踩过更新完系统起不来的问题,最后才摸出一套相对稳妥的流程。
这篇就来聊聊Deepin添加Ubuntu源这件事,把为什么能加、为什么容易翻车、怎么安全地加、出问题了怎么救,全部讲清楚。适合那些不满足于官方源、需要装docker-ce、新版开发工具、或者某些只发布Ubuntu包的软件的同学,看完可以直接照做,少走弯路。
1. 为什么Deepin要折腾Ubuntu源,值不值得
1.1 Deepin、Debian、Ubuntu三个“亲戚”到底什么关系
聊这个话题前,得先把Deepin和Ubuntu的“血缘关系”捋顺。Deepin早期是基于Ubuntu开发的,后来从Deepin 15开始逐渐转向基于Debian稳定分支,Deepin 20系列也就是从这个底座上来的。Ubuntu本身也是Debian的分支,等于说Deepin和Ubuntu是表兄弟,底层都流着Debian的血,包格式都是deb,包管理器都是apt系,理论上仓库是可以互相引用的。
但“可以引用”不代表“可以直接混用”。三个发行版虽然同宗,软件包的版本、编译参数、依赖关系都有差异。Ubuntu的包往往为了自己的发布周期做了大量定制,依赖版本比Debian稳定分支新,又不完全一致,强行把Ubuntu源塞进Deepin,轻则把某个库升级到不兼容的版本,重则让桌面环境和你天天用的应用商店一起崩掉。这不是危言耸听,我就见过有人混源之后,apt update倒是成功,结果安装软件时直接把libc6从Deepin版本替换成了Ubuntu版本,最后整个系统进不去桌面。
所以核心结论是:能用,但必须有方法地“用”,而不是无脑把一行源地址粘进去。
1.2 加了Ubuntu源能解决哪些实际问题
既然风险这么大,为什么还有那么多人要加?因为真实需求摆在那里。Deepin的应用商店虽然本土化做得不错,官方源里的软件也算全,但遇到下面这些场景就捉襟见肘:
- 装docker-ce。Deepin官方源里通常只有docker.io这个老版本,或者压根没有docker-ce;而Docker官方源、Ubuntu源里都有完整的版本链,尤其是新版功能、依赖支持更全。
- 装一些开发工具链。很多工具只发布Ubuntu版本的deb包,比如某些厂商的IDE、闭源的编译工具、内网办公软件,它们往往只标注支持Ubuntu 20.04/22.04,不会为Deepin单独适配。
- 需要较新版本的第三方库或软件。Deepin源为了保证系统稳定,软件版本更新偏保守;Ubuntu的LTS版本虽然也不算激进,但毕竟生态大、社区活跃,很多软件只有Ubuntu源里有打包好的新版。
换句话说,加Ubuntu源本质上是“借用”Ubuntu生态来解决Deepin软件覆盖不足的问题。年轻用户会遇到“想在Deepin上打开SSH服务、想自己定制系统ISO、想用官方源里没有的开发套件”这类需求,这些需求不复杂,但往往都会卡在包源这一步。
1.3 动手之前,先把这些风险刻在脑子里
我说句实在话,混源这件事,最怕的不是混,而是不知道在混。
风险一:依赖关系错乱。apt的全名叫Advanced Package Tool,它不关心包是哪个发行版出的,只关心依赖能不能满足。当你把Ubuntu源加入候选列表后,一旦某个已安装的Deepin包依赖一个较新的共享库,apt极有可能跑去Ubuntu仓库里拉那个库的Ubuntu版本。这个库再升级它自己的依赖,连锁反应就开始了。
风险二:内核和驱动被替换。有人在Deepin上混源后,apt upgrade会尝试把内核头文件、显卡驱动、桌面组件都换成Ubuntu版本,而Deepin桌面是深度定制过的,和Ubuntu的GNOME组件并不完全兼容,替换完大概率遇到显示异常,分辨率卡死在1024*768这种状态,或者进入不了桌面。
风险三:签名和信任链问题。Deepin仓库和Ubuntu仓库使用不同的GPG密钥,直接添加Ubuntu源而不导入对应密钥,apt会报NO_PUBKEY错误;但如果做法不规范(比如用apt-key全局信任),又等于把所有仓库都放在同一个信任等级上,出了问题更难排查。
风险四:没有“后悔药”。如果事先不备份源列表,混源出问题后,你连恢复到初始状态都困难,只能靠记忆重写,那个时候你会发现记性根本不靠谱。
所以,在动手前想清楚一件事:你添加Ubuntu源,是为了装一个具体软件,还是希望让整个系统的一切软件都升级到Ubuntu版本?前者值得做,而且可以做得优雅;后者基本是奔着重装系统去的。
2. 准备工作:摸清底细、备份源、选对版本
2.1 先查系统版本和架构,别凭感觉
加源之前,第一件要做的事,不是写配置,而是搞清楚自己身处的系统究竟是什么底细。右键打开终端,执行下面的命令:
cat /etc/os-release输出里能看到ID=deepin、VERSION_ID、VERSION_CODENAME这些字段。比如我手头在测的机器上显示的是VERSION_ID="20.9",这说明这是一台基于Debian 10(buster)的Deepin 20系统;如果是Deepin 23,底层则更接近Debian 13(trixie)。这两个平台的底层库版本差异很大,直接决定你该选择哪个版本的Ubuntu源。
顺带还要确认机器架构:
dpkg --print-architecture绝大多数电脑返回的会是amd64,这个就是标准x86_64架构,直接用常规Ubuntu源就行;如果返回的是arm64,那就要用ports.ubuntu.com一类的ARM端口源,而不能用默认源。这一步很多人忽略,结果复制了一堆x86的源地址到树莓派上,404报得莫名其妙。
2.2 备份现有源列表,给自己留好退路
我见过太多人加源前自信满满,翻车后一脸懵。老规矩,动手前先把现有状态完整备份,这是最便宜、最有效的保险。
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo cp -r /etc/apt/sources.list.d /etc/apt/sources.list.d.bak注意连/etc/apt/sources.list.d/这个目录也一起备份,因为Deepin的部分软件源、第三方源可能放在这里。等出问题要恢复的时候,直接:
sudo mv /etc/apt/sources.list.bak /etc/apt/sources.list sudo rm -rf /etc/apt/sources.list.d sudo mv /etc/apt/sources.list.d.bak /etc/apt/sources.list.d然后sudo apt update,马上就回到你熟悉的Deepin源状态。这个动作花不到一分钟,但关键时刻能救命。
2.3 Ubuntu版本代号那么多,到底选focal还是jammy还是noble
Ubuntu每两年出一个LTS版本,每半年出个临时版本,每个版本都有自己的代号。选错版本,apt update会出现大段404,更麻烦的是就算更新成功,也可能因为底层库版本不匹配引发依赖灾难。
选版本的核心原则:让Ubuntu源的库版本尽量接近当前Deepin所基于的Debian版本。这里给一个我实测过的参考表:
| Deepin版本 | 底层Debian | 推荐Ubuntu源版本 | 对应代号 | 风险等级 |
|---|---|---|---|---|
| Deepin 20.x | Debian 10 (buster) | Ubuntu 20.04 | focal | 较低 |
| Deepin 23 | Debian 13 (trixie) | Ubuntu 22.04 / 24.04 | jammy / noble | 中等 |
为什么Deepin 20推荐focal而不是更新的jammy或noble?因为focal的库版本时间点更接近Debian 10时代的软件快照,混源时能减少核心库冲突。当然,如果你只是需要某个特定软件的新版本,比如docker-ce,那其实不必纠结于Ubuntu版本,直接用Docker官方基于Ubuntu的仓库即可,这个后面细说。
Deepin 23用户的情况复杂一些,它底层比Deepin 20新很多,理论上可以尝试jammy甚至noble,但风险相应也高,建议从较低的优先级级别开始测试,不要一上来就全量使用。
提示:可以执行
apt-cache policy查看当前候选包来源和版本,来辅助判断你当前的库和哪个Ubuntu版本更接近。
2.4 镜像站怎么选:从阿里、清华到中科大的取舍
确认了Ubuntu版本,下一个要选的,是去哪下载。选源地址有几个现实考量:访问速度、同步完整度、长期稳定性。
国内常见的Ubuntu镜像站有这么几个:
| 镜像站 | 地址 | 特点 |
|---|---|---|
| 阿里云 | mirrors.aliyun.com/ubuntu/ | 速度快、同步频率高,国内使用人数多 |
| 清华大学 TUNA | mirrors.tuna.tsinghua.edu.cn/ubuntu/ | 同步策略严格,教育网和公网都有较好体验 |
| 中科大 USTC | mirrors.ustc.edu.cn/ubuntu/ | 稳定性好,长期维护,支持多种协议 |
| 腾讯云 | mirrors.cloud.tencent.com/ubuntu/ | 云服务器内网访问非常快 |
| 华为云 | mirrors.huaweicloud.com/ubuntu/ | 更新及时,云上友好 |
个人使用的话,我通常优先选阿里云或清华。如果你跑在腾讯云/阿里云这些云服务器上,优先用同一个云厂商的镜像站,因为内网有加速,速度能拉开很大差距。在国内网络环境下优先考虑国内镜像,偶尔也会遇到某些镜像同步刚出问题的情况,到时候换个镜像站改一行URL就行,这也是为什么不建议把所有源捆绑写死在一个文件里的原因。
3. 核心实操:把Ubuntu源安全地加进Deepin
3.1 推荐做法:独立文件管理源配置
很多人习惯把源地址直接追加在/etc/apt/sources.list末尾,但我更推荐在/etc/apt/sources.list.d/下单独建一个文件,比如起名叫ubuntu.list。这样有几个好处:第一,以后不用了,直接删掉这个文件,不会碰到Deepin原本的配置;第二,出了问题容易定位,一眼就知道是哪个源导致的;第三,备份恢复时范围清晰。
用任意编辑器创建文件,注意要有sudo权限:
sudo nano /etc/apt/sources.list.d/ubuntu.list内容可以参考下面这个模板(以Ubuntu 22.04 jammy、阿里云镜像为例):
deb https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse这里只说deb,不加deb-src。源码包是源代码,普通用户用不上,加上之后反而会在apt update时多下载一大票索引,拖慢速度、没必要。组件(main、restricted、universe、multiverse)四个我都保留,因为不同软件可能存在于不同组件里,只填main有时会发现某些包找不到,浪费排查时间。
3.2 用apt-pinning做优先级隔离,防止系统核心包被替换
这一节是整个混源操作里最重要的一环,也是最容易被忽略的一环。如果不做任何优先级限制,直接sudo apt update && sudo apt upgrade,apt会默认把优先级同样高的Ubuntu版本拿出来比较,很可能把桌面核心组件、库文件替换成Ubuntu的,导致大面积冲突。
解决办法是使用apt的pinning机制,也就是给不同来源设置优先级。我在/etc/apt/preferences.d/下建一个ubuntu-pin文件:
sudo nano /etc/apt/preferences.d/ubuntu-pin写入以下内容:
Package: * Pin: release o=Ubuntu Pin-Priority: 100 Package: docker-ce Pin: release o=Ubuntu Pin-Priority: 500第一段的意思是,所有来自Ubuntu的包默认优先级为100。需要理解apt的优先级数值逻辑,常见几个档位:
| 优先级值 | 含义 | 行为 |
|---|---|---|
| 1000 | 高到可以覆盖所有情况 | 强制安装 |
| 990 | 很高 | 会优先于默认源被选中 |
| 500 | 默认候选 | 安装时正常参与候选比较 |
| 100 | 很低 | 只有显式指定或被依赖时才使用 |
| -1 | 禁止 | 永远不安装 |
设置成100,意味着apt正常情况下不会主动把Deepin包替换成Ubuntu包,只有当你手动指定apt install xxx且Deepin源里没有这个包、Ubuntu里有,才会去Ubuntu源里找。这样就能把“补充生态”和“劫持核心”这两件事基本隔开。
第二段是白名单,以docker-ce为例,单独把它的优先级提到500,这样它才能正常参与候选安装。如果你要装的是别的软件,就照葫芦画瓢,把包名替换一下,多写几组也没问题。这个思路的核心,是“默认怀疑Ubuntu源,逐个放行”,跟防火墙的白名单逻辑是一样的。
3.3 更新索引、校验优先级、确认源生效
源配置和优先级配置都写完了,下一步执行:
sudo apt update这一步会去拉取源上的软件包索引。如果一切顺利,你会看到Ubuntu源的索引被正常下载,没有报错。
接下来验证优先级是否生效,用这条命令:
apt-cache policy这个命令会列出当前系统配置的各个仓库候选版本。重点看输出里有没有出现类似这样的行:
500 http://mirrors.aliyun.com/ubuntu jammy/main amd64 Packages release o=Ubuntu,a=jammy,n=jammy,l=Ubuntu,c=main,b=amd64 origin mirrors.aliyun.com 100 http://mirrors.aliyun.com/ubuntu jammy/universe amd64 Packages release o=Ubuntu,a=jammy,n=jammy,l=Ubuntu,c=universe,b=amd64 origin mirrors.aliyun.com前面数字就代表优先级。假如我们看到main组件是100,universe也是100,说明pin设置起效了;如果看到的是500,那就说明pin文件没有生效,要检查优先级文件路径、包名写法、Pin:那行的格式对不对。
再针对性验证特定包:
apt-cache policy docker-ce输出会显示该包有几个候选版本,分别来自哪个源、优先级多少。如果我们对docker-ce设置了500,这里应该能看到来自Ubuntu源的候选是500,这样可以放心继续安装。这一步属于“事前验证”,比装完之后再发现问题强得多。
3.4 实战案例:通过Ubuntu源安装docker-ce并保持系统稳定
现在演示一个相对完整的流程,目标是给Deepin装docker-ce。先说结论,Docker官方其实提供了独立的Debian/Ubuntu源,所以纯为装docker的话,可以直接用Docker官方源,而不必整个混入Ubuntu源。但如果你的场景里还有别的软件需要Ubuntu源,那就在已经配好Ubuntu源的基础上,用下面的方式来安装。
先把Docker官方GPG密钥装好:
sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc这里的逻辑是:Docker官方仓库也是基于Ubuntu仓库构建的,所以它的密钥链、仓库结构都跟Ubuntu兼容。装完密钥以后,把Docker官方源加进来:
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null注意上面这行脚本里有一步是通过os-release动态取codename的,如果$VERSION_CODENAME取出来是空或者不正确,需要手动替换成你设置的Ubuntu代号,比如focal或jammy。因为Docker官方仓库并没有为Deepin的代号单独建目录,必须写Ubuntu的版本代号。
接下来就是典型的安装步骤:
sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io因为之前已经给来自Ubuntu的docker-ce设置了优先级500,apt会有正常的候选版本,不会提示找不到包。安装完成后执行:
sudo systemctl status docker sudo docker run hello-world如果能正常pull镜像并打印出hello信息,说明docker环境跑起来了。这个过程如果跳过优先级设置,很可能在安装时看到一大串“推荐安装”但无法解决的依赖关系,或者apt擅自升级其他包,这就是为什么我一直强调先配pinning再操作,顺序不能反。
4. 常见翻车现场与排查记录
4.1 签名验证失败(NO_PUBKEY)怎么解
最常见的错误,是执行sudo apt update后出现类似这样的信息:
W: GPG error: https://mirrors.aliyun.com/ubuntu jammy InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY F6B9C0F6F3F1D1C4原因很简单:apt不信任Ubuntu仓库的GPG密钥。Deepin仓库用的是Deepin自己的密钥,Ubuntu仓库用Ubuntu的密钥,两者不通用。
解决方案分两种。如果Deepin仓库里能装到ubuntu-keyring包,最简单:
sudo apt-get install ubuntu-keyring装完之后,Ubuntu的归档签名密钥会统一安装到系统里,再刷新update,报错就会消失。
如果装不上,传统做法是:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F6B9C0F6F3F1D1C4但注意apt-key这种全局信任方式在新版本中被标记为过时,有安全风险。更推荐的做法是把Ubuntu密钥下载到/usr/share/keyrings/下,然后在源配置里通过signed-by指定密钥文件,这样只信任指定的这一个源,不扩大信任范围。我个人在实际操作中通常两种都用过,但长期维护时会尽量改成signed-by模式。
4.2 更新时404、仓库索引缺失
apt update如果出现大量404 Not Found,十有八九是源地址和Ubuntu版本对不上。比如系统是Deepin 20(底层接近Debian 10),却写了jammy(Ubuntu 22.04)的仓库,而某些组件在jammy里没有及时同步,或者镜像站还未完整同步最新组件目录,就会出现404。
排查思路是三步走:第一步,查看每个源文件具体写了什么,确认版本代号是否正确;第二步,用浏览器或curl直接访问那个带404提示的URL路径,看目录是否存在;第三步,如果确实404,把源地址里的组件名去掉或者替换成一个确定存在的组件,比如只保留main,先跑通apt update再说。
还有一个细节是,不同镜像站对同一个Ubuntu版本的同步目录不同,有的镜像站会提供jammy-backports,有的同步不及时。建议先只加主线和updates/security两个目录,backports这些非必要的不加,减少404概率。
4.3 依赖冲突:libc6、libssl版本对不上怎么办
安装了某个来自Ubuntu源的软件之后,apt突然报出一堆需要升级libc6、libssl、libstdc++6之类的提醒,这是混源后最典型的“连锁反应”。因为Ubuntu包依赖的库版本比Deepin源里的新,apt就会尝试去Ubuntu源升级这些库。一旦升级成功,Deepin桌面的组件可能因为依赖被替换,出现各种诡异问题。
遇到这种情况,我的处理方法是:先别急着升级。看看具体是哪个软件需要这个依赖,查一下这个软件在本机是不是必需的。如果并不是必需,直接不装了;如果必须装,那就把依赖范围进一步收紧。
更常用的应急手段是,安装一个不需要动核心库的替代版本软件。举个例子,想在Deepin上装新版GCC,与其从Ubuntu源里拉gcc(会拖一堆依赖),不如考虑conda或者容器方案,在容器里跑Ubuntu环境,把污染控制在一个隔离环境里,这样宿主系统的库无论如何都不会被动。
如果依赖冲突已经发生,最稳妥的办法是回滚源配置,把之前加的Ubuntu源临时禁用,然后用备份的源列表恢复原状:
sudo mv /etc/apt/sources.list.d/ubuntu.list /etc/apt/sources.list.d/ubuntu.list.disabled sudo apt update很多时候apt会因此降级一些库版本到Deepin原生版本,系统能恢复正常。
如果回滚后还是无法解决,可以考虑用aptitude这种更智能的依赖解决工具:
sudo apt-get install aptitude sudo aptitude install 包名它会给出多组依赖解决方案,允许你逐个选择,比apt直接无脑自动解决要灵活些。
4.4 混源后的衍生问题排查(应用商店、分辨率等)
混源之后,除了包管理器层面的问题,还会遇到一些“间接伤害”。比如Deepin应用商店打不开、开机后分辨率锁定在1024*768、输入法失效等。这些问题的根源往往在于,系统里某些桌面组件或驱动库被替换成了Ubuntu版本,与Deepin深度定制的桌面环境不匹配。
Deepin应用商店打不开,优先检查依赖完整性:
sudo apt --fix-broken install如果是桌面组件的问题,比如DDE(Deepin Desktop Environment)相关包版本被改动,可以通过apt查看哪些DDE包不是来自Deepin仓库:
apt list --installed | grep dde | grep -v deepin看到有“意外”来源的包,可以针对性降级或重装。
分辨率锁定在1024*768这类显示异常,多数情况下是显卡驱动问题。混源后可能把xserver-xorg-video相关驱动或mesa库升级到了Ubuntu版本,跟Deepin内核的配合出问题。处理方法通常是重装Deepin仓库版本的显卡驱动包,或者直接重新安装deepin官方源中的xserver相关包。如果你是在虚拟机上遇到的1024*768,那更可能是虚拟机增强工具没装好,跟混源没关系,需要单独装open-vm-tools或VBoxGuestAdditions。
这里想提醒一句:遇到这些衍生问题,第一反应不应该是“继续加新源”,而是“看看哪些包被动过”。大多数混源问题都是某个核心包被替换引起的,把那个包找出来、恢复到Deepin源版本,问题基本就消失了。
5. 让混源状态长期不翻车的几条经验
5.1 源配置的最小化原则
很多人把混源变成“大杂烩”,今天加Ubuntu源,明天加PPA,后天又从某个不知名博客复制一行第三方源。源越多,系统的信任面越广,依赖冲突的可能性越大。我的原则是:源配置最小化,能用官方源解决的就不用第三方源,能用一个仓库解决的就不加两个仓库。
在Deepin上添加Ubuntu源时也一样,只加自己需要的部分。如果你的需求只是个别软件,优先考虑给这个软件单独建一个源文件,而不是把整个Ubuntu源全部铺开。这种“按需添加、按需移除”的模式,长期看最安全。
5.2 优先级策略再强调一遍
再强调一遍apt-pinning的配置。优先级数值不是越大越好,也不是越小越好,关键是要跟你的使用场景匹配。如果你只是偶尔手动装几个软件,优先级设100完全够用;如果你希望某些包自动跟随Ubuntu源更新,可以在holders配置里维护一个白名单。
这个白名单方案,比把整个Ubuntu源优先级全部调成500要安全得多。每个包单独pin,意味着你对系统的影响范围是精确可控的。谁出了问题,改一个包名就行,不用推倒重来。
5.3 日常维护习惯:缓存清理、备份、日志查看
混源之后的日常维护,有几个习惯值得养成。
- 每次安装大软件前,先确认双方源里的版本关系:
apt-cache policy 包名,看看候选版本到底来自哪个仓库。 - 每次源列表变化后,先备份一次,而不是等翻了车才想起备份。
- 定期
sudo apt clean清理下载缓存,避免/var/cache/apt/archives目录膨胀。 - 查看安装日志时,多关注
/var/log/apt/history.log里被升级/安装的包列表,如果发现非Deepin来源的关键库出现在升级记录里,就要警惕。
5.4 什么情况下应该果断回滚
最后聊一个很多人不愿意面对的问题:什么时候该停止修补,直接回滚?我的经验是,当系统核心包(libc6、libssl、systemd、桌面环境组件)已经被替换,并且引发的问题反复出现时,挣扎修补的成本远高于回滚。与其在网上搜三个小时怎么修依赖,不如老老实实把源列表切回备份,然后在隔离环境里重新规划混源方案。
还有一些情况,比如某个软件就是需要高版本libc,而这类核心库版本差距无法调和的时候,也别硬混。换成容器、虚拟机,或者干脆换一个基于Ubuntu的发行版来跑这个软件,都比把Deepin搞成一个“四不像”强得多。
我在实际使用中,最深的体会是:Deepin添加Ubuntu源并不是一个“复制粘贴一条命令”的操作,而是一个需要规划、需要设优先级、需要留后路的系统工程。网上那些 “一键换源” 的脚本,大多数只是把源地址换掉,却不会管系统死活。你对系统有多尊重,它就会对你有多稳定。
最后再分享一个小习惯:我在源文件里会写大量注释,标明每一行源是干什么用的、为什么加、加于哪一天。看似不起眼,真到排查问题或者半年后清理源的时候,这些注释能省下大把时间。毕竟,敢动源的人,也得敢为自己的系统负责。