从一块性能尚可的Linux小主机,到一台随拿随用的远程开发机,树莓派在折腾圈里的定位一直很特别。哪怕已经进入了嵌入式开发和云主机普及的今天,树莓派4B乃至早期型号,依然是很多桌面端无法替代的实验环境——戴上GPIO、串口、继电器、传感器,它就成了一台可以随时折腾的实体硬件平台。我最早接触树莓派远程开发,是从一次次U盘拷代码开始的:在电脑上写完Python脚本,用scp传到树莓派,然后SSH进去手动执行,改一行重新传一行。时间一长,效率低得让人暴躁,于是才认认真真把VSCode的Remote-SSH整套玩法吃透。这篇东西不是官方文档复述,而是我从零开始、踩过不少坑之后的完整实操记录。
核心思路一句话:让VSCode在本地只充当“编辑器外壳”,真正跑代码、装环境、存文件的位置全在树莓派上,你本地敲代码,按下Ctrl+S保存,远程立刻生效,终端、调试器、变量监视器全部走SSH通道。这套模式特别适合:
- 树莓派无屏幕、纯命令行使用的场景(头less模式);
- 频繁切换局域网或想省去来回传文件的人;
- 需要直接在树莓派上调试GPIO、摄像头、ROS等设备的开发者;
- 手头只有一台Win/Mac笔记本,但想用Linux环境做实验的业余选手或毕设党。
1. 为什么我劝你别再“本地编辑 + U盘/SFTP上传”了
先聊聊远程开发最原始的样子。很多初学者(包括当年的我)习惯把树莓派当成一个“小电脑”:在笔记本上写代码,写完后通过U盘、网盘或者SMB共享文件夹把文件同步到树莓派上,再通过终端执行。这套流程表面看没什么问题,但一旦项目变大、调试频繁,你会立刻感受到几个明显的痛点:
第一个痛点是文件来回同步的挫败感。哪怕用脚本自动scp,也免不了每次改动后都要等几秒钟。代码少的时候无所谓,但当你在改一个几千行的项目、每几十秒就要调整一次参数时,传播延迟会直接打乱你的调试节奏。
第二个痛点是调试能力几乎为零。树莓派上跑的是Linux环境,但你在Windows/Mac桌面上装IDE,很难让调试器直接和树莓派里的Python解释器或GDB建立起稳定连接。绝大多数人最后只能print大法,打印日志-执行-看输出-改代码-再执行,循环往复。
第三个痛点很隐蔽:依赖环境不一致。你本地的包版本、系统库和树莓派上不完全一样。很多代码在本地跑得好好的,一上树莓派就报“No module named xxx”或者“GLIBC版本不兼容”。在本地折腾半天,结果还是要到树莓派上重新装。
VSCode Remote-SSH解决的正是这三个问题。它的原理并不玄乎:VSCode在本地跑一个客户端界面,通过SSH协议在远程树莓派上启动一个轻量的服务端组件(VSCode Server),本地编辑器里的文件树、搜索、语法高亮、终端全部走SSH隧道与远端交互。你在VSCode里打开的每个文件,其实都是远端树莓派上的真实文件;你创建的虚拟环境,直接建立在树莓派的文件系统里;你按F5启动调试,远端解释器在树莓派上跑,调试信息再回传到本地界面。一句话,编辑器和运行时环境彻底解耦。
这套模式和“本地远程插件”有着本质区别。很多编辑器通过FTP/SFTP挂载远程目录,本质还是“把远端的文件拉下来编辑,保存时再上传”,上传后还得手动去服务器执行,且语法提示用的是本地解释器,跟远程环境完全是两套东西。Remote-SSH是把“整个开发环境”搬到远端,本地只剩一个渲染层。你按F12跳转定义,依赖的是树莓派上翻出来的代码;你安装扩展,默认装的也是远端Linux版本;你打开Python交互式窗口,跑的也是远程虚拟环境的解释器。
所以如果你要拿树莓派做深度学习推理、ROS2机器人控制、仪表盘数据采集这类依赖真实硬件环境的开发,Remote-SSH几乎是体验最接近“直插显示器”的开发方式,而且支持Windows、macOS和Linux客户端,门槛低,不用额外买屏幕和键鼠。
2. 开始前的准备:树莓派系统、SSH开启与局域网IP那些事
这套方案的前提是树莓派已经能通过SSH访问。很多人卡在这里,尤其是刚拿到树莓派4B、完全没有显示器的情况下。我用的系统是Raspberry Pi OS Lite(无桌面版),安装过程不需要连接显示器,通过SD卡烧录系统后做两件最基础的事:开启SSH服务、配置好网络。
2.1 无屏幕烧录系统并开启SSH
用Raspberry Pi Imager把系统镜像烧到SD卡后,不要急着拔卡。烧录完成后SD卡里会出现一个boot分区(Windows下显示为可访问的盘符)。在boot分区里新建一个空文件,命名为ssh,不要带任何扩展名。这个空文件的作用是告诉树莓派在首次启动时自动开启SSH服务,它只在系统启动时检查一次,不会留下任何配置残留。
如果你插网线,这一步就已经完成了。连上电源后,树莓派会自动从路由器获取IP地址。如果你想用Wi-Fi,还需要在boot分区里再新建一个wpa_supplicant.conf文件,里面填入Wi-Fi信息。注意树莓派官方系统的wpa_supplicant配置有固定的格式:
country=CN ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="你的Wi-Fi名" psk="你的Wi-Fi密码" key_mgmt=WPA-PSK }很多新玩家会在这个文件的编码格式上出问题。务必用记事本另存为时选择“UTF-8编码”,不要用Windows默认的ANSI,否则Wi-Fi密码里出现中文或特殊字符时,树莓派会一直连不上网。country=CN这行可以填你所在国家/地区的代码,影响到5GHz Wi-Fi的信道选择,在国内填CN就对了。
2.2 查找树莓派IP的几种姿势
拿到IP是连不上SSH的常见瓶颈。最靠谱的方式是登录路由器后台看DHCP客户端列表,树莓派的主机名默认是raspberrypi,一眼就能找出来。如果你不想每次进路由器后台,也可以直接在电脑上扫一下局域网:
- Windows下用Advanced IP Scanner扫整个网段;
- macOS/Linux下用
nmap -sn 192.168.1.0/24(把网段换成你自己的)扫描存活主机。
不过我还是强烈建议,第一次能SSH登录后就立刻在树莓派里固定IP,免得以后连IP都找不到了。固定IP有两个层面可以操作:一是在路由器管理界面做DHCP静态绑定,把树莓派的MAC地址绑定到一个固定IP上;二是在树莓派系统里直接改/etc/dhcpcd.conf文件,比如:
interface eth0 static ip_address=192.168.1.200/24 static routers=192.168.1.1 static domain_name_servers=192.168.1.1 223.5.5.5这里domain_name_servers我填了两个,一个是路由器,一个是国内公共DNS。别小看DNS配置,后面你在树莓派上apt update、pip install的时候,DNS解析快不快直接影响体验。
2.3 初次SSH登录与基础环境准备
Windows用户建议直接用系统自带的OpenSSH客户端。如果你使用的是很老的Windows 7/8,那需要额外安装一个SSH工具才能在命令行里连树莓派,但官方推荐把系统升级到Win10或Win11再折腾,毕竟VSCode新版也不再支持Win7了。
打开终端,输入:
ssh pi@192.168.1.200默认用户名是pi,初始密码是raspberry。首次登录会提示你确认主机指纹,输入yes回车。登录后立即执行:
sudo apt update && sudo apt upgrade -y这一步不是可选项。树莓派官方系统里很多包的版本比较老,VSCode Server在远端下载时会依赖较新的glibc和libstdc++,系统太旧会导致VSCode连接后启动服务器失败。我在树莓派3B上就遇到过这种情况,顺手把系统升到最新的Bookworm版本后问题消失。
3. VSCode Remote-SSH插件的完整接入流程
系统准备就绪后,接下来进入正题:用VSCode连上树莓派。
3.1 安装Remote-SSH扩展
在VSCode扩展市场搜索Remote - SSH,扩展ID是ms-vscode-remote.remote-ssh,作者是Microsoft。安装它即可。这个扩展会同时安装三个相关组件:Remote-SSH本身、Remote-SSH:Editing Configuration Files,以及Remote Explorer。它们的作用分别是:建立连接、编辑SSH配置文件、管理所有远程主机。安装完成后,VSCode左侧活动栏会出现一个“远程资源管理器”图标,底部状态栏也会显示当前的远程连接状态。
注意:安装完扩展后,如果左侧没出现远程资源管理器图标,点一下活动栏的“...”,把它勾选出来即可。VSCode的界面布局偶尔会因为旧版本残留配置导致某些面板隐藏。
3.2 配置SSH Host
点击远程资源管理器图标,在弹出的下拉菜单里选择“SSH Targets”,点击旁边的齿轮图标(用于配置SSH主机),VSCode会自动帮你打开用户目录下的SSH配置文件。Windows下路径一般是C:\Users\你的用户名\.ssh\config,macOS/Linux下是~/.ssh/config。如果没有这个文件,VSCode会自动创建。
往配置文件里写这样的内容:
Host raspberrypi HostName 192.168.1.200 User pi Port 22说明一下这四行的含义:
Host raspberrypi:显示在VSCode主机列表里的名字,可以随便起,相当于一个别名;HostName:真实连接的IP或域名;User:登录用户名;Port:SSH端口,默认22。如果你出于安全原因改了SSH端口,这里对应修改即可。
写完保存,刷新一下远程资源管理器面板,就能看到名为raspberrypi的主机出现在列表中。
3.3 发起第一次连接
点击主机右侧的“在当前窗口连接”图标,VSCode会弹出一个新窗口开始连接。首次连接时,VSCode会提示你选择的远程服务器的平台类型,选择Linux,VSCode Server会自动在树莓派上安装最新版本的服务端组件。这个过程根据网络情况需要1-3分钟不等。
连接成功后,最直观的变化是VSCode窗口左下角的绿色图标会变成“SSH: raspberrypi”,下方的终端也自动变成了树莓派上的bash。在这个状态下,你用快捷键Ctrl+``调出来的终端,实际跑在树莓派上,在里面执行ls、pwd`这些命令,操作的是远端文件系统。
一个容易踩的坑:连接成功后VSCode会自动在工作区里打开一个“远程窗口”,此时把本地文件夹拖进去是不行的。需要在“文件-打开文件夹”里输入远程路径,比如
/home/pi/myproject,VSCode会在远端浏览目录结构。如果你直接把本地路径拖进去,VSCode会拒绝并提示“无法在远程会话中打开本地文件夹”。
3.4 远程工作区的文件操作与体验
连接建立后,VSCode的“文件树”显示的就是树莓派上的文件。你可以在远端任意位置创建、重命名、删除目录和文件。每次保存(Ctrl+S/Command+S)都是直接写远程磁盘,零延迟感(局域网内几乎无感知)。同时,VSCode内置的“源代码管理”功能在远程环境下也完全可用,直接对远端的Git仓库进行提交、推送等操作,不需要在树莓派上单独安装什么特殊插件。
我个人的经验是:最好在树莓派上建立一套清晰的目录结构,比如~/projects下按项目分子目录,别把所有文件堆在home根目录下。远程开发最大的爽点在于,你本地电脑可以随便重装系统、换硬盘,但项目代码和依赖环境全部留在树莓派上,随时打开VSCode就能接着干。
4. 连接后的关键调试:免密登录、扩展管理与性能优化
完成了基础连接,等于拿到了钥匙,但还差一些顺手好用的“润滑剂”,让整条链路稳定流畅。
4.1 配置SSH免密登录,消灭密码输入
每次连接都输密码不是致命问题,但很影响心情。更关键的是,如果Pipeline或自动脚本要使用SSH,那免密登录就成了硬需求。配置免密并不复杂,用SSH密钥对实现:
在本地电脑上执行(如果你还没生成过密钥):
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"一路回车即可,会在~/.ssh下生成id_rsa(私钥)和id_rsa.pub(公钥)。私钥千万不能泄露,公钥可以随便分发。然后把公钥推送到树莓派上:
ssh-copy-id pi@192.168.1.200Windows下的OpenSSH通常也自带ssh-copy-id,如果没有,你可以手动执行:
type $env:USERPROFILE\.ssh\id_rsa.pub | ssh pi@192.168.1.200 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"原理就是把你的公钥追加到树莓派上pi用户家目录的.ssh/authorized_keys文件里。之后再次用VSCode连接,不再要求输入密码,直接进入远程窗口。
补充一个小细节:如果你在Windows下用VSCode连接时一直报“Permissions for the key are too open”之类的错误,说明私钥文件权限太宽松了。把
id_rsa文件的“属性-安全”里除了当前用户之外的授权全部删掉即可,只保留“SYSTEM”和你的用户名。
4.2 扩展的管理逻辑:本地与远程环境要分开装
很多人第一次用Remote-SSH时被VSCode的扩展列表搞懵了:明明我在本地装了Python扩展,为什么连接上树莓派后没有生效?这是因为VSCode把扩展分成了两类:一类是UI扩展(只在本地界面运行,比如主题、图标、部分语言语法高亮),另一类是工作区扩展(要在远程环境运行才能提供真实功能,比如Python、Jupyter、C/C++调试器、GitLens等)。当你进入远程会话时,VSCode会默认把所有扩展区分为“在本地安装(当前已安装)”和“在SSH:xxx上安装(远程安装)”。
在远程环境里打开扩展面板,搜索你需要的扩展,点击“在SSH:xxx中安装”即可。以Python开发为例,在远程端安装完Python扩展后,VSCode会自动在树莓派上探测Python解释器路径,你可以通过命令面板(Ctrl+Shift+P)执行“Python:选择解释器”,指定使用树莓派上的某个虚拟环境。
我在树莓派上常用的远程扩展就这几个:Python、Pylance、Remote-SSH本身、GitLens(版本历史可视化)、以及一个中文语言包。别装太多花里胡哨的,树莓派的CPU参数在那里,扩展装多了VSCode Server本身的负载会升高,界面的输入延迟也会变明显。
4.3 在树莓派上创建虚拟环境与安装依赖
既然开发环境完全在树莓派上,建立独立的虚拟环境就成了基本操作。在远程终端里执行:
cd ~/projects python3 -m venv venv source venv/bin/activate pip install --upgrade pip之后所有依赖安装都装入这个虚拟环境。注意树莓派本身ARM架构的pip源速度可能偏慢,建议在~/.pip/pip.conf里配置国内镜像源:
[global] index-url = https://mirrors.aliyun.com/pypi/simple/ trusted-host = mirrors.aliyun.com这样安装opencv-python、numpy这类大包时会快很多。同时,树莓派的Linux环境通常是32位或64位的,务必确认ARM架构下pip下载的wheel包兼容。目前Raspberry Pi OS Lite默认是64位系统,绝大多数主流Python包都有ARM64的wheel,直接pip install一般都能装上。
4.4 树莓派性能调优:让远程开发更顺滑
树莓派4B虽然比前代强不少,但作为开发机跑VSCode Server,轻量编译和Python调试没问题,重负载的C++全量编译还是会卡。我建议做三件事:
- 给树莓派加上散热片和小风扇。这听起来和“远程开发”无关,但树莓派一旦过热降频,你在VSCode里敲代码都会觉得有延迟——别问我是怎么知道的。
- 在
/boot/firmware/config.txt里(旧版本是/boot/config.txt),把GPU显存调低到16MB,因为远程开发基本不需要GPU显示输出:
gpu_mem=16- 关闭桌面环境。如果你用的是Raspberry Pi OS Lite,这一步可以忽略;如果是桌面版,可以通过
sudo systemctl set-default multi-user.target把默认启动从图形界面切到命令行,大幅释放内存。
树莓派的内存对远程开发的体验影响很大。4B的2GB版本勉强够用,4GB和8GB版本体验明显更舒服。如果你只是跑跑Python、Node.js,2GB也够;但如果要跑Jupyter Notebook、中大型C++工程,建议直接上8GB版本。
5. 远程开发中最容易翻车的几个问题与完整修复过程
这部分写我在实际使用中遇到的几个最折磨人的问题,以及排查思路。很多坑不看日志根本无从下手。
5.1 报错“此扩展在此工作区中被禁用”到底怎么回事
关键词里提到这个报错,基本见一次懵一次。这个提示的全貌可能是:此扩展在此工作区中被禁用,因为其被定义为在远程扩展主机中运行。请在 'ssh: xxx' 中重新加载。
排查链路如下:先看这个扩展安装在哪一侧。如果它已经被安装到了本地,但被定义为“远程扩展”,VSCode就会在远程会话里禁用它。解决方法是切换到远程会话后,在扩展面板里看“已禁用”列表,找到它,点“在SSH:xxx中安装/启用”。实际操作中,我遇到过的是某个本地扩展自动更新后,把平台兼容范围缩窄了,导致远程不可用。
一句话总结:进入远程会话后,扩展安装目标必须选“SSH:xxx”,不要选“本地”。VSCode的扩展机制设计得比较严格,本地和远程互不干扰,才能保证不同环境之间的扩展版本不打架。
5.2 Ubuntu树莓派SSH无法连接,卡在登录界面
有些玩家树莓派刷的是Ubuntu Server而非官方Raspberry Pi OS。这种情况下SSH连不上,十有八九是系统里默认没装openssh-server(对,Ubuntu Server有些架构版本默认不装,或者装完没启动)。排查步骤:
在树莓派上用显示器键盘(或者接串口)进入系统,执行:
sudo systemctl status sshd sudo systemctl enable --now ssh如果提示Unit ssh.service could not be found,先安装:
sudo apt install openssh-server另一个常见原因是Ubuntu默认开启了防火墙ufw,但没放行22端口:
sudo ufw allow 22/tcp sudo ufw enable做完后再从电脑端测试ssh 用户名@IP。很多教程把Ubuntu系统的SSH问题归结为“网络不通”,实际上绝大部分是服务没起来或防火墙拦截。
5.3 VSCode连接时卡在“Downloading VSCode Server”或“Installing”
这个坑在树莓派上尤其容易出现,因为VSCode Server的下载节点在国外,某些地区网络环境下载速度很慢甚至直接超时。解决思路有两个:一是给树莓派配代理(前提是你有可信的代理设施,且不能说太多);二是如果你在局域网里,可以从本地下好VSCode Server压缩包后手动传到树莓派,然后解压到目标目录。
VSCode Server的安装目录在~/.vscode-server下,它的归档名和版本号与VSCode客户端严格对应。如果你卡下载,可以在树莓派上执行:
tail -f ~/.vscode-server/.vscode-server-*查看服务端的日志,看看它卡在哪一步。这个日志文件会告诉你完整的安装路径和版本号,方便你手动干预。考虑到具体情况,我这里不展开手动安装的每一步,如果你真的遇到这个困境,用下面的通用手法:先在本地浏览器下载对应的vscode-server-linux-arm64.tar.gz,再scp到树莓派,解压到~/.vscode-server/bin/<commit-id>/。你的VSCode版本每个都有一个commit ID,在“帮助-关于”里能看到它。
5.4 Windows下SSH密钥和VSCode路径中的中文字符
Windows用户如果一个SSH接连崩溃,先查路径是否含中文或空格。VSCode Remote-SSH在Windows下如果用户目录含中文,偶发会出现解析配置文件的错误。规避方法:在C:\Users\你的用户名\.ssh\config里写绝对路径时,尽量不引用中文路径;或者为.ssh目录设置一个更保险的权限。另外,如果你在Windows下用了多个SSH密钥,需要在config里明确指定IdentityFile的完整路径,否则VSCode可能用错了密钥导致认证失败。
5.5 连接保持不稳定:断连重连地狱
远程开发最烦的就是代码写一半,VSCode突然“Remote SSH 连接已关闭”。排查方向有两个:一是树莓派侧Wi-Fi不稳,建议优先使用网线连接,规避无线网卡的休眠和丢包;二是物理链路没问题,则说明SSH长连接被服务端或网络设备“无情”掐断,需要在SSH配置里加上保活参数:
Host raspberrypi HostName 192.168.1.200 User pi ServerAliveInterval 60 ServerAliveCountMax 3这两行的意思是:每60秒客户端自动发送一次保活包,如果连续3次没有收到响应,才判定连接断开。加上之后,我在树莓派上开一个长时间的任务,笔记本合盖再打开,VSCode十有八九能自动恢复连接,不需要重连。
如果你还想更保险,可以在树莓派侧的/etc/ssh/sshd_config里加:
ClientAliveInterval 60 ClientAliveCountMax 3这样服务端也会主动探测客户端是否存活。两边都保活,断连概率大幅下降。
5.6 权限与GPIO:远程开发瓶颈常在权限不在代码
最后提醒一个树莓派人容易忽略的点:如果你在远程开发GPIO控制程序,VSCode远程终端里的用户如果不在gpio用户组,运行import RPi.GPIO或者GPIO.setmode()时会直接报权限错误。解决办法:
sudo usermod -aG gpio pi然后重新登录(exit再连一次)。同理,访问/dev/i2c-1、/dev/spidev0.0这类设备节点,也需要对应的用户组权限。远程开发时你会觉得“代码明明没错,怎么就权限不够了”,其实就是这些零碎的系统组权限没配好。
6. 进阶玩法:端口转发文件同步多设备协作
当基础连接稳定后,思路就可以打开了。Remote-SSH能做的事情远比“改代码跑代码”多得多。
6.1 端口转发:把树莓派服务映射到本地浏览器
我最常用的进阶功能是SSH端口转发。树莓派上跑Flask、FastAPI、Jupyter Notebook这类Web服务时,服务监听在树莓派的某个端口,从本地浏览器直接访问http://树莓派IP:端口也能访问,但有些服务的回调地址会写死为127.0.0.1,导致你本地打不开。
此时可以在VSCode的“端口”面板里添加转发规则,把树莓派的5000端口转发到本地localhost:5000。这样浏览器地址栏输入http://localhost:5000就能直接访问树莓派上的Web服务,就像它在本地运行一样。这个功能底层还是SSH的-L参数,但VSCode把它做成了图形化点击,真香。
6.2 多树莓派主机管理
如果你手头不止一块树莓派(比如一块4B当开发机、一块Zero 2W当GPIO控制节点),在~/.ssh/config里配置多个Host就行了:
Host rpi-dev HostName 192.168.1.200 User pi Host rpi-zero HostName 192.168.1.201 User pi远程资源管理器里会列出两个主机,点击切换,VSCode会为每个主机维护独立的“远程窗口”,互不干扰。本地机器只是一个控制台,多块板卡之间的切换成本几乎为零。
6.3 在树莓派上跑服务端构建任务
树莓派现有的性能跑小型前端项目也是没问题的。如果你在树莓派上装Node.js 18+,npm run dev这种开发服务器可以一直挂着,VSCode里改代码,Webpack/Vite自动重编译,浏览器刷新页面就能看到变化。对于依赖真机的项目,比如树莓派接摄像头做图像识别,这种“改代码-立即跑-调参-再跑”的循环特别快。远程开发把一个频繁的“编辑-同步-执行-看日志”循环压缩成了“编辑-执行-看输出”一步到位。
6.4 多设备协作与个人工作流
顺带说说多设备协作。因为开发环境完全在树莓派上,你可以在办公室用Windows台式机连一次,回家用MacBook再连一次,两边的VSCode扩展、设置、打开的文件路径完全一致。如果配合Git管理代码,你甚至都不用担心“上次写到哪了”的问题,因为代码和依赖都在远端,换了设备等于换了个显示屏幕而已。
我个人现在的工作流是:树莓派4B(8GB版)固定放在弱电箱旁边,用网线接入路由器,上面挂着SSH、Git、Python虚拟环境和一些小服务。无论我人在哪里(只要网络能到),都能用VSCode继续调试代码。对于需要长期运行的脚本,比如数据采集、定时任务,直接用systemd或tmux在树莓派上跑着,VSCode只是偶尔打开改改配置、看看日志。这套组合的稳定性和自由度,比在云服务器上开发多了硬件交互的乐趣。
最后分享一点我在远程开发过程中的心得:第一次连上时,会感觉VSCode有点卡,因为服务端正在初始化;这不代表配置失败,稍等片刻后就会流畅起来。如果你发现某个扩展在远程不生效,第一反应别去本地扩展市场里疯狂重装,而是确认当前窗口左下角是否显示“SSH:xxx”——只要不是这个状态,说明你还在本地环境里折腾。树莓派远程开发的门槛本来就不高,真正让人放弃的,往往不是技术难题,而是那些细节处的理解偏差。把SSH配置、密钥免密、扩展安装目标、保活参数这几件事理顺,剩下的就只剩下享受“本地编辑、远端运行”的丝滑体验了。