本文档堪称一部史诗,详细记录了我们如何将一个在Windows上岁月静好的Python项目,扔进一个“毛坯房”风格的青龙Docker容器里,并最终让它活下来的全过程。我们一路上降妖除魔,克服了环境不匹配、工具玩失踪、网络闹脾气以及依赖包“水土不服”等一系列经典且令人头秃的难题。
第一阶段:西天取经的目标与出发点
-
核心目标: 部署位于Ubuntu服务器上的青龙容器里的Python脚本,这些脚本使用了具备跨平台使用的三方工具LibreOffice,让它能在不同操作系统下自动修正多种格式(
.doc,.docx,.xls,.xlsx,.pdf)文件里的错别字。 -
出发地 (本地环境): Windows系统,一个安逸舒适的“花果山”,所有依赖都已配齐,脚本运行丝滑。
-
目的地 (服务器环境): 一台Ubuntu服务器,其上住着一个标准的青龙面板Docker容器——我们的“西天”。
第二阶段:初入宝地,各路神仙先给个下马威
第一难:驯服上古神兽.doc
我们的脚本需要一位法力高强的神仙LibreOffice,来将老旧的.doc格式“点化”成现代的.docx。因此,首要任务是在青龙容器里把这位神仙请出来。
-
遇到的难题 1.1:错误的“咒语”:念了
apt-get,神仙没反应-
现象: 进入容器后,我们想当然地念出咒语
apt-get install libreoffice,结果系统返回apt-get: command not found。 -
原因分析: 我们以为住进了精装修的Ubuntu大平层,结果一开门,发现是个极简风的Alpine毛坯房。
-
解决方案: 换个法术!放弃
apt-get,改用Alpine的本地咒语apk。一句apk add libreoffice,神仙乖乖现身。
-
-
遇到的难题 1.2:神仙开口,满嘴“豆腐块”
-
现象: LibreOffice请来后,一处理包含中文的文档,就满屏方框乱码,仿佛在说天书。
-
原因分析: 这间毛坯房里连个中文字帖都没有,神仙不识字,可不就满嘴豆腐块嘛。
-
解决方案: 赶紧贴几张字画!我们最终选择了更潮、更全面的
font-noto-cjk。一句apk add font-noto-cjk,神仙终于能说人话了。
-
-
遇到的难题 1.3:神仙吐出的“龙珠”去哪了?
-
现象: 测试脚本成功运行,日志显示已生成
.docx文件,但青龙面板的管家却说没看见。 -
原因分析: 青龙面板的管家只关心剧本(脚本文件),对演员们下的蛋(生成的文件)不感兴趣。而且我们也不知道这颗蛋下在了哪个角落。
-
解决方案:
-
地毯式搜查:在容器内使用
find / -name "文件名",像开了天眼,瞬间定位了龙珠的藏匿地点。 -
隔空取物: 使用
docker cp <容器名>:<绝对路径> <宿主机路径>这招,成功将龙珠从容器里掏出来,下载到本地检查,确认法力无边!
-
-
第三阶段:行至中途,真正的挑战开始
第二难:给项目“搬家”的风水问题
我们制定了标准的搬家流程:本地打包 -> 上传服务器 -> 扔进容器 -> 开箱入住。
-
遇到的难题 2.1:水土不服:行李上的中文标签全变火星文
-
现象: 从Windows打包的
.zip行李箱,在容器里一打开,所有中文标签都变成了看不懂的符号。 -
原因分析: Windows管家打包用的是“方言”(GBK),而Linux管家开箱用的是“普通话”(UTF-8),语言不通,自然鸡同鸭讲。
-
解决方案探索:
-
方案A (失败): 尝试请系统翻译官
unzip -O GBK来帮忙,结果翻译官太老,不认识-O这个新词。 -
方案B (失败): 花钱请了个高级翻译官
apk add unzip,结果还是个老古董,依然不认识-O。 -
方案C (王炸): 自己动手,丰衣足食。既然系统自带的翻译官又老又笨,我们干脆自己写一个Python翻译官(
unzip_gbk.py)。利用zipfile库并手动进行方言转换(filename.encode('cp437').decode('gbk')),天下太平。unzip_gbk.py脚本内容:import zipfile import sys import os def unzip_with_gbk(zip_file_path): """ 使用GBK编码解压zip文件,解决中文文件名乱码问题。 """ if not os.path.exists(zip_file_path): print(f"错误:文件 '{zip_file_path}' 不存在。") return print(f"正在解压文件: {zip_file_path}") with zipfile.ZipFile(zip_file_path, 'r') as zf: for member in zf.infolist(): try: # 关键:先用默认的cp437编码得到原始字节,再用GBK解码成正确的字符串 correct_filename = member.filename.encode('cp437').decode('gbk') except: # 如果GBK解码失败,则使用原始文件名(可能是英文或UTF-8) correct_filename = member.filename # 如果是目录,则创建目录 if member.is_dir(): os.makedirs(correct_filename, exist_ok=True) continue # 提取文件内容 file_content = zf.read(member) # 确保文件的父目录存在 if os.path.dirname(correct_filename): os.makedirs(os.path.dirname(correct_filename), exist_ok=True) # 写入文件 with open(correct_filename, 'wb') as f: f.write(file_content) print(f" -> 已解压: {correct_filename}") print("解压完成!") if __name__ == "__main__": if len(sys.argv) < 2: print("用法: python3 unzip_gbk.py <你的zip文件名>") else: file_to_unzip = sys.argv[1] unzip_with_gbk(file_to_unzip)
-
-
第三难:请神容易送神难之PyMuPDF
这是我们遇到的最困难、最核心的挑战。脚本需要另一位大神fitz,但请神的过程堪比西天取经。
-
遇到的难题 3.1:神仙的“马甲”问题
-
现象:
ModuleNotFoundError: No module named 'fitz',但本地pip list里也找不到fitz。 -
原因分析:
fitz是神仙下凡行走江湖用的“花名”,而PyMuPDF才是他在天庭注册的“真名”。你要请神,得喊对真名才行。
-
-
遇到的难题 3.2:“欧标插头”插不进“国标插座”
-
现象:
pip install PyMuPDF后,运行时报错ImportError: Error relocating ... symbol not found。 -
原因分析: 官方给的
PyMuPDF是个进口电器,带的是欧标插头(glibc库)。可我们的Alpine毛坯房里,预留的是国标插座(musl libc库)。插不进去,急死人。 -
解决方案: 现场施工,改造插头。我们干脆不要那个进口电器了,直接在房间里(容器内)用本地材料(
apk add build-base...)现场组装一个。一句pip install --no-binary...,开始现场施工。
-
-
遇到的难题 3.3:施工队被“海关”拦下了 (最顽固的敌人)
-
现象: 现场施工需要从国外(
mupdf.com)进口一批核心原料(C++源码包),但我们的施工队每次去拉货,都被“海关”(网络防火墙)以各种理由(ConnectionResetError)劝返。 -
原因分析: 容器的网络环境访问该国外服务器存在持续性的连接问题,这在中国大陆的网络环境下很常见。
-
解决方案探索:
-
方案A (失败): 手动走私原料,结果原料在路上颠簸坏了(哈希校验失败),被施工队当场扔掉,然后他们又头铁地去闯关。
-
方案B (失败): 换个版本的原料,结果还是被同一个海关拦下。
-
方案C (终极大法):开辟“走私”通道。既然正门走不通,我们就从隔壁能通关的邻居家(Windows电脑
192.168.1.67)挖条地道。我们在邻居家开了个“允许邻居借道”的后门,然后在施工队出发时给他们一张小纸条(http_proxy=...),告诉他们从地道走。最终,原料顺利运达,施工成功!
-
-
第四阶段:取得真经与感悟
-
成果盘点:毛坯房变豪华别墅(和它的物业费): 经过上述所有操作,我们发现最终的Docker镜像从500MB暴增到2.22GB。这完全正常!你把一个空房间,硬是塞进了一整套宜家(LibreOffice)和一座小型机械加工厂(C++编译工具链),不变胖才怪!我们还学会了如何通过
apk del build-base来给别墅“减肥”。 -
最后的大彻大悟:青龙面板的“大锅饭”哲学: 我们终于搞明白,青龙面板不搞“单间”(
venv虚拟环境)那套,所有脚本都在一个大食堂里吃“大锅饭”(全局Python环境)。所以,请客吃饭(装依赖)必须直接往大锅里加菜,别在自己单间里捣鼓。
这次取经之路虽然磨难重重,但我们最终修成正果,收获的不仅是能运行的脚本,更是一身降妖除魔的本领。

432

被折叠的 条评论
为什么被折叠?



