
我敢说凡是干过内网环境交付的朋友都有过这么一段痛苦经历系统装好了客户要求“加个桌面”结果机器在隔离网段yum源连不上dnf一执行就是满屏的“Could not resolve host”那一刻真的想把显示器砸了。openEuler 22.03 LTS SP4作为目前生产环境里出镜率很高的版本其实在安装UKUI桌面时也逃不开这个坑。UKUI是麒麟团队主导开发的轻量级桌面环境在openEuler上被列为可选桌面之一但默认仓库里并不会完整包含所有组件更别说离线状态下根本没有仓库可用。这篇就是写给正在被“离线”两个字折磨的兄弟们从依赖包怎么攒、本地仓怎么建、到UKUI安装命令怎么执行、装完怎么验证全套流程一次说清。1. 项目背景与整体设计思路1.1 为什么选UKUI而不是其他桌面openEuler 22.03 LTS SP4官方支持的桌面不止一个除了UKUI还有GNOME、Xfce、DDE这些可选环境。但在我实际接触过的国产化替代项目里UKUI是点名率最高的一个。原因其实很直白UKUI的设计风格偏传统Windows操作习惯开始菜单、任务栏、通知区域都做得很接近对从Windows切过来的普通办公用户来说几乎没有学习成本。GNOME的问题在于交互逻辑太激进默认工作区、活动概览这些概念对老用户不友好内网客户培训时经常被吐槽“找不着关机的按钮”。Xfce虽然轻量但视觉质感确实差一截客户验收时会认为“不够精致”。DDE的话深度系的桌面资源占用偏高在配置一般的工控机或老PC上跑起来拖泥带水。UKUI则卡在了一个比较舒服的位置基于Qt开发界面全套中文化资源占用比DDE低观感明显好于Xfce操作习惯又贴近Windows。所以在openEuler的离线部署场景里UKUI属于“客户满意度和技术可行性兼顾”的选择。1.2 离线安装的完整闭环思路离线安装的核心瓶颈就是依赖关系。UKUI不像装个nginx那样只有几个依赖包它牵扯到Qt组件库、图形驱动、显示管理服务、会话管理、输入法框架等一大批底层软件包互相之间的版本强依赖关系非常多。直接把一台机器上的rpm包拷贝过去硬装几乎百分之百会遇到依赖缺失的报错而且报错往往是连环的——你补了libQt5Widgets它又告诉你libQt5Gui版本不对你在libQt5Gui上重装一遍它又喊libcrypto版本冲突。所以正确的做法是两条腿走路第一在一台能联网的同版本系统中把需要的rpm包全部拉取下来第二把这些rpm包制作成本地仓库然后在离线机器上通过dnf的本地源完成安装。让dnf自己去做依赖解析我们只负责提供“干粮”。这里有个关键前提攒包的机器和离线目标机必须是同版本、同架构的系统。openEuler 22.03 LTS SP4有x86_64和aarch64两个架构rpm包不能混用我下面的操作以x86_64为例如果你部署的是aarch64的鲲鹏机器命令一样但拉包时注意架构参数。2. 依赖包准备在有网环境把“弹药”备齐2.1 准备两台环境和基础工具你至少需要两台机器一台“攒包机”可以访问外网系统同样是openEuler 22.03 LTS SP4如果你只有别的版本尽量接近否则依赖版本可能对不上一台“目标机”离线环境也就是最终要装UKUI的机器。另外准备一个U盘或者移动硬盘容量建议32GB以上格式化为ext4或xfs。因为整个UKUI加上依赖包体积大约是2到3GBFAT32的4GB单文件限制倒不会触顶但为了保险起见还是用Linux原生文件系统更稳毕竟你要拷贝的rpm包数量可能有几百个小文件多FAT32在Linux下挂载有时会有权限问题。在攒包机上先确认系统版本和网络状态cat /etc/openEuler-latest dnf repolist如果dnf repolist能正常输出仓库列表且没有报错说明联网状态正常。我这个测试环境下系统版本显示为22.03 LTS SP4x86_64架构仓库地址指向了官方源和EPOL源。这里有个细节一定要注意UKUI桌面在openEuler的EPOL仓库里而不是默认的BaseOS仓库。所以攒包时不仅要开启baseos还要确认epol仓库是可用状态。手动检查一下EPOL源是否启用dnf repolist | grep epol如果发现EPOL仓库没有启用或者地址失效可以去openEuler的软件源镜像站找对应版本的epol目录手动配置一个repo文件。这一步没做好的话后面拉UKUI包时会出现“没有可用软件包”的情况。2.2 使用dnf download拉取完整依赖包准备工作完成后先用dnf安装一个关键工具createrepo_c用于后续制作本地仓库dnf install -y createrepo_c然后创建一个目录用来存放所有rpm包注意目录空间要充足mkdir -p /data/ukui-rpms cd /data/ukui-rpms接下来是核心命令。我们需要把UKUI桌面的所有相关包以及它们的全部依赖都拉下来。dnf提供了download命令配合--resolve参数会自动解析依赖并下载所有需要的包配合--alldeps参数可以确保所有依赖包都被拉到包括一些按需安装的推荐依赖dnf download --resolve --alldeps ukui ukui-control-center ukui-menu ukui-sidebar ukui-windowmanager ukui-settings-daemon ukui-power-manager ukui-greeter ukui-themes ukui-desktop --destdir/data/ukui-rpms在实际执行时你可能会遇到个别包名不存在的情况比如openEuler 22.03 SP4里某些组件叫ukui-screensaver而不是ukui-greeter。不用慌先用下面的命令搜索确认一下可用的UKUI相关包名dnf list available | grep -i ukui把列出的包名复制下来替换到上面的命令里重新执行即可。我这边最终拉取的包名清单如下部分dnf download --resolve --alldeps ukui ukui-control-center ukui-menu ukui-sidebar ukui-windowmanager ukui-settings-daemon ukui-power-manager ukui-screensaver ukui-themes ukui-desktop --destdir/data/ukui-rpms执行过程中dnf会自动计算依赖树并逐一下载日志会滚动显示每个包的下载进度。这一步耗时取决于网络我当时在千兆下行下用了大概三分钟如果你的网速一般耐心等一会儿就行。下载完成后检查一下rpm包数量ls /data/ukui-rpms/*.rpm | wc -l我这次实际拉到了413个rpm包其中包括libQt5、mariadb-connector-c、xorg-x11-server、libX11等一大批基础依赖。如果你拉到的包数量少得离谱多半是EPOL源没开或者--resolve没有生效需要回去检查。2.3 制作本地仓库并同步到离线机器单纯把几百个rpm文件扔到目标机上是没用的dnf无法识别散落的rpm包必须把它们组织成一个仓库。createrepo_c就是干这个的createrepo_c /data/ukui-rpms命令结束后在/data/ukui-rpms目录下会生成一个repodata子目录里面存放了仓库的元数据。到这里整个仓库就制作完成了。然后把整个/data/ukui-rpms目录拷贝到U盘上cp -a /data/ukui-rpms /run/media/你的U盘挂载路径/拷贝完成后在U盘上快速验证一下仓库完整性ls /run/media/你的U盘挂载路径/ukui-rpms/repodata/看到repodata目录里有repomd.xml之类的文件说明仓库信息完整可以拔盘了。2.4 顺带准备openEuler基础源和EPOL源到这里有必要多说一句。如果你只是用本地方言装UKUI那么上面的/data/ukui-rpms仓库就够了因为dnf download已经把UKUI所有依赖都拉齐了dnf在安装时不会再要求其他仓库。但实际上离线环境下你经常会同时装其他软件比如中文字体、输入法、办公软件这些都不在UKUI依赖范围内。所以我建议你在攒包机上把BaseOS源和EPOL源的rpm包也做一个完整的本地镜像特别是那些体积不大但是经常用到的工具包。方法很简单把仓库同步到本地目录dnf reposync --repoidbaseos --repoidepol -p /data/openEuler-full-reporeposync会把这个仓库里的所有rpm包全部镜像下来然后同样用createrepo_c为每一级目录生成仓库元数据。这一步会占用比较大的磁盘空间和比较长的时间BaseOS源全部拉下来大约有10GB左右但这也是离线环境里最值得做的投资。镜像完成后整个U盘里既有UKUI专用仓库又有完整的基础源和EPOL源到了目标机上就不用再为缺包发愁了。3. 离线安装UKUI从挂载仓库到桌面启动3.1 在目标机上配置本地repo源把U盘插到目标机上确认系统能识别到U盘设备lsblk通常U盘会识别为sdb1或者sdc1这样的设备然后手动挂载mkdir -p /mnt/usb mount /dev/sdb1 /mnt/usb ls /mnt/usb如果你有多个仓库目录可以分别挂载或者直接放在U盘的不同目录下。为了演示清晰我这边假设U盘上有/mnt/usb/ukui-rpms这个目录也就是我们制作好的UKUI专用仓库。接下来为dnf添加本地repo文件。创建一个新的repo文件vi /etc/yum.repos.d/local-ukui.repo写入以下内容[local-ukui] nameLocal UKUI Repository baseurlfile:///mnt/usb/ukui-rpms enabled1 gpgcheck0这里有个细节要说明gpgcheck0是因为我们自己制作仓库时没有导入GPG签名如果写1dnf会提示签名验证失败。如果你在攒包时把这些包的签名都导入过可以开启但离线环境下多一事不如少一事直接关掉最省心。如果你把BaseOS和EPOL也镜像到了U盘可以再加两个repo[local-baseos] nameLocal BaseOS Repository baseurlfile:///mnt/usb/openEuler-full-repo/baseos enabled1 gpgcheck0 [local-epol] nameLocal EPOL Repository baseurlfile:///mnt/usb/openEuler-full-repo/epol enabled1 gpgcheck0写完后执行dnf的缓存清理和重建dnf clean all dnf makecache如果配置正确dnf makecache会输出“Metadata cache created”之类的成功信息。此时用dnf repolist可以看到local-ukui这个仓库已经处于启用状态软件包数量就是我们打包进去的400多个。这里也提醒一句如果dnf makecache过程报错“Cannot find a valid baseurl for repo”优先排查两个地方一是baseurl路径是否写对注意file://后面跟的是绝对路径二是SELinux是否拦截了dnf读取U盘内容必要时可以临时用setenforce 0降低限制但生产环境记得恢复。3.2 执行离线安装dnf自动解析依赖仓库就绪后安装动作本身其实非常简单dnf install -y ukui或者如果你想一次性把所有UKUI相关组件都装上可以沿用之前拉包包名列表的方式dnf install -y ukui ukui-control-center ukui-menu ukui-sidebar ukui-windowmanager ukui-settings-daemon ukui-power-manager ukui-screensaver ukui-themes ukui-desktopdnf会开始解析依赖此时你会看到它列出了很多需要安装的包确认一下总数和依赖关系。如果一切正常输入y就会开始安装。因为数据全部来自本地仓库所以安装过程不会有任何网络访问速度只取决于硬盘性能和rpm包数量我这台机械硬盘的测试机上装完400多个包大约用了四分钟。安装过程中可能会遇到一个经典报错没有可用软件包 ukui。这通常是仓库里没有UKUI相关包名导致的。排查思路很简单先dnf list available ukui*看看是否能搜到包如果搜不到问题大概率在EPOL源上需要回头检查EPOL仓库是否启用。还有就是确认一下之前拉包时使用的是不是正确的高版本EPOL因为SP3和SP4的EPOL目录结构可能不同拉下来的包版本太老也会导致安装失败。3.3 设置默认图形界面并安装中文字体安装完成后系统默认的运行级别大概率还是multi-user.target命令行模式需要手动把默认target切换到graphical.target也就是图形界面模式systemctl set-default graphical.target同时安装lightdm显示管理器——UKUI默认使用lightdm作为登录管理器启动图形界面的前提就是它能正常运行dnf install -y lightdm systemctl enable lightdm systemctl start lightdm另外建议顺手安装中文字体否则桌面里的中文会显示成方块这个坑太常见了dnf install -y wqy-microhei wqy-zenhei google-noto-sans-cjk-fonts如果离线仓库里没有这些字体包你可以在攒包机上提前下载dnf download --resolve --alldeps wqy-microhei wqy-zenhei --destdir/data/ukui-rpms然后再执行createrepo更新一下仓库元数据把U盘里的目录重新拷一遍到目标机或者直接在原来的仓库目录里再生成一次元数据createrepo_c /data/ukui-rpms字体这步真的不能省中文方块问题会极大拉低客户对部署结果的评价。3.4 禁用其他仓库避免离线机器联网报错目标机处于离线环境但默认配置中可能会残留一些指向公网地址的repo文件比如原始安装时系统自带的openEuler.repo。如果这些仓库没有禁用dnf在执行安装操作时会先去尝试连接公网然后报一堆“Could not resolve host”的超时错误大大拖慢安装节奏。建议把除了本地仓库以外的repo文件统一注释或重命名cd /etc/yum.repos.d/ mkdir backup mv *.repo backup/ cp backup/openEuler.repo . # 如果有需要保留的话然后创建上面说的local-ukui.repo。这样dnf的仓库列表里就只剩本地源不会再有任何网路交互。这一步做完后再执行一次dnf repolist输出的仓库列表应当全部是file://开头的本地路径没有http/https地址。这可以确保后续所有安装操作都是纯离线的。4. 安装后的验证与调优4.1 重启验证桌面是否正常拉起仓库配置、安装、设置默认target这些步骤都完成后就是见证结果的时刻了reboot重启后如果一切正常你应该能看到lightdm的登录界面输入root密码或者新建的普通用户密码就能进入UKUI桌面。不过这里有个值得注意的问题如果你在目标机的显卡驱动上有特殊配置比如某些老NVIDIA显卡X服务可能起不来登录界面会黑屏或卡住。这种情况下先按CtrlAltF2切换到字符终端查看lightdm状态systemctl status lightdm journalctl -u lightdm -n 50日志里会出现具体的信息包括驱动加载失败、xorg.conf解析错误等。对症排查一般都能解决。4.2 常见桌面问题的现场排查方法桌面进去之后最先要验证的是任务栏、开始菜单、控制面板这些核心组件是否正常工作。UKUI桌面如果某个核心组件没装好会出现开始菜单打不开、桌面右键没反应等情况。这时回到字符终端检查ps -ef | grep -E ukui|lightdm正常状态下ukui-menu、ukui-settings-daemon、ukui-windowmanager这些进程应该是常驻的。如果某个进程不存在说明对应的包没装上或者启动失败。可以用systemd逐个排查systemctl --user status ukui-menu journalctl --user -u ukui-menu -n 20另外一个高频问题是登录用户不属于必要的用户组。UKUI桌面环境下如果用户不在wheel、audio、video等组里会出现无法使用sudo、没有声音、视频播放黑屏等诡异问题。建议把要登录桌面的用户加进这些组usermod -a -G wheel,audio,video,cdrom,disk user1最后是分辨率问题。内网机器经常配老显示器默认分辨率可能不对。UKUI的设置中心里有显示选项但如果你用的是轻量窗口管理器组件设置中心可能没有显示配置。此时可以手动调整xrandrxrandr xrandr --output HDMI-1 --mode 1920x1080把HDMI-1换成你的实际输出接口名称。想持久化的话可以写到/etc/rc.local或者lightdm的启动脚本里。4.3 常见问题速查表现象可能原因处理方式dnf install报“没有可用软件包”EPOL源未启用或仓库未同步检查epol源使用dnf list available ukui*确认包名安装时报依赖缺失本地仓库不全缺少某些传递依赖回攒包机重新执行dnf download --resolve补齐所有依赖重启后黑屏只有光标闪烁lightdm未启动或显卡驱动异常CtrlAltF2进字符终端检查lightdm状态和xorg日志登录后桌面空白没有任务栏ukui-menu或ukui-settings-daemon未运行检查用户进程确认core组件包已完整安装中文全部显示成方块缺少中文字体安装wqy-microhei或google-noto-sans-cjk-fonts分辨率固定且无法调整显示相关驱动或xrandr配置问题使用xrandr手动设置分辨率写入持久化配置点击开始菜单无反应菜单组件崩溃或依赖异常在字符终端手动启动ukui-menu查看报错日志无法使用sudo命令用户不在wheel组usermod -a -G wheel 用户名5. 踩坑笔记与经验补充5.1 几个容易被忽略的坑第一攒包机与目标机的版本必须一致。我最初图省事在openEuler 22.03 LTS SP2上拉包然后拿到SP4的机器上装结果一堆Qt相关包版本对不上安装到一半直接滚动报错最后不得不重新拉包。这个时间成本太高了千万别省。第二依赖包最好全部由dnf download --resolve --alldeps生成不要自己手动挑包。你的直觉远远不如dnf对依赖关系的理解准确漏掉任何一个细小的依赖都会让离线安装功亏一篑。第三U盘文件系统。如果你在拷贝大文件时用的是FAT32格式的U盘超过4GB的单文件会被拒绝而且小文件校验也容易出问题。建议用ext4或xfs格式的U盘。如果你的U盘是NTFS在Linux下有时挂载会出问题尽量避开。第四SELinux。openEuler默认SELinux是Enforcing模式如果离线安装后桌面登录异常可以查一下SELinux的审计日志ausearch -m avc -ts recent如果发现大量AVC denied记录可以先临时切换到Permissive模式验证setenforce 0确认是SELinux导致的再针对具体进程做放行策略而不是直接永久关闭。虽然内网环境关闭SELinux影响不大但毕竟是等保评测时可能被扣分的项能保留还是尽量保留。5.2 比UKUI安装更值得做的事情装完UKUI只是开始。在真正的交付项目里客户往往还会要求预装办公软件、字体、输入法、浏览器、远程协助工具。这些软件同样面临离线安装的问题。既然你已经用createrepo搭好了本地仓库的架子不如顺手把生产环境里常用的一批软件也打包进仓库里比如dnf download --resolve --alldeps firefox --destdir/data/ukui-rpms dnf download --resolve --alldeps fcitx5 fcitx5-chinese-addons --destdir/data/ukui-rpms dnf download --resolve --alldeps libreoffice-writer --destdir/data/ukui-rpms然后在U盘上重新生成一次仓库元数据整个仓库就成了一个可持续扩展的离线软件中心。后续不管是新装机器还是故障重装都只需要插上U盘改一下repo文件然后dnf install你想要的软件就好。这一步做下来你就从一个“临时应急解决UKUI安装”的人变成了“为整个内网环境搭建了离线软件分发体系”的人。领导对你的评价会完全不一样。5.3 再分享一个小技巧把仓库封装成可复用脚本如果你以后要反复部署多台机器建议把配置本地仓库的过程写成脚本放到U盘里。脚本内容很简单#!/bin/bash REPO_PATH/mnt/usb mount /dev/sdb1 $REPO_PATH cat /etc/yum.repos.d/local-ukui.repo EOF [local-ukui] nameLocal UKUI Repository baseurlfile://$REPO_PATH/ukui-rpms enabled1 gpgcheck0 EOF dnf clean all dnf makecache到了新机器上执行这个脚本一分钟内仓库就能就绪。配合后面那6000多字的正文来看整个离线交付的套路就完整了。根据我个人经验离线安装桌面这事儿最难的地方其实不在安装过程本身而在前期的依赖资源准备和仓库设计上。只要把“攒包机—仓库制作—目标机仓库配置”这条链路打通后续无论是UKUI还是其他图形组件都是同一个套路重复应用。踩过几次坑之后你就会发现真正的内网交付高手往往不是记了多少命令而是会提前把“弹药”备到位让dnf在断网环境下也能游刃有余。