资讯动态

服务器远程运行Jupyter Notebook:虚拟环境配置与SSH端口转发实战

发布时间:2026/10/24 7:14:15 来源:尧图企业网站定制
在实验室里经常会有人拎着笔记本过来问服务器上怎么开 Jupyter Notebook最好还能直接用我自己配好的那个虚拟环境。这个问题听起来简单真正上手才发现至少有四道坎远程连接要通、Jupyter 要在没显示屏的服务器上跑起来、本地浏览器要能正常打开页面、最后虚拟环境还得能被 Notebook 识别不然一新建文件又回到默认的 base前几分钟全白折腾。我见过不少人在前两步就卡住了更别说最后一步——环境装了一堆打开 Notebook 却死活找不到。这篇文章我就把整套流程完整捋一遍。假设你已经在某个实验室的服务器上有账号服务器是 Linux 系统你平时主要通过 SSH 登录。看完之后你不仅能跑起 Jupyter还能把自定义环境加到内核列表里彻底告别嗯怎么还是 base的尴尬。1. 先看运行链路浏览器只是个遥控器1.1 Jupyter 到底跑在哪里很多刚接触服务器 Jupyter 的人会误以为 Notebook 运行在自己电脑上。实际上你在本地浏览器里看到的网页只是前端界面真正执行 Python 代码的是服务器上的 kernel 进程。也就是说所有的 import、计算、模型训练都发生在服务器上你的笔记本只负责展示页面、收集输入和显示结果。拆开看这条链路是这样的服务器上启动 Jupyter Server监听某个端口默认 8888。本地浏览器通过 HTTP 访问服务器的端口Jupyter 把 Notebook 页面推送到浏览器。你在单元格里按 CtrlEnter代码被发送回服务器交给 kernel 执行。执行结果包括 print、图片、表格再通过网络返回浏览器显示。理解这一点非常关键因为你之后遇到的所有问题比如连不上打开慢内核断连本质上都在上面这条链路的不同环节出了问题。只要定位到是哪一环断掉排查思路就清晰了。1.2 动手前必须确认的三件事我建议在安装任何东西之前先检查三件事避免后面白忙活服务器 IP 或主机名是否可用。用ssh usernameserver_ip能正常登录。你的账号是否有写权限至少在家目录里有空间装包、建环境。Python 是否已安装。一般服务器都会装但版本可能旧一点。再补充一个我踩过的真实小坑有一次某同事让我帮他在服务器上配 Jupyter折腾半天发现他根本连不上服务器最后查出来是 SSH 登录时把端口写错了。如果 SSH 这一步都不通后面所有步骤都无从谈起。所以别急着装软件先确认能连上这个前提。可以用下面命令快速确认 Python 环境which python3 python3 --version如果系统里有多个 Python建议记下路径。等会儿建虚拟环境时要用。2. 创建虚拟环境把依赖隔离在自己的小房间2.1 为什么不能直接装在系统 Python 里实验室服务器通常是多人共用的系统 Python 环境往往已经被折腾得惨不忍睹。A 研究组需要 pytorch 2.xB 研究组还在用 1.xC 同学装了个不知名的包把 numpy 直接升级到不兼容的版本结果大家写代码的时候全都一脸懵。虚拟环境就是为了解决这种一个环境装所有东西导致的混乱。你可以把它理解成合租房里的独立房间公共区域系统 Python保持不变每个房间虚拟环境里的软件随便折腾互不干扰。你只需要在干活的时候进自己的房间干完再出来就行。2.2 使用 conda 创建环境如果你的服务器已经装了 Anaconda 或 Miniconda最简单的方式就是用 conda。Miniconda 更轻量Anaconda 自带很多常用库。没有的话可以用 Miniconda 安装脚本装一个。创建环境conda create -n myenv python3.10这里myenv是环境名python3.10指定解释器版本。conda 的优点是能管理 Python 版本本身比如系统默认 Python 是 3.8但你项目需要 3.10conda 可以直接给你一个独立的 3.10。激活环境conda activate myenv激活后命令行前面会出现(myenv)标记这时候which python指向的就是环境内的解释器了。如果提示conda activate不能用可能需要先跑一次conda init bash然后重新登录 SSH或者重新加载 shell 配置。这个坑很常见尤其在新装的 Miniconda 上。2.3 使用 venv 创建环境如果不想装 Anaconda用系统自带的venv也完全够用。它更轻量但只能基于系统当前的 Python 版本创建环境不能随意切换 Python 大版本。cd ~ python3 -m venv myenv source myenv/bin/activate激活后(myenv)前缀同样会出现。venv 的好处是不依赖额外工具干净利落缺点是如果你需要多个 Python 版本它没法直接解决。两种方式对比对比项condavenvPython 版本切换支持可指定任意版本不支持跟随系统 Python底层库管理可管理部分非 Python 依赖只管理 Python 包安装体积较大Miniconda 也有几百 MB轻量适用场景深度学习、需要不同 Python 版本普通项目、只需要隔离 Python 包我在实验室实际用得最多的还是 conda因为深度学习项目经常需要指定 CUDA 版本配合的 Python 版本venv 做不到这一点。如果只是写脚本做数据分析venv 就够了。3. 在服务器上安装并配置 Jupyter3.1 安装 Jupyter Notebook创建好环境之后先激活环境然后在环境内部安装 Jupyterconda activate myenv pip install jupyter notebook如果你用的是 JupyterLab也可以pip install jupyterlab为什么强调激活后再安装因为这样 Jupyter 相关包会装进当前环境而不是污染 base。后面启动时用当前环境的jupyter命令路径才不会搞混。注意区分一下版本现在 Jupyter Notebook 有 7.x 和旧版 6.x。7.x 基于 Jupyter Server配置项名字和旧版略有差异。如果你看到网上教程写的c.NotebookApp.xxx不生效大概率是因为你在 7.x 上找了旧配置项。后面我再详细说配置差异。安装完成后可以先跑一下jupyter --version确认安装成功并输出版本信息。3.2 生成配置文件Jupyter 启动时会读一个配置文件通常是~/.jupyter/jupyter_notebook_config.py。第一次运行需要手动生成jupyter notebook --generate-config然后编辑这个文件。对于 Jupyter Notebook 7.x主要是这一段c.ServerApp.ip 127.0.0.1 # 只监听本机地址 c.ServerApp.port 8888 # 使用端口 8888 c.ServerApp.open_browser False # 服务器上不自动打开浏览器 c.ServerApp.allow_remote_access True # 允许远程访问配合端口转发如果是旧版 6.x对应的是c.NotebookApp.ip 127.0.0.1 c.NotebookApp.port 8888 c.NotebookApp.open_browser False c.NotebookApp.allow_remote_access True我个人建议新装机器直接用 7.x因为它内部切换到 Jupyter Server 之后扩展机制和稳定性都更现代。旧版配置虽然兼容但迟早要迁。ip设置成127.0.0.1而不是0.0.0.0是为了安全考虑。除非你明确知道自己在做什么否则不要直接把服务暴露到所有网卡上。后续远程访问用 SSH 端口转发就够了没必要监听公网。后面第 4 节我会展开讲。3.3 设置登录密码由于 Jupyter 自带认证机制最好用一个密码保护。旧版 Jupyter 提供命令jupyter notebook password新版同样支持这个命令它会提示你输入并确认密码。执行后密码会被哈希写入~/.jupyter/jupyter_server_config.json以后启动 Notebook 时只需要输入这个密码。为什么不推荐启动时用 token因为每次重启 token 都会变然后你得去日志里找那一长串字符非常麻烦。设一个固定密码一劳永逸。密码设置好之后网页登录只会要求输这个密码不会再弹 token 框。4. 远程访问两种常用方案对比4.1 方案一SSH 端口转发我最推荐这个方案安全也最容易排查。原理很简单你在本地电脑和服务器之间建立一条 SSH 加密通道把服务器上的某个端口映射到本地的一个端口。这样浏览器访问本地端口数据通过 SSH 隧道转发到服务器上的 Jupyter。命令格式ssh -N -f -L 8888:localhost:8888 usernameserver_ip各个参数的含义-N表示不执行远程命令只做转发-f表示后台运行-L 8888:localhost:8888表示把本机的 8888 端口映射到服务器的 8888 端口命令执行完之后在你本地浏览器打开http://localhost:8888就能看到 Jupyter 登录页面了。这个方法的好处是服务器上的 Jupyter 只监听127.0.0.1外部网络根本访问不到它数据在传输过程中也被 SSH 加密。即使所有人共用服务器也不用担心别人在网络上抓到你的密码。如果 SSH 连接容易断开可以加个保活参数ssh -N -f -o ServerAliveInterval60 -L 8888:localhost:8888 usernameserver_ipServerAliveInterval60的意思是每 60 秒发一次心跳包防止长时间没流量被防火墙掐断。我实测下来加了这项之后连续挂一两天都没问题。Windows 用户如果用的是 PowerShell 或者 Windows Terminal直接敲同样的命令即可。如果你用的是 MobaXterm 这类工具它自带隧道配置界面图形化操作也可以。4.2 方案二直接开放端口访问还有一种方式是让 Jupyter 监听0.0.0.0然后浏览器直接访问服务器的 IP 加端口http://服务器IP:8888需要改配置c.ServerApp.ip 0.0.0.0改完之后别忘了检查防火墙。很多服务器的防火墙默认没开 8888 端口需要放行sudo ufw allow 8888某些集群环境还有安全组设置得在管理页面里放行端口。这个方法适合什么场景适合你确定服务器处于可信内网、且你能方便地开放端口的情况。但说实话风险比较大Jupyter 有执行任意命令的能力一旦有人猜到密码或利用漏洞等于直接把服务器控制权交出去。所以我基本只在自己有完全掌控权的机器上用实验室共用服务器我建议大家走 SSH 端口转发。4.3 启动 Jupyter 并在后台运行一切配置好之后启动命令很简单jupyter notebook --no-browser --port8888--no-browser告诉服务器不要尝试打开浏览器毕竟服务器上根本没有图形界面。问题是如果直接在前台运行SSH 窗口一关Jupyter 也就停了。所以要让它一直在后台跑两个办法比较靠谱方法一用 nohupnohup jupyter notebook --no-browser --port8888 ~/jupyter.log 21 这样 Jupyter 在后台跑日志输出到~/jupyter.log以后想看错误就去翻这个文件。方法二用 tmux更灵活tmux new -s jupyter jupyter notebook --no-browser --port8888进入 tmux 后跑 Jupyter按Ctrl-b d退出会话SSH 断开也不影响。下次回来tmux attach -t jupyter就能回到 Jupyter 的会话界面。如果你想关掉 Jupyter在 tmux 里按Ctrl-c即可。我个人现在基本只用 tmux因为除了跑 Jupyter我平时在服务器上跑训练脚本也靠它。如果你完全不想学新工具nohup 也能满足 90% 的需求。另一个小习惯启动后别急着关终端先看日志里是否有报错。正常时日志最后会显示类似http://127.0.0.1:8888/如果这里显示的不是127.0.0.1而是别的地址说明配置里 IP 没有改对。要是启动失败日志里一般会直接告诉你原因十有八九是端口被占了。5. 关键一步让 Jupyter 认得出你的虚拟环境5.1 为什么 Notebook 里还是默认环境很多人在服务器上装好了虚拟环境也激活了环境启动 Jupyter然后新建 Notebook 一看sys.executable指向的还是系统的 Python 路径装了一堆包的环境好像根本没生效。原因在于Jupyter 启动时会根据它自己的运行环境去调用 Python kernel。你虽然在 shell 里激活了myenv但 Jupyter Server 进程本身的 Python 解释器可能还是 base 环境的。更关键的是Notebook 的 kernel 是一个独立进程你在 shell 里 activate 的环境对它没有任何直接影响。就好比你订了酒店房间但酒店前台给你的房卡却是公共区域的卡你得单独告诉 Jupyter现在我要用这个环境的 Python 作为 kernel。5.2 使用 ipykernel 注册环境解决办法是让每个虚拟环境把自己注册成 Jupyter 的一个可选内核。这样启动 Notebook 之后就能在下拉菜单里看到它点一下就能切换。操作分两步第一步在虚拟环境里安装 ipykernelconda activate myenv pip install ipykernel第二步注册内核python -m ipykernel install --user --namemyenv --display-nameMyEnv Python 3.10参数解释--namemyenv是内核的内部名字用来唯一标识。--display-name是你在 Jupyter 网页端下拉菜单里看到的显示名可以随便起建议起得让自己一眼能认出来。--user表示把内核配置安装到当前用户目录通常在~/.local/share/jupyter/kernels/下不需要 root 权限。注册之后刷新 Jupyter 网页。在新建 Notebook 的时候Kernel 菜单里就能看到 MyEnv Python 3.10 了。已打开的 Notebook 也可以在菜单栏Kernel - Change Kernel里切换。注册完可以验证一下新建选这个内核的 Notebook运行import sys print(sys.executable)如果输出的是~/miniconda3/envs/myenv/bin/python或者类似的路径说明环境已经正确穿透到 kernel 里了。这个验证习惯我强烈建议养成每次配完环境都看一眼能省不少事。5.3 多个环境怎么管理如果你经常给不同项目建环境会发现每次都要重复一遍pip install ipykernel和python -m ipykernel install。这个过程可以写成一个简单脚本#!/bin/bash conda activate $1 pip install ipykernel python -m ipykernel install --user --name$1 --display-name$1调用时bash add_kernel.sh myenv就行。有段时间我实验室里帮好几个同学配环境有了这个脚本一套流程 30 秒搞定。还有一个更省事的思路直接装一个nb_conda_kernels包它会在启动 Jupyter 时自动扫描所有的 conda 环境把它们全部列成可选内核。装一次以后建新环境直接出现在列表里不用挨个注册。conda activate base conda install -c conda-forge nb_conda_kernels注意要去 base 环境装然后 Jupyter 启动时它才会自动扫描。缺点是如果环境特别多内核列表会很长选起来有点眼花。我个人的选择是共用服务器上装一个nb_conda_kernels大家都能顺手选环境自己日常用的机器还是手动注册干净可控。6. 常见问题与排查实录6.1 问题速查表下面这些是我实际见过的案例整理成的一份速查表建议先收藏。现象可能原因排查方法浏览器打不开 localhost:8888SSH 隧道没建立成功检查 SSH 命令是否报错用ssh -v看调试输出浏览器显示无法连接服务器端口号不一致确认启动 Jupyter 的端口和转发命令里的端口一致初次访问弹出 token 框尚未设置固定密码执行jupyter notebook password后重启服务Notebook 新建后还是 base 环境kernel 未注册在对应环境执行ipykernel install端口被占用有人或之前实例占用 8888用lsof -i:8888查看进程或换端口启动Jupyter 启动后马上退出配置项写错看日志确认ServerApp和NotebookApp配置与版本匹配服务器重启后 Jupyter 消失没有使用后台守护方式改用 tmux 或 systemd 方式打开 Notebook 一直显示 Connectingipykernel 缺失或内核崩溃在对应环境重装 ipykernel看服务器日志conda activate 无效shell 未初始化执行conda init bash后重新登录6.2 几个真实案例复盘先说端口占用。又一次我的 Jupyter 突然启动报错提示端口被占用。排查过程很简单lsof -i:8888看到是一个残留的旧进程占着直接kill掉再启动就好。大多数端口问题的本质就是这个偶尔也可能是你上次的 nohup 进程还没退出导致的幽灵进程。启动前养成查端口的习惯能少踩不少坑。再说内核连接失败。某个师妹反馈点开 Notebook 之后一直转圈状态是 Connecting。我看了一下她的环境里没装 ipykernel只是在 conda 环境里启动了 jupyter。虽然 Jupyter 进程本身能跑但新建的就是旧内核环境里找不到对应的启动脚本自然就连不上。补装一次 ipykernel 之后就恢复了。这其实就是第 5 节讲的注册问题的变体很多 New User 都会漏掉。最后说一个容易忽略的有些实验室服务器对登录节点有限制要求只有调度节点能跑计算任务。这时候你把 Jupyter 跑在登录节点上重负载任务会拖垮整台机器影响所有同学。这种情况下的正解是申请一段交互式作业在里面启动 Jupyter然后同样用 SSH 端口转发访问。具体命令要看实验室的调度系统但思路是一致的把 Jupyter 放到有资源的节点上而不是长期占着登录节点。遇到这类问题最好先问一下实验室管理员有没有相关约定别自己埋头配。6.3 被低估的安全事项补漏说几个容易被忽略的安全细节不要用 root 账号跑 Jupyter。Jupyter 一旦出问题root 权限意味着整台机器被接管。密码尽量用强密码不要设空密码。有些同学贪方便不设密码结果服务又开着公网这等于把服务器大门敞开。日志文件会记录访问来源和 token不要随意分享给别人。配置里c.ServerApp.token 这种写法强烈不建议尤其在生产或多人共用环境里。这些经验不是书上教的都是我或者同事实际踩过之后总结出来的。有一次某同学图省事直接开了0.0.0.0监听结果日志里出现了大量来自陌生地址的访问尝试吓得我赶紧把服务改成 SSH 转发模式。安全这个东西一次疏忽可能就是整台服务器的灾难。7. 我对这套方案的个人补充建议最后分享一点个人体会。如果你打算在实验室服务器上长期用 Jupyter 工作我建议一上来就别用老式 Notebook 界面直接用 JupyterLab。命令相同配置大同小异但界面更适合同时开多个 Notebook、终端、文件管理效率高不少。启动 JupyterLab 只需要把启动命令改成jupyter lab --no-browser --port8888SSH 端口转发和 kernel 配置不用变直接复用。另外如果你经常需要在本地传代码、看结果可以考虑把 Jupyter 的密码放到~/.jupyter/jupyter_server_config.json里备份一份或者写一个一键启动脚本。我在服务器上一般放一个start_jupyter.sh#!/bin/bash nohup jupyter lab --no-browser --port8888 ~/jupyter.log 21 echo Jupyter started, check ~/jupyter.log以后每次连上服务器只需要bash start_jupyter.sh然后本地跑 SSH 转发两条命令搞定。这套组合我用了一年多中间没出过什么大问题。折腾服务器的过程就是这样——一开始觉得乱等你把链路各个环节都摸清楚了之后再遇到问题基本就是看日志、查端口、对配置三步走的事。希望这篇记录能帮你少绕点弯路。毕竟环境配置这种事永远是第一次最痛苦配好了就一劳永逸。

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

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

免费获取报价 →
↑