如果你在2025年还要在一台CentOS 7服务器上安装Python和Jupyter多半不是想考古而是手上正好有一台跑业务的旧机器或者公司内部统一用的是这套系统。CentOS 7默认的Python还是2.7直接pip装新库基本处处碰壁更别提跑Jupyter Notebook。把Python 3和新版Jupyter装好除了能获得一个网页版的Python交互环境也能给数据分析、爬虫、量化策略调试提供一个相对稳定的远程工作区。这篇文章整理了我最近一次在CentOS 7上从零配置Python和Jupyter的完整过程覆盖源码编译和Miniconda两种路线、远程访问配置、systemd后台运行以及常遇到的网络、依赖和Jupyter打不开等坑希望对正在折腾同一件事的人有帮助。1. 先看清环境CentOS 7的现状与安装方案选择1.1 为什么还在用CentOS 7它到底卡在哪CentOS 7的生命周期在2024年年中已经正式结束官方软件源进入了归档状态。很多新装系统的人可能不理解都停止维护了为什么还有那么多服务器在跑CentOS 7原因很简单生产环境迁移成本太高或者是虚拟机上跑着某些老项目内核和依赖不敢动。我这次要装的机器也是这种情况内部文档和监控脚本都依赖CentOS 7的既有环境系统不能重装只能在这个基础上补Python和Jupyter。CentOS 7默认的Python是2.7.5这个版本的问题不是你写不了代码而是整个生态已经抛弃了Python 2。现在pip安装包默认走的是PyPI大量包的最新版本根本不支持Python 2.7就算你强行装也会遇到依赖解析失败、编译报错甚至装完import直接崩。Jupyter Notebook虽然曾经支持Python 2但新版早就放弃了所以想在CentOS 7上稳定用Jupyter第一步就是装一个干净的Python 3环境。除了Python版本老CentOS 7还有几个暗坑openssl版本偏低最新Python源码编译时容易报ssl模块缺失sqlite版本也偏老导致后面跑一些ORM和数据分析库时出诡异问题yum源里的gcc和编译依赖不全编译Python时中途报错。这些都不是Jupyter本身的问题但会在安装过程中连环引爆。1.2 安装Python和Jupyter的路线怎么选在CentOS 7上装Python 3主流有三条路yum源安装、源码编译安装、Miniconda安装。yum源安装最省事比如通过软件集合库Software Collections装Python 3.6但这套方案的缺点是版本太旧而且需要额外开启SCL源。对于想用现代Python库的人来说3.6已经不太够用了很多新库和语法特性都不支持。源码编译安装路径最正统也不依赖发行版的包管理生态适合要严格控制Python版本的场景。缺点是编译时间长依赖要自己补齐尤其是openssl、libffi、sqlite这些基础库漏一个后面就会报奇怪错误。Miniconda安装是我个人最推荐的方式。它自带独立的Python发行版和包管理器安装时不用碰系统自带的Python 2.7创建虚拟环境也特别方便装Jupyter只需要一个conda或者pip命令。更重要的是Miniconda的Python默认会把openssl、readline、sqlite等底层库打包好省去源码编译时那一大堆配置和调试。对于“只要能用Jupyter写代码”这个目标来说Miniconda是性价比最高的选择。如果你的生产环境不允许装Miniconda这种第三方发行版那再走源码编译也不迟。下面的内容我会把两条路线都写一遍你可以根据机器情况选。2. 系统层面准备换源、装依赖、解决网络类问题2.1 先换一个能用的yum源别让安装停在第一步CentOS 7停止维护后官方yum源里的很多包已经无法正常拉取即使能访问速度也慢得离谱。我一般先把yum源切换到阿里云或者清华的CentOS 7镜像这个过程并不复杂但要注意备份原文件。第一步备份原始repo文件cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak第二步下载阿里云提供的CentOS 7源文件curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo如果curl命令不在可以用wget或者直接把文件下载下来再上传。下载完成后执行清理和重建缓存yum clean all yum makecache同时建议安装EPEL扩展源后面很多编译依赖和工具包都在EPEL里yum install -y epel-release yum install -y wget vim net-tools lrzsz这里有个细节CentOS 7的repo文件中默认URL可能指向mirrorlist或者已经失效的链接。如果你执行yum命令时报“Could not retrieve mirrorlist”或者无法解析地址多半是网络配置或DNS出了问题先按下面的思路排查。2.2 先把“ping不通百度”这类问题解决掉新装的CentOS 7虚拟机经常会出现ping不通外网的情况尤其是用VMware或者VirtualBox的时候。有人一看到ping不通百度就开始怀疑网络配置但在排查之前先想一下顺序通不通网取决于三层物理链路、IP路由、DNS解析。先看IP地址和路由是否正常ip addr ip route如果ip addr里网卡没有IP可能是网卡没有自动启动。CentOS 7默认的网卡配置文件在/etc/sysconfig/network-scripts/ifcfg-eth0检查里面是否有ONBOOTyes没有的话改成yes然后重启网络服务systemctl restart network如果是云服务器或者公司内网则要确认是否为DHCP动态获取。如果ip route显示默认网关缺失很影响外网访问。常见做法是ip route add default via 192.168.1.1 dev eth0但这只是临时生效长期用还是要改配置文件。DNS问题也很常见。如果你能ping通IP地址比如ping -c 3 223.5.5.5能通但ping域名不通那一定是DNS解析的问题。我看过太多CentOS 7的/etc/resolv.conf里写的DNS还是网关地址解析慢或者直接失败。临时解决办法echo nameserver 223.5.5.5 /etc/resolv.conf echo nameserver 114.114.114.114 /etc/resolv.conf永久办法是修改网卡配置文件的DNS1、DNS2字段然后重启网络服务。这一步看起来和安装Python没关系但如果不解决后面下载源码包、pip安装库都会卡死甚至报“Cannot fetch index base URL”。2.3 安装编译依赖这一步别图省事无论你走Miniconda还是源码编译我都建议先把系统基础的编译工具链装好。Miniconda虽然自带底层依赖但某些pip包安装时仍需调用gcc编译扩展模块。源码编译Python更是必须。一次性把常用的依赖装齐yum install -y gcc gcc-c make kernel-devel yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel libffi-devel逐个解释一下为什么需要这些东西。gcc和make是编译C扩展的基础没有它们源码编译Python时会卡在“building Python”阶段。openssl-devel对应Python的ssl模块缺失之后pip和Jupyter的HTTPS访问都会失败。libffi-devel对应ctypes模块不装的话会报ModuleNotFoundError: No module named _ctypes。sqlite-devel对应Python内建的sqlite3模块不装的话后面有些Python包会报找不到sqlite库。还有一个容易踩的坑CentOS 7自带的openssl版本是1.0.2用源码编译Python 3.10以上时ssl模块默认会尝试用系统openssl如果版本太老新版的hashlib、ssl会出现兼容问题。我后面一般会建议不使用系统openssl或者干脆用Miniconda方案绕开它。3. 安装Python源码编译与Miniconda双方案3.1 源码编译Python 3.10适合需要严格控制版本的场景如果你要编译安装Python推荐选3.10或者3.9这个档位兼容性好主流第三方库都支持。太高版本比如3.12、3.13在某些老机器上可能出现编译工具链过旧的问题。下面以Python 3.10.11为例。先下载源码包。如果机器能访问外网可以从python.org下载wget https://www.python.org/ftp/python/3.10.11/Python-3.10.11.tgz如果外网慢就改用国内镜像比如华为云的Python镜像把URL替换成对应路径即可。下载完成后解压并编译tar xzf Python-3.10.11.tgz cd Python-3.10.11 ./configure --prefix/usr/local/python310 --enable-optimizations make -j$(nproc) make altinstall这里有两个关键点。第一--enable-optimizations会启用Python的PGO优化编译时间会明显变长但运行性能更好。不愿意等的话可以去掉。第二使用altinstall而不是install这一点一定不能错。install会覆盖系统自带的/usr/bin/pythonCentOS 7的yum工具是依赖Python 2.7的一旦覆盖系统包管理直接瘫痪。编译安装完成后Python二进制在/usr/local/python310/bin/python3.10。为了方便调用可以建立软链接ln -s /usr/local/python310/bin/python3.10 /usr/local/bin/python3 ln -s /usr/local/python310/bin/pip3.10 /usr/local/bin/pip3注意不要动/usr/bin/python。检查一下/usr/local/bin/python3 -V /usr/local/bin/pip3 -V这时候用pip安装Jupyter即可但因为系统openssl版本老我建议后面用虚拟环境时再装避免污染全局。3.2 Miniconda方案一键搞定Python和JupyterMiniconda相比源码编译更省心尤其适合不太熟悉Linux底层编译机制的人。下载最新版安装脚本wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh再执行安装脚本bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/miniconda3-b表示静默安装不交互-p指定安装目录。很多教程会让你一路回车这里直接指定目录更可控。安装完成后初始化conda的环境变量/opt/miniconda3/bin/conda init这会往~/.bashrc里写入初始化代码然后执行source ~/.bashrc生效。执行后你应该能看到命令提示符前面出现(base)环境标识。如果你不希望默认进入base环境可以执行conda config --set auto_activate_base false为了加快后续Python包下载速度先把conda的镜像源切换到国内源。配置~/.condarc文件channels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud执行conda clean -i清空索引缓存然后创建独立Python环境conda create -n jupyter310 python3.10 -y conda activate jupyter310之后所有Python操作都在这一个环境里不会影响系统Python也不会和别的项目打架。3.3 两种方案到底怎么选我给你的建议源码编译和Miniconda不是非此即彼的关系。我的判断标准就三条如果你的服务器是受限环境不允许安装Miniconda这类第三方软件那就源码编译注意把依赖补齐。如果你只是要一个分析环境不想跟系统依赖纠缠Miniconda是首选。如果你对Python版本有严格管理需求比如多个项目需要不同Python版本和包集合conda的环境管理也比源码编译后手动建虚拟环境更方便。实在拿不准的时候先试Miniconda。它装了不想要可以整个目录删掉几乎不会残留系统级垃圾。源码编译装错了反倒难清理还容易污染系统路径。4. 安装并配置Jupyter Notebook4.1 在虚拟环境里安装Jupyter Notebook和JupyterLab如果走Miniconda方案先激活环境conda activate jupyter310再安装Jupyter全家桶。我不喜欢只装一个notebook而是把jupyter、notebook、jupyterlab一起装方便后续切换界面pip install jupyter notebook jupyterlab如果你走的是源码编译方案建议先创建虚拟环境再安装/usr/local/bin/python3 -m venv /opt/jupyter-env source /opt/jupyter-env/bin/activate pip install jupyter notebook jupyterlab安装过程会拉取一大串依赖包括ipykernel、nbconvert、traitlets等。如果网络不稳可以给pip加国内源pip install jupyter notebook jupyterlab -i https://mirrors.aliyun.com/pypi/simple/安装完成后先不要急着启动因为仅仅启动Jupyter还只能在本机访问想远程用还需要做几项配置。4.2 生成配置文件并设置登录密码先执行一次配置文件的生成命令jupyter notebook --generate-config生成的文件一般在~/.jupyter/jupyter_notebook_config.py。如果你是以root身份运行可能还需要额外关心允许root启动的问题这个后面会说。生成密码有两种方式。第一种是交互式输入jupyter notebook password执行后会提示输入密码密码会保存到~/.jupyter/jupyter_notebook_config.json。第二种是把密码哈希值直接写进config文件适合脚本化部署。我一般用第一种简单直接。然后用vim编辑配置文件vim ~/.jupyter/jupyter_notebook_config.py至少改这几个关键项c.ServerApp.ip 0.0.0.0 c.ServerApp.port 8888 c.ServerApp.open_browser False c.ServerApp.allow_root True c.ServerApp.password 如果你安装的是新版本Notebook可能用的不是NotebookApp而是ServerApp两种写法都在配置模板里按你自己的版本注释来改。ip设置为0.0.0.0表示允许所有网卡接口访问open_browser设为False服务器上不自动打开浏览器allow_root这一项只有在root账号运行时才需要。这里有个容易被忽略的细节新版Jupyter默认会强制使用token认证。如果你刚才没有设置password启动时会打印一串token访问地址是http://IP:8888/?token...。我建议直接设置密码不然每次重启token都会变。4.3 配置远程访问防火墙、端口和systemd服务在CentOS 7上防火墙默认是firewalld。先开放Jupyter使用的8888端口firewall-cmd --permanent --add-port8888/tcp firewall-cmd --reload确认端口已经放行firewall-cmd --list-all如果是云服务器还得去云控制台的安全组放行8888端口。这一步很多人忘记导致防火墙配了还是不能访问。云平台的安全组和服务器内部防火墙是两层都要通过才能通。为了不让Jupyter随着SSH断开而退出我习惯用systemd把它做成服务。创建服务文件vim /etc/systemd/system/jupyter.service内容如下[Unit] DescriptionJupyter Notebook Server Afternetwork.target [Service] Userroot ExecStart/opt/miniconda3/envs/jupyter310/bin/jupyter-notebook --allow-root --config/root/.jupyter/jupyter_notebook_config.py Restartalways RestartSec10 [Install] WantedBymulti-user.target注意ExecStart里的路径要和你实际环境一致。如果是源码编译的虚拟环境路径要改成/opt/jupyter-env/bin/jupyter-notebook。配置完成后systemctl daemon-reload systemctl enable --now jupyter systemctl status jupyter能把服务跑起来并设置成开机自启基本上远程访问就没问题了。之后浏览器访问http://服务器IP:8888输入刚才设置的密码就能进入Jupyter网页版登录入口。4.4 把Notebook默认创建到别的文件夹很多人会遇到“Jupyter怎么创建在别的文件夹”的问题。默认情况下Jupyter会以启动时的目录为工作根目录所以你在网页上新建文件默认保存在当前目录。想换目录最简单的办法是启动前切换目录cd /data/jupyter jupyter notebook想永久指定就在配置文件里加一行c.ServerApp.notebook_dir /data/jupyter如果目录不存在先创建并设置权限mkdir -p /data/jupyter chmod 755 /data/jupyter改完配置后重启服务systemctl restart jupyter注意一个问题Jupyter的根目录相当于一个沙盒你可以在网页上访问根目录及其子目录的所有文件。想通过Jupyter访问/etc或其他系统目录是不太应该的因为服务权限通常也做不到。这个特性不是bug是为了防止浏览器端用户越权操作服务器文件。如果的确需要访问其他路径可以创建一个软链接到根目录里。5. 常见问题与避坑速查5.1 网页访问不了如何一步步排查浏览器访问http://服务器IP:8888打不开先检查服务本身是否在运行systemctl status jupyter如果状态是active且没有报错再检查端口是否监听ss -lntp | grep 8888输出里应该能看到0.0.0.0:8888的监听记录。如果只看到127.0.0.1:8888说明Jupyter只监听了本机地址config里的c.ServerApp.ip没生效多半是改错了配置文件。如果端口正常在服务器本地执行curl -I http://localhost:8888看是否返回HTTP响应。本地能通但外部不通就继续查防火墙和安全组。很多时候外部访问不通问题不在Jupyter而在出口防火墙。如果访问时提示“拒绝了连接”那可能是服务根本没起来看日志journalctl -u jupyter -n 50日志里如果有端口被占用换个端口或者杀掉占用进程lsof -i:88885.2 Jupyter里“一个cell只输出最后一行”是怎么回事初用Jupyter的人经常会写一整个cell的代码里面有多个表达式结果运行后只显示最后一个表达式的输出。这不是bug而是Jupyter的交互式设计cell最后一个表达式的值会被自动显示之前的表达式结果不会自动打印必须显式用print()才能看到。比如一个cell这样写import pandas as pd df pd.DataFrame({a: [1, 2], b: [3, 4]}) df.head()只有df.head()会显示在输出区。如果你想看到多个变量的信息用print显式输出print(df.shape) print(df.head())也可以使用IPython的display函数from IPython.display import display display(df.head()) display(df.describe())这个问题其实算不上故障但对新手来说非常困惑尤其是用Jupyter做数据分析往往需要在数据处理的每个步骤都看到中间结果。写代码时习惯性地加print()可以避免误以为结果丢了。5.3 Anaconda的Jupyter突然打不开用不了是什么原因这个问题我在本机Windows上见过很多次Linux服务器上也会出现只是概率低一些。常见原因有四个。第一个是配置文件损坏。可能是之前安装的插件或者手动修改的配置导致Jupyter启动异常。遇到这种情况备份后删除配置文件重新生成mv ~/.jupyter ~/.jupyter.bak jupyter notebook --generate-config第二个是内核注册表混乱。比如你卸载了某个Python环境但~/.local/share/jupyter/kernels里还残留着旧内核启动时会报kernel error。清理方法jupyter kernelspec list jupyter kernelspec remove kernel-name第三个是包依赖冲突。最常见的是Traitlets、MarkupSafe版本不兼容导致Notebook启动时报ImportError。我遇到过cannot import name soft_unicode from markupsafe这是因为新版MarkupSafe移除了旧接口解决办法是固定版本pip install markupsafe2.0.1第四个是端口被占用。之前有一个Jupyter实例卡死了端口没释放再启动新的就会报端口被占用。直接看端口杀掉旧进程fuser -k 8888/tcp5.4 编译Python时常见的两个坑源码编译Python时容易遇到两个非常典型的报错。第一个是ModuleNotFoundError: No module named _ctypes这个基本可以确定是缺libffi-devel。解决办法是装上这个依赖再重新编译。yum install -y libffi-devel但要注意重新编译前最好清理一下编译产物make clean ./configure ... make -j$(nproc) make altinstall第二个坑是ssl模块在Python 3.8以上编译时失败通常是CentOS 7的openssl版本太老。报错日志里会出现_ssl.c相关错误。如果不想折腾最好用Miniconda方案因为conda环境会带更新的openssl。如果就是要源码编译可以单独编译一个新的openssl并用--with-openssl参数指定路径但过程比较繁琐。5.5 问题速查表我把CentOS 7上安装和运维Jupyter常遇的问题整理成一张表方便对照。现象大概率原因解决动作ping不通百度但内网通DNS配置不对或网关缺失检查resolv.conf和ip routeyum报mirrorlist失效官方源已归档更换阿里云或清华源编译Python报missing zlib缺zlib-develyum install zlib-devel编译Python报_ctypes缺失缺libffi-develyum install libffi-develpip非常慢或超时默认源访问慢配置阿里云pip源Jupyter只能本机访问config中ip未设置0.0.0.0修改ServerApp.ip外网还是不能访问云安全组未放行端口云控制台开放8888/tcp启动报端口被占用旧进程未退出fuser -k 8888/tcpcell只显示最后一个表达式Jupyter交互设计如此使用print或display找不到指定程序环境变量或虚拟环境未激活which jupyter确认路径Notebook保存时报磁盘错误工作目录权限不对chmod对应目录Kernel一直显示connectingipykernel版本不一致pip install ipykernel --upgrade这张表不是为了凑篇幅是我实际维护多个Jupyter服务时沉淀下来的排查路径。大多数问题都不用重装按顺序定位到原因就能解决。最后聊一个跟Jupyter体验很相关的细节千万不要在Notebook运行状态下用pip install去改装正在运行的内核环境特别是源码编译的Python装完有时候模块版本全乱内核直接崩。我一般的做法是先用pip把包装到同一个虚拟环境再回到Notebook页面重启kernel让新的依赖正常加载。CentOS 7的老机器如果内存不大Notebook里也别开太多tab后端kernel的僵尸进程最好定期清一清不然内存会被悄悄吃光。这套环境装好之后日常写脚本、跑数据、调接口都很顺手也算给老机器续了一命。