树莓派搭建开发环境_在树莓派上安装编程语言和开发工具-程序员宅基地

技术标签: Docker  工具  树莓派  

本文公众号地址

背景

自从上次心血来潮给树莓派装完系统,一直没想好怎么具体使用它的场景,它就这样默默地躺在抽屉吃灰了一年

再次想起它,是一个周日的下午:收到之前在腾讯云买的云服务器快过期的提醒,一个4核8G内存的ubuntu,平时主要用它作为开发机,在本地电脑性能不够的时候,辅助 调试代码,以及 编译服务 ,还是非常顺滑的

但随后登录控制台,一看续期的价格,同样性能比去年要贵个200多(去年 388,今年 646),横向对比了国内几个云厂商价格也都差不多,索性放弃续期了,想着有没有其他办法整个独立的开发环境呢?

让家里台式机一直跑着是种方法,windows 的 wsl 已经非常完善,完全可以当 linux 开发机用了

不过目前自己要跑的服务,也用不上台式机的性能,还有没有更轻量运行的方式呢?

这不就正好,终于可以重新唤醒尘封已久的树莓派咯。虽然4U4G的性能说不上绰绰有余,但就跑几个服务来说还是足够的

本文内容

  • 搭建开发环境(docker、各开发语言、code server)

  • 文件服务器(samba)

  • 监控(prometheus + grafana + node exporter)

  • 远程桌面连接

  • 智能开关

  • 后续展望

系统准备

我的树莓派上安装的是 ubuntu 22,通过 raspberry pi imager(官方刷系统工具)刷入系统并安装,具体的安装可以参考去年写的博客

安装开发环境

笔者比较熟悉的开发模式: docker + 各语言开发环境 + vscode,在树莓派上原样进行安装

docker

安装 docker 的目的主要是能快速启动与主机环境隔离的容器,并进行服务编译。特别是编译 C++ 服务的时候,centos、ubuntu 这类的系统镜像自带的 gcc、glibc 版本往往不足要求,需要升级,但 glibc 的升级稍有操作不慎,又会对系统本身造成影响,所以还是建议在容器中编译相关服务

# 使用阿里源安装 docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh --mirror Aliyun

安装后查看版本:

docker -v
Docker version 24.0.7, build afdd53b

关于在国内拉取容器镜像下载加速方式: 对不同的镜像仓库,如 docker hub 官方镜像、registry.k8s.io(kubernetes 相关服务的镜像仓库,旧域名是 k8s.gcr.io)、quay.io(红帽镜像仓库)等,使用的仓库代理地址各有不同

# 原拉取镜像方式
docker pull mysql:8.0.31
docker pull registry.k8s.io/kube-apiserver:v1.17.3
docker pull quay.io/dexidp/dex:v2.28.1

# 使用镜像仓库代理拉取方式
## docker hub 官方镜像: 设置中科大镜像加速器
## 参考: https://mirrors.ustc.edu.cn/help/dockerhub.html
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
EOF
## 重启docker 后再拉取
docker pull mysql:8.0.31

## registry.k8s.io
docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.17.3

## quay
docker pull quay.mirrors.ustc.edu.cn/dexidp/dex:v2.28.1

各个语言的开发环境

关于各种开发语言如何安装环境,网上教程一大把,过程无外乎是下载和解压安装包、环境变量配置和下载源配置,熟悉了操作也快,但每次重装系统,或者基于一个基础镜像安装开发环境,都需要重新操作一遍还是挺麻烦的

笔者把常用语言和服务的安装脚本整理在 shell-tools 这个仓库了,可以直接一行指令帮我安装,还可以指定需要安装的版本

比如安装 go、java、python 和 nodejs:

# go_version: 指定版本,默认版本在 Makefile.vars.version 中定义
# NET=CN: go 安装包将从国内源加速下载,并在安装后设置 GOPROXY 为 goproxy.cn
NET=CN go_version=1.21.4 make golang

# 将安装 jdk1.8 (默认开发环境 JAVA_HOME)、jdk17(vscode java 插件使用)、maven、gradle
NET=CN make java

# 将安装 conda、python 3.12
NET=CN python3_version=3.12 make python3

# 将安装 nodejs 18.16.1
NET=CN nodejs_version=v18.16.1 make nodejs

升级 gcc、glibc,也可以使用这个脚本

# 升级 gcc 到 12.3.0
NET=CN gcc_version=12.3.0 make gcc

# 升级 glibc 到 2.35
NET=CN glibc_version=2.35 make glibc

# glibc 的默认安装地址为 /usr/local,因此使用前需要设置环境变量,把 /usr/local/lib 放到前面
## 参考: https://unix.stackexchange.com/a/67783
export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/lib

code server

关于 vscode 之前写过常用插件的介绍,远程开发模式下,本地装 vscode,通过 remote ssh 连接到远端服务器,再安装各个开发语言的插件,体验还是很丝滑的
在这里插入图片描述

架构如上图: 本地运行 vscode 的前端UI框架,后台服务器自动运行 vscode server,负责具体项目和具体开发语言的插件的运行,并提供 debugger、terminal 等功能

更进一步,我们还可以直接在远端服务器安装 code server,它是 vscode 的在线版,相当于UI服务也在服务器上运行,直接通过浏览器就能打开了

在这里插入图片描述

vscode 和 code server 的对比如上图,区别就是 nodejs(即 UI)也是运行在服务器上的,本机只需打开浏览器即可

code server 在树莓派的安装和配置方式如下:

# 通过 shell-tools 安装 code server 4.19.0
code_server_version=4.19.0 make code-server

# 配置: /opt/modules/code-server-4.18.0-linux-arm64/config.yaml
bind-addr: 0.0.0.0:8080
auth: password
password: codeserver
cert: false

# 启动
nohup /opt/modules/code-server-4.19.0-linux-arm64/bin/code-server --config /opt/modules/code-server-4.19.0-linux-arm64/config.yaml > /dev/null 2>&1 &

之后打开 http://树莓派内网ip:8080 就能开始愉快地享受网页版 vscode 了

在这里插入图片描述

扩展: 如果你想把 code server 提供给小伙伴们一起使用,配置就比较麻烦了,需要加一层 oauth proxy 或其他代理,以支持多用户登录。 jupyterhub 也是一种选择,后续有机会可以写写具体怎么做

文件服务器

除了用于开发,树莓派作为常驻 linux 主机,还可以安装 samba 并作为文件服务器,视频、音乐等媒体统一放到一块硬盘上,作为本地的媒体库

samba

samba 服务对应的 SMB(Server Message Block) 是一种在局域网中共享文件的协议,直接说下它在linux系统的安装方法

# 安装 samba,并添加 samba 的访问用户(注意和系统用户不同)
apt -y install samba samba-common-bin

# 添加用于登录 samba 的用户: pi, 并设置密码
smbpasswd -a pi

# 激活用户
smbpasswd -e pi

安装后,在 /etc/samba/smb.conf 中配置开放访问的目录


# vim /etc/samba/smb.conf

[music]
path = /data/music
writeable=Yes
valid users = pi
create mask=0777
directory mask=0777
public=yes
browseable=yes

挂载机械硬盘

在尝试把之前买的机械硬盘(作为媒体数据盘)挂载到树莓派的时候,遇上了一点小问题: 硬盘格式已经是 NTFS 并且放了一些数据了,但linux 系统无法直接读取,需要安装 ntfs-3g 驱动才行

apt -y install ntfs-3g

并在 /etc/fstab 中设置开机自动挂盘,参考

/dev/sdb1       /data/music   ntfs-3g defaults,nofail,uid=1000,gid=1000,umask=0007,x-systemd.device-timeout=5         0       0

远程桌面

对 linux 系统来说,平时开发写写代码敲敲指令,是不太需要访问桌面的。不过有时想体验 linux 版的应用(QQ),还是可以装个远程桌面来体验一下

常见的远程桌面协议是 xrdp 和 vnc,这里我们通过 xrdp 来配置:

# 安装 xrdp
apt -y install xrdp

# 安装 lxde cinnamon 桌面
apt -y install lxde cinnamon-desktop-environment

# xsession 在用户登录桌面系统后被执行,可用于定制化桌面
# 参考: https://unix.stackexchange.com/a/47426
# 使用 cinnamon 作为桌面
echo cinnamon > ~/.xsession

## 修改 /etc/xrdp/startwm.sh 并在 "fi" 和 “test -x” 中间加3行
unset DBUS_SESSION_BUS_ADDRESS
unset XDG_RUNTIME_DIR
startlxde

# 启动 xrdp
systemctl start xrdp
# 或: /etc/init.d/xrdp restart

# 开机自启动
systemctl enable xrdp

xrdp 的端口 3389 可以在 /etc/xrdp/xrdp.ini 配置中查看和修改

然后通过 microsoft remote desktop 连接:

在这里插入图片描述

非常简洁的桌面

然后我们可以安装新版适配了 linux 的 QQ,从官网下载

# 下载
wget https://dldir1.qq.com/qqfile/qq/QQNT/2355235c/linuxqq_3.1.1-11223_arm64.deb

# 安装
dpkg -i linuxqq_3.1.1-11223_arm64.deb

监控

到这一步,我们给树莓派装的开发环境算是基本弄好了,可以愉快地在上面构建镜像、运行服务,不过摸着那微微发烫的 cpu,担心也随之而来: 是不是有个好看的面板,能直接看到当前树莓派的状态,做个监控更好呢?

那就话不多说,开始整看板吧

获取树莓派的性能指标

先来看看命令行获取树莓派 cpu 的温度的方式:

参考-使用 vcgencmd 指令查看 Raspberry Pi 的 CPU 溫度、運行速度與電壓等資訊

vcgencmd measure_temp | grep  -o -E '[[:digit:]].*'

在这里插入图片描述

vcgencmd 指令是基于树莓派的内核 firmware 自带的指令,能拿到关于系统资源和硬件状态相关信息,如时钟频率、电压、内存等

但通过指令获取参数的方式,采集起来需要额外写脚本,相比 exporter 的方式来说还是不太方便,那么有没有原生的 exporter 可以直接拿到温度数据呢?

node exporter

前面说的系统指令只是粗略看看 cpu 的指标,要想持续监控,还得通过 prometheus 采集、exporter 提供系统指标的机制,把相关指标提前暴露出来

node exporter 是提供系统相关监控指标的服务,在树莓派上部署它的 arm 版本后,可通过 node_thermal_zone_temp 指标获取温度,数据来源是系统文件 /sys/class/thermal/thermal_zone0/temp 即由系统直接提供的 cpu 温度数据

部署 prometheus、node exporter 和 grafana

继续使用 shell-tools 工具一键安装

# 安装 prometheus 和 node exporter
prometheus_version=2.45.0 node_exporter_version=1.6.1 NET=CN make prometheus

# 安装 grafana
grafana_version=10.2.0 NET=CN make grafana

# 启动
/opt/modules/prometheus/prometheus --web.enable-lifecycle --config.file=/opt/modules/prometheus/prometheus.yml --web.listen-address=:3001

/opt/modules/grafana/bin/grafana-server --homepath /opt/modules/grafana --config /opt/modules/grafana/conf/custom.ini

/opt/modules/node_exporter/node_exporter --web.listen-address=":9100"

安装后,在 prometheus 配置文件中添加 node exporter 的本地地址即可开始采集指标

# vim /opt/modules/prometheus/prometheus.yml

scrape_configs:
  - job_name: "node_exporter"
    static_configs:
      - targets: ["localhost:9100"] # node exporter 地址

prometheus 对接 grafana

采集到指标后,关键的一步就是用“酷炫”的grafana看板展示出来,让我们能及时看到系统状态

node exporter 的官方的看板是 node exporter full,分类非常详细,导入看板的 json 文件,并添加 prometheus 数据源(localhost:3001)即可

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

开机服务自动启动

前面我们给树莓派已经安装了一系列服务,那么有时候树莓派要重启,我们会想让这些服务也在系统重启后自动启动。docker 这种通过 systemctl 管理的服务,直接执行 systemctl enable docker 就可以了,手动安装的 code server 、prometheus,应该怎么配置呢?

方法也有很多种,常见的有: rc.local、init.d、crontab @reboot 等方法,它们执行的时机各有不同

参考-在树莓派上设置应用程序开机启动的五种方法

什么时候触发执行

linux 系统启动后,/sbin/init 脚本会进行一众系统服务的初始化,顺序我们可以通过 systemd-analyze plot > startup_order.svg 导出,一些自动启动的脚本启动顺序如下:

/etc/init.d: 最先初始化的一批系统服务

rc.local: network 即网络服务启动之后

crontab @reboot: network 启动之前

为什么要特别提到启动顺序,因为有的服务依赖网络相关的基础服务(如网卡初始化),如果通过 /etc/init.d 或是 crontab @reboot 很可能启动失败。相对比,rc.local 的启动顺序较后,可以保证在系统基础服务启动后开始。另外从配置方式来看,systemctl 和 /etc/init.d 都需要基于一定的格式规范,如服务名、依赖哪些服务等,rc.local 则直接写入服务的启动指令即可

下面我们来看看 rc.local 如何配置

rc.local 添加服务启动指令

root 用户下编辑 /etc/rc.local 文件,添加服务的启动指令

# vim /etc/rc.local
#!/bin/bash
# 启动 prometheus
nohup /opt/modules/prometheus/prometheus --web.enable-lifecycle --config.file=/opt/modules/prometheus/prometheus.yml --web.listen-address=:3001 > /dev/null 2>&1 &

# 启动 grafana
nohup /opt/modules/grafana/bin/grafana-server --homepath /opt/modules/grafana --config /opt/modules/grafana/conf/custom.ini > /dev/null 2>&1 &

# 启动 node exporter
nohup /opt/modules/node_exporter/node_exporter --web.listen-address=":9100" > /dev/null 2>&1 &

之后通过 chmod +x /etc/rc.local 添加可执行文件,重启树莓派再次登录,可以看到相关服务已经运行起来了

另一个注意点是 rc.local 中的指令是串行执行,前面的指令报错,后面的也不会执行,所以也建议通过 nohup 即后台方式启动服务

智能插座

毕竟性能有限,随着我们在树莓派上部署的服务越来越多,也难免会遇到资源用尽,直接卡住无法连接的情况,除了重启没有别的恢复办法

好几次在外面远程连接家里树莓派,跑了几个比较吃资源的服务卡住之后,又没法重启,真的是很无奈,索性搞了个小米智能插座,感受了一波物联网带来实际的便利

在这里插入图片描述

在这里插入图片描述

后续展望

经过了一个多月的折腾,我的树莓派终于可以作为开发服务器长期跑起来了。相比开头说的云服务器,性能方面稍弱,但也带来可以对接本地数据、可随时在手机端重启等好处

之后还能在上面跑什么服务,或者还能和现实世界有什么交互呢?我也还没有特别想好,就粗略地列一列零散的点子吧,看看以后有没有时间继续折腾一下

nas: 我是真没想到竟然真有人去把树莓派当作 nas,参考,数据传输速度上的瓶颈应该还是挺明显的,当作小型文件服务器才比较现实

本地文档库+媒体库: 归档自己所有的音乐、相册、视频、电子书等

传感器: 搞个空气质量检测器,参考

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xiaoliizi/article/details/134751135

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签