Serving a Website on a Raspberry Pi Zero Running Entirely in RAM
Serving a Website on a Raspberry Pi Zero Running Entirely in RAM
在完全运行于内存的树莓派 Zero 上托管网站
My micro site, zero.btxx.org, is being served to the public internet from a Raspberry Pi Zero v1.3 running Alpine Linux. The best part? It’s diskless and running entirely from memory! 我的微型网站 zero.btxx.org 目前正通过一台运行 Alpine Linux 的树莓派 Zero v1.3 向公网提供服务。最棒的部分是什么?它实现了无盘化,完全在内存中运行!
This is even more impressive considering the Pi Zero only has 512MB of total memory, ~40MB of which is tied up running Alpine Linux. But since RAM is so abundant and cheap these days that we can… Oh, right. Anyway, what a time to be alive! If you’re interested in running your own website off a Pi Zero, follow along! 考虑到树莓派 Zero 总共只有 512MB 内存,其中约 40MB 还被 Alpine Linux 占用,这显得尤为令人印象深刻。不过,鉴于如今内存如此充裕且便宜,我们可以……哦,对了。总之,这真是一个伟大的时代!如果你有兴趣在树莓派 Zero 上运行自己的网站,请跟随本文一起操作!
The (Local) Hardware
(本地)硬件需求
Before we start, let’s make a list of all the required hardware items we need. 在开始之前,让我们列出所有需要的硬件清单。
-
Raspberry Pi Zero v1.3
-
512MB+ microSD card (still needed for install and booting into RAM)
-
Waveshare Ethernet HAT (optional, can use OTG adapter instead)
-
Ethernet cable
-
Micro USB power cord / power adapter
-
Cool case (optional)
-
树莓派 Zero v1.3
-
512MB 或以上的 microSD 卡(安装和引导至内存时仍需使用)
-
微雪(Waveshare)以太网扩展板(可选,也可使用 OTG 转接器代替)
-
网线
-
Micro USB 电源线/电源适配器
-
外壳(可选)
Why the 512MB Micro SD Card?
为什么选择 512MB 的 Micro SD 卡?
This will make our image backups much easier (at the end of this post). Since we are limited to a maximum RAM space of 512MB (storage), it makes sense to avoid backing up more than we need. 这将使我们的镜像备份变得更加容易(详见本文末尾)。由于我们的最大内存空间(存储)限制为 512MB,因此避免备份不必要的数据是非常合理的。
Additional hardware that will only be needed temporarily for the initial install of Alpine: 仅在 Alpine 初始安装期间需要临时使用的额外硬件:
-
Monitor
-
HDMI to mini-HDMI adapter
-
Keyboard
-
显示器
-
HDMI 转 mini-HDMI 转接器
-
键盘
The (External) Hardware
(外部)硬件需求
Since I plan to avoid handling the heavy TLS termination directly on the Pi Zero, I’m going to funnel secure traffic through a separate, tiny VPS. I’m currently using TierHive (referral) which has been fantastic so far. They’re still in alpha, but that’s fine for this personal experiment. I’ve selected TierHive based on their low pricing and pre-built HAProxy configuration options. 由于我计划避免直接在树莓派 Zero 上处理繁重的 TLS 终止任务,我打算通过一台独立的微型 VPS 来引导安全流量。我目前使用的是 TierHive(推荐链接),到目前为止体验非常棒。他们仍处于 Alpha 测试阶段,但这对于个人实验来说完全没问题。我选择 TierHive 是因为其低廉的价格和预置的 HAProxy 配置选项。
VPS Stats
VPS 配置
-
Alpine Linux
-
128 MB RAM
-
1 GB Storage (NVMe)
-
1 vCPU
-
~$4/year
-
Alpine Linux
-
128 MB 内存
-
1 GB 存储 (NVMe)
-
1 vCPU
-
约 4 美元/年
But don’t worry about this right now. We’ll get into those details shortly! Feel free to use a different provider or a free service like Cloudflare if that’s your jam. 不过现在不必担心这些。我们稍后会详细介绍!如果你喜欢,也可以随意使用其他服务商或像 Cloudflare 这样的免费服务。
Preparing Our microSD Card
准备 microSD 卡
The following was performed on macOS. Using a different operating systems will require different steps. Note that we will be extracting the tar content directly on to our microSD card, so make sure you download the Alpine image ending with tar.gz. 以下操作在 macOS 上完成。使用其他操作系统需要不同的步骤。请注意,我们将直接把 tar 内容解压到 microSD 卡中,因此请确保下载以 tar.gz 结尾的 Alpine 镜像。
Plug in SD card and find the disk with diskutil list. For our example the SD card will be located at /dev/disk4.
插入 SD 卡并使用 diskutil list 找到磁盘。在我们的示例中,SD 卡位于 /dev/disk4。
Wipe and re-partition the card as FAT32:
擦除并重新分区为 FAT32:
diskutil eraseDisk FAT32 ALPINE MBRFormat /dev/disk4
Extract the Alpine tarball onto the card:
将 Alpine 压缩包解压到卡中:
tar xzf alpine-rpi-*.tar.gz -C /Volumes/ALPINE
Clean up any macOS junk then eject it: 清理 macOS 的垃圾文件并弹出:
find /Volumes/ALPINE -name '._*' -delete
rm -rf /Volumes/ALPINE/.Spotlight-V100
rm -rf /Volumes/ALPINE/.fseventsd
rm -rf /Volumes/ALPINE/.Trashes
diskutil eject /dev/disk4
Now pop the microSD card into your Pi Zero. Be sure to have your Pi connected to a monitor and keyboard, then turn it on. 现在将 microSD 卡插入树莓派 Zero。确保树莓派已连接显示器和键盘,然后开机。
Alpine Linux in Diskless Mode
无盘模式下的 Alpine Linux
Once the Pi boots into the Alpine Live environment, login with root (no password required). Take note that the SD card should be located at /dev/mmcblk0.
当树莓派启动进入 Alpine Live 环境后,使用 root 登录(无需密码)。请注意,SD 卡应位于 /dev/mmcblk0。
Normally you would run setup-alpine and walk through the installer, but we need to configure lbu first. This will allow us to save our configurations and site files on to our SD card in order to keep persistent changes on reboot.
通常你会运行 setup-alpine 并完成安装程序,但我们需要先配置 lbu。这将允许我们将配置和网站文件保存到 SD 卡中,以便在重启后保留更改。
setup-lbu mmcblk0p1
mkdir -p /media/mmcblk0p1/cache
setup-apkcache /media/mmcblk0p1/cache
lbu commit -d
Pay close attention to lbu commit -d. You will need to run this anytime you install/remove packages or change files on the system. Otherwise they will be lost on future reboots or power outages.
请务必注意 lbu commit -d。每当你安装/卸载软件包或更改系统文件时,都需要运行此命令。否则,它们会在下次重启或断电后丢失。
With that complete, we can now continue with the install by running setup-alpine. This walks you through:
完成后,我们可以通过运行 setup-alpine 继续安装。它会引导你完成以下设置:
-
Keyboard: Pick yours
-
Hostname: Name your Pi whatever
-
Networking: Setup eth0
-
DNS: 8.8.8.8 is fine (or whatever you want)
-
Timezone: Pick yours
-
Mirror: Press f to select the fastest based on your location
-
SSH server: dropbear is MUCH lighter than the others. Highly recommend this!
-
Root password: Set one
-
Disk: IMPORTANT! Pick none here. This keeps it diskless.
-
键盘:选择你的键盘布局
-
主机名:随意命名
-
网络:设置 eth0
-
DNS:8.8.8.8 即可(或使用你喜欢的)
-
时区:选择你的时区
-
镜像源:按 f 选择离你最近的最快镜像
-
SSH 服务器:dropbear 比其他选项轻量得多,强烈推荐!
-
Root 密码:设置一个
-
磁盘:重要!此处选择 none。这能保持无盘运行。
When it asks you about storing configs / APK cache, it should already have your previously configured /media/mmcblk0p1/cache sets as default. Keep those the same.
当询问存储配置/APK 缓存时,它应该已经默认选择了你之前配置的 /media/mmcblk0p1/cache。保持默认即可。
Now with the install complete you can reboot the system. Once it boots up and you login, you can check that everything is running in memory by running: df -h /. If the root (/) is mounted as tmpfs or ramfs, it’s running in RAM. Hooray!
现在安装完成,你可以重启系统了。启动并登录后,可以通过运行 df -h / 来检查一切是否在内存中运行。如果根目录 (/) 被挂载为 tmpfs 或 ramfs,说明它正在内存中运行。太棒了!
Software: darkhttpd
软件:darkhttpd
Since we only need to serve basic HTTP (VPS handles the TLS, remember?) the best web server option for our limited resources is darkhttpd. Let’s install and setup a boot runtime to persist on reboots: 由于我们只需要提供基础的 HTTP 服务(记得吗?TLS 由 VPS 处理),对于我们有限的资源来说,最好的 Web 服务器选择是 darkhttpd。让我们安装并设置一个开机自启的运行时,以便在重启后生效:
doas apk add darkhttpd
Then we need to make a runtime file at /etc/init.d/darkhttpd:
然后我们需要在 /etc/init.d/darkhttpd 创建一个运行时文件:
#!/sbin/openrc-run
description="darkhttpd static web server"
command="/usr/bin/darkhttpd"
command_args="/var/www/example.com --port <desired-port-number> --maxconn 20"
command_background=true
pidfile="/run/darkhttpd.pid"
depend() { need net }
Then get everything running right away: 然后立即启动它:
chmod +x /etc/init.d/darkhttpd
rc-update add darkhttpd default
rc-service darkhttpd start
Here you can see that we place our website files under /var/www. Make sure you let lbu know to include this directory or else you will lose these files on reboot!
在这里你可以看到我们将网站文件放在 /var/www 下。确保让 lbu 包含此目录,否则重启后这些文件会丢失!
lbu include /etc/init.d/darkhttpd
lbu include /var/www
Also notice the maxconn parameter. Feel free to adjust this as you see fit. That’s it!
还要注意 maxconn 参数。请根据需要随意调整。就是这样!
nginx
nginx
If you require a little more flexibility or control of your web server, you can always use nginx instead. 如果你需要更灵活的 Web 服务器控制,也可以选择使用 nginx。
doas apk add nginx
Then create a site-specific configuration file at /etc/nginx/http.d/yourdomain.com.conf
然后在 /etc/nginx/http.d/yourdomain.com.conf 创建站点特定的配置文件。