资讯动态

Ubuntu 20.04安装Python 2.7:源码编译、虚拟环境与Docker容器化部署指南

发布时间:2026/8/12 23:06:40 来源:尧图企业网站定制
1. 项目概述为什么在2024年还要折腾Python 2.7最近在整理一个老旧的自动化运维脚本仓库时我遇到了一个经典问题几个核心的资产盘点和服务探活脚本是七八年前用Python 2.7写的里面大量使用了print语句不带括号、urllib2、以及老式的字符串处理逻辑。直接迁移到Python 3固然是终极方案但时间紧任务重我需要先让这些脚本在全新的Ubuntu 20.04.3 LTS服务器上跑起来保障现有业务流程不中断。Ubuntu 20.04本身已经不再预装Python 2这成了第一个拦路虎。这个需求听起来很“复古”但在企业运维、遗留系统维护甚至是一些特定科学计算和工业控制场景下依然真实存在。如果你也面临类似处境——需要为一个新部署的系统临时兼容一个老项目或者维护一个短期内无法重写的核心遗产代码——那么这篇在Ubuntu 20.04.3 LTS上安装和配置Python 2.7的完整指南就是为你准备的。我将不仅告诉你如何安装更会分享如何安全、隔离地使用它以及最终如何规划向Python 3的过渡。2. 环境准备与方案选型并非只有apt install一条路在开始敲命令之前我们先理清思路。在Ubuntu 20.04上获取Python 2.7主要有三种路径每种都有其适用的场景和需要权衡的利弊。2.1 方案对比源码编译、第三方仓库与容器化方案一从源码编译安装这是最经典、最可控的方式。直接从Python官网下载2.7系列的最终版本如2.7.18源码包在本地编译。它的最大优势是纯净和高度可定制化。你可以指定安装路径例如/opt/python27与系统自带的Python 3完全隔离避免污染系统环境。同时你可以根据需要开启或关闭某些模块如SSL支持、sqlite3模块这对于构建最小化运行环境或解决特定依赖问题非常有用。缺点是步骤稍多需要手动解决开发工具链和部分库的依赖并且后续的包管理pip也需要单独安装和配置。方案二使用第三方PPAPersonal Package Archive仓库Ubuntu社区有一些维护者提供了包含Python 2.7的PPA例如知名的deadsnakes团队。通过添加他们的仓库你可以直接用apt命令安装就像安装任何其他软件包一样便捷。这种方法省去了编译的麻烦安装速度快并且通常能较好地集成到系统的包管理体系中。但它的风险在于你需要信任第三方仓库的维护者。此外通过系统包管理器安装的Python 2.7其二进制文件通常会被放在/usr/bin/python2.7可能会与某些期望/usr/bin/python就是Python 2的系统工具或脚本产生预期外的交互。方案三使用Docker容器这是目前最推荐用于处理遗留环境的方法尤其是在生产环境中。你可以拉取一个包含Python 2.7的官方镜像如python:2.7-slim或者基于Ubuntu 18.04等仍支持Python 2的系统创建自定义镜像。所有依赖都被封装在容器内与宿主机环境彻底隔离绝对安全。部署和清理都极其方便。缺点是需要你具备一定的Docker使用知识并且对于需要直接与宿主机硬件或特定目录交互的脚本需要配置卷挂载和权限稍显复杂。注意对于绝大多数寻求快速、稳定解决方案的运维场景我强烈推荐方案一源码编译或方案三Docker。方案二PPA在可控性上稍弱本文将以方案一作为主线进行详细演示因为它最具教学意义能让你理解整个底层过程之后无论采用哪种方案都能心中有数。同时我会在关键节点穿插对Docker方案的说明。2.2 基础系统准备无论选择哪种方案我们都需要确保系统具备编译软件或管理容器的基础能力。首先更新软件包列表并升级现有软件包是一个好习惯。sudo apt update sudo apt upgrade -y接下来安装编译Python源码所必需的开发工具和库。这些包包括编译器、链接器、标准库头文件以及Python某些核心模块如zlib,sqlite3,ssl所依赖的开发文件。sudo apt install -y build-essential sudo apt install -y zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-devbuild-essential是一个元数据包它包含了gcc,g,make等核心编译工具。后面那一长串*-dev包则是为了确保编译出的Python支持常见的功能模块。例如缺少libssl-devssl模块就无法编译会导致使用pip安装某些需要HTTPS连接的包时失败缺少zlib1g-dev则无法处理压缩文件。3. 源码编译安装Python 2.7.18全流程我们选择Python 2.7系列的最终版本2.7.18进行安装这是一个包含最终安全修复的版本。3.1 下载源码与解压首先找一个合适的目录例如/usr/src用于存放源码。使用wget从Python官网下载源码包。cd /usr/src sudo wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz下载完成后解压源码包并进入解压后的目录。sudo tar -xzf Python-2.7.18.tgz cd Python-2.7.183.2 配置编译选项运行configure脚本。这一步会检查系统环境生成适合当前系统的Makefile。这里有几个关键参数需要指定--prefix/opt/python27这是最重要的参数。它指定了Python的安装目录。我们将其安装到/opt目录下这是一个用于存放第三方独立软件的常规位置与/usr下的系统软件隔离。--enable-optimizations这个选项会运行一些测试并基于测试结果优化生成的二进制文件使其运行速度提升约10%。但这会显著增加编译时间可能翻倍。对于生产环境建议开启如果只是想快速验证可以省略。--enable-shared生成共享库libpython2.7.so。有些第三方C扩展模块可能需要链接这个共享库。通常建议加上。sudo ./configure --prefix/opt/python27 --enable-optimizations --enable-shared配置过程会输出一系列检查结果只要没有出现明显的“not found”错误尤其是前面安装的那些*-dev库就可以继续。3.3 编译与安装接下来使用make命令进行编译。-j参数后面跟的数字表示并行编译的作业数通常设置为CPU核心数可以加快编译速度。你可以用nproc命令查看核心数。sudo make -j$(nproc)编译完成后执行安装。sudo make install至此Python 2.7.18就已经被安装到了/opt/python27目录下。你可以验证一下/opt/python27/bin/python2.7 --version应该输出Python 2.7.18。3.4 解决共享库路径问题由于我们使用了--enable-shared并安装到了非标准路径系统可能找不到Python的动态链接库。直接运行上述命令可能没问题但当你尝试导入某些模块或第三方C扩展时可能会遇到类似“error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file”的错误。我们需要告诉系统到哪里去找这个库。有两种方法方法一临时生效推荐用于测试在运行Python前设置LD_LIBRARY_PATH环境变量。export LD_LIBRARY_PATH/opt/python27/lib:$LD_LIBRARY_PATH /opt/python27/bin/python2.7 -c import ssl; print(ssl.OPENSSL_VERSION)方法二永久生效创建一个配置文件让系统在启动时自动加载该路径。echo /opt/python27/lib | sudo tee /etc/ld.so.conf.d/python27.conf sudo ldconfig执行sudo ldconfig命令后系统会重新加载库文件缓存之后就可以直接运行Python而无需设置环境变量了。3.5 安装并配置pipPython 2.7.18的安装包可能没有自带pip或者自带的版本很旧。我们需要手动安装它。首先下载get-pip.py安装脚本。注意pip官方已经停止了对Python 2的支持但我们可以使用一个最终兼容的版本。wget https://bootstrap.pypa.io/pip/2.7/get-pip.py然后使用我们刚安装的Python 2.7来运行这个脚本。--user参数会将pip安装到当前用户的目录下~/.local/bin避免需要sudo权限。但为了全局使用我们通常直接安装到Python的目录中。sudo /opt/python27/bin/python2.7 get-pip.py安装完成后pip和pip2命令会被安装在/opt/python27/bin/目录下。为了方便使用我们可以创建一个软链接到/usr/local/bin/这个目录通常在普通用户的PATH环境变量中。sudo ln -s /opt/python27/bin/pip2 /usr/local/bin/pip2现在你可以在终端中直接使用pip2命令来为这个Python 2.7环境安装包了例如pip2 install requests。实操心得在编译安装后务必测试核心模块是否能正常导入特别是ssl和sqlite3。我曾经遇到过因为漏装libsqlite3-dev导致Django的数据库后端无法工作的问题。一个快速的测试命令是/opt/python27/bin/python2.7 -c “import sqlite3, ssl, zlib; print(‘All core modules imported successfully.’)”。4. 虚拟环境与依赖管理隔离是王道直接在系统级Python 2.7环境下安装项目依赖是危险的容易引发包版本冲突。对于Python 2.7项目我强烈建议使用virtualenv来创建独立的虚拟环境。4.1 安装virtualenv首先确保pip2已经就绪然后用它安装virtualenv。sudo pip2 install virtualenv4.2 为项目创建虚拟环境假设你的老项目代码在/home/user/old_project目录下。cd /home/user/old_project virtualenv -p /opt/python27/bin/python2.7 venv这个命令做了两件事-p参数指定了使用我们自定义安装的Python 2.7解释器。在当前目录下创建了一个名为venv的文件夹里面包含了一个独立的Python环境。4.3 使用虚拟环境激活虚拟环境后所有Python和pip操作都会被限制在这个“沙箱”内。source venv/bin/activate激活后终端提示符通常会发生变化前面会多出(venv)字样。此时python命令指向的是虚拟环境内的2.7解释器pip命令也指向虚拟环境内的pip。(venv) userserver:~/old_project$ python --version Python 2.7.18 (venv) userserver:~/old_project$ which python /home/user/old_project/venv/bin/python接下来你就可以在虚拟环境中安全地安装项目依赖了。如果项目有requirements.txt文件直接使用(venv) pip install -r requirements.txt如果没有则需要根据项目文档或代码中的import语句手动安装。完成工作后使用deactivate命令退出虚拟环境。(venv) deactivate5. 常见问题与故障排查实录在实际操作中你几乎一定会遇到下面这些问题。这里我把自己踩过的坑和解决方案整理出来。5.1 编译阶段错误问题1ModuleNotFoundError: No module named ‘_ctypes’或在配置阶段报错。原因缺少libffi的开发文件。解决安装libffi-dev包然后重新执行configure和make。sudo apt install -y libffi-dev问题2pip install时SSL证书验证失败。现象pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.原因Python编译时没有正确链接到系统的OpenSSL库。可能是在configure阶段缺少libssl-dev或者OpenSSL库的路径不标准。解决确保已安装libssl-dev。在编译前可以尝试找到OpenSSL的路径ls -l /usr/lib/x86_64-linux-gnu/libssl*。有时需要显式指定OpenSSL路径进行重编译sudo ./configure --prefix/opt/python27 --with-openssl/usr --enable-optimizations sudo make clean sudo make -j$(nproc) sudo make install5.2 运行时问题问题3运行Python脚本时提示/usr/bin/python: bad interpreter: No such file or directory。原因脚本的shebang行第一行指向了#!/usr/bin/python而这个路径在Ubuntu 20.04上默认不存在可能是python3。解决修改脚本的shebang行指向我们安装的Python 2.7解释器绝对路径例如#!/opt/python27/bin/python2.7。或者在虚拟环境中运行脚本因为激活虚拟环境后python命令会指向正确的解释器。问题4使用pip2安装包时速度极慢或连接超时。原因PyPI的官方源在国外且对老旧pip版本的支持可能不佳。解决为pip配置国内镜像源。创建或编辑pip配置文件~/.pip/pip.conf对于全局pip是/etc/pip.conf[global] index-url https://pypi.tuna.tsinghua.edu.cn/simple trusted-host pypi.tuna.tsinghua.edu.cn对于虚拟环境中的pip可以在激活环境后使用pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package临时指定。5.3 与系统Python 3的共存问题5如何区分python、python2、python3命令这是我们自定义安装的Python 2.7位于/opt/python27/bin/python2.7。我们为其pip创建了软链接pip2。系统自带的Python 3位于/usr/bin/python3其包管理命令是pip3。/usr/bin/python这个符号链接在Ubuntu 20.04上默认指向python3。强烈建议不要修改它因为很多系统工具如apt依赖于此。我们应该始终使用完整路径或我们创建的别名/虚拟环境来调用Python 2.7。一个清晰的管理习惯是永远不在系统级/usr/bin/的python或pip命令下安装Python 2的包。所有操作都通过/opt/python27/bin/python2.7、pip2或在虚拟环境中进行。6. 备选方案使用Docker容器运行Python 2.7环境如果你觉得编译安装和配置环境变量太麻烦或者需要在多台机器上快速部署一致的环境Docker是最佳选择。6.1 快速启动一个Python 2.7交互环境docker run -it --rm python:2.7-slim bash这条命令会docker run运行一个容器。-it以交互模式运行并分配一个伪终端。--rm容器退出后自动删除用于临时测试。python:2.7-slim使用官方的、基于Debian的轻量级Python 2.7镜像。bash在容器内启动bash shell。进入容器后你会发现Python 2.7和pip已经安装好了可以直接使用。6.2 使用Dockerfile构建项目专属镜像对于正式项目你应该创建一个Dockerfile来固化环境。# Dockerfile FROM python:2.7-slim WORKDIR /app # 将宿主机的项目依赖文件复制到容器内 COPY requirements.txt . # 安装依赖使用国内镜像加速 RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt # 复制项目代码 COPY . . # 指定容器启动时默认运行的命令例如你的主脚本 CMD [python, main.py]然后在项目根目录构建镜像并运行# 构建镜像 docker build -t my-old-python-app . # 运行容器并将宿主机的当前目录挂载到容器的/app目录方便开发调试 docker run -it --rm -v $(pwd):/app my-old-python-app # 或者以守护进程模式运行 docker run -d --name my-app -v $(pwd):/app my-old-python-appDocker方案将环境隔离做到了极致宿主机系统保持绝对干净。当你不再需要这个老项目时只需要删除镜像和容器即可没有任何残留。7. 从Python 2到Python 3的迁移思考与工具安装Python 2.7只是权宜之计。长期来看将代码迁移到Python 3是必须完成的任务。这里分享一些启动迁移的思路和工具。第一步使用2to3进行初步语法转换Python自带了一个名为2to3的工具可以自动修复许多常见的语法差异。务必在代码备份上进行操作# 查看2to3会建议哪些修改不实际修改文件 2to3 your_script.py # 将修改写回原文件使用 -w 参数 2to3 -w your_script.py2to3能处理诸如print语句、xrange()、unicode类型等基础问题但对于更复杂的逻辑差异如迭代器行为、标准库模块重组则无能为力。第二步使用python-future和six库对于需要同时维护Python 2和Python 3兼容性一段时间的项目可以使用future和six这两个兼容层库。它们提供了统一的API让你可以用一种写法同时支持两个版本。第三步全面测试迁移后测试是重中之重。你需要覆盖所有功能分支特别是涉及字符串文本/二进制、网络I/O、文件操作和外部API调用的部分。编写或完善单元测试是保障迁移质量最有效的手段。第四步利用现代工具辅助像pylint、mypy这样的静态分析工具以及caniusepython3这样的包可以帮助你识别代码中不兼容Python 3的部分和依赖项。最后我个人在实际操作中的体会是处理遗留的Python 2代码心态比技术更重要。不要试图一次性完美迁移一个庞大的项目。可以采取“分而治之”的策略先通过本文的方法让它在隔离环境中运行起来保证业务连续性。然后将项目拆分成模块逐个模块进行迁移、测试和替换。对于最核心、最复杂的部分甚至可以将其重写为一个小型的独立服务。记住最终的目标不是“安装好Python 2.7”而是“安全地告别Python 2.7”。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价