🍓 第五章 使用树莓派架设服务器
📄 一句话概括

前四章都在让这块板子「为你干活」;从这一节起,它开始「为别人干活」——变成一台 24 小时开着、等着别人来要东西的服务器。 本节先装最基础的那个:Web 服务器(Apache),让别人用浏览器就能看到你放在里面的网页。它是后面三节的地基——PHP 装在它身上、数据库给它用、FTP 给它传文件。

📝 本节和前面几节的关系

上一章(第四章)讲的是「你怎么管这台机器」:命令、权限、目录、装包——都是你在操作它。 本节换了个方向:让别人通过网络来访问它。你会反复用到上一章学的两件事——apt 装包(4-5)和文件权限(4-3,这里 www-data 会第一次登场)。 读法建议:把「客户端 / 服务器」这个角色概念看懂,比记住命令更重要——后面三节、以及以后所有网络服务,都是这一套。

一、先说清「服务器」到底是什么

这个词被用得很滥,其实它不是某种特殊硬件:

💡 一句话记住

服务器 = 一台「一直开着、等着别人来要东西」的电脑。 它和你桌上这台的唯一区别是角色——你主动去要,它被动地等。

围绕这个角色,有两个词要分清:

词 谁扮演 在这件事里做什么
客户端(client) 你的手机、笔记本、另一个电脑 主动发起请求:我要 /index.html
服务器(server) 这台树莓派 被动响应:给你,或者告诉你不给

同一个程序可以一会儿当客户端、一会儿当服务器——比如你的浏览器(客户端)去访问树莓派(服务器),而树莓派的 PHP(客户端)又去问数据库(服务器)。别把「服务器」当成一台固定的机器,它是个角色。

二、Web 服务器干的事:听懂 HTTP

Web 服务器(也叫 HTTP 服务器)只做一件事:坐在一个端口上等,收到 HTTP 请求,把对应的文件或内容回过去。

它的工作循环就是三步,反复转:

① 等(监听 80 端口)
② 收到请求 → 看懂对方要什么(GET /index.html)
③ 找到文件 → 塞进响应里发回去

两个数字要认:

端口 协议 干什么
80 HTTP 普通的网页访问
443 HTTPS 加密过的网页访问
📝 端口是什么?

还记得 3-6 里那个「IP 是门牌号、端口是房间号」的比喻吗?IP 找到这台机器,端口找到机器上哪个程序。 所以「装一个 Web 服务器」在系统层面的实质是:让一个程序长期占住 80 端口,不停地听。

这就解释了为什么别人能访问你:只要在同一局域网,他们浏览器里敲 http://树莓派的IP,默认就是去敲 80 端口——你的树莓派一直在那儿听着,自然就应了。

三、三个候选:Apache、nginx、lighttpd

Web 服务器软件有很多款,树莓派上常见的是这三个:

软件 特点 适合谁
Apache(apache2) 老牌、资料最多、模块化(.htaccess、a2enmod 都出自它) 本课要学的,也是新手最不容易迷路的
nginx(读作 engine-x) 更省内存、并发更强,现在公网上的占有率已超过 Apache 追求性能、想装 WordPress 之外的现代应用
lighttpd 更轻,几百 KB 级 嵌入式、只服务几个小页面的场景
💡 为什么本课教 Apache

不是因为 Apache 最好,而是因为它的资料最多、报错最好查、和 PHP 的默认搭配最顺(下一节就装 PHP,Apache 有现成模块直接接上,nginx 得另配 php-fpm)。 学会 Apache 之后,换 nginx 只是换套配置文件的写法,概念是通的。

四、装 Apache:三行命令

Raspberry Pi OS 默认没装任何 Web 服务器(这点和某些发行版不同),所以从零装:

# ① 先刷新软件清单(第四章 4-5 学的)
sudo apt update

# ② 装 Apache2
sudo apt install apache2 -y

# ③ 看它是不是活着
systemctl status apache2 --no-pager

第 ③ 步期望看到一行:

Active: active (running) since ...

看到 active (running) 就算成功(有没有那行 Active 是判据)。

📝 装完就已经自动跑起来了

Debian 系的包很贴心:apt install 装完后会自动启动服务、并设成开机自启。 所以严格说,你不需要再敲 systemctl start apache2——但敲一遍也没坏处(已经跑着的话它只会回一句已经是 active)。 查开机自启有没有开:systemctl is-enabled apache2,期望输出 enabled。

五、验收:从别的电脑看到它

这是本节最有成就感的一步,要在另一台电脑(你的 Windows)上做:

  1. 先在树莓派上查 IP: bash hostname -I 假设得到 192.168.1.100。

  2. 在 Windows 的浏览器里打开: http://192.168.1.100

  3. 期望看到 Apache 的默认页面(标题是 Apache2 Debian Default Page,里面写着 It works!)。

⚠️ 打不开先查这四样

① IP 对不对——树莓派可能换了地址(2-5 讲过查 IP 三种方式); ② 在不在同一个局域网——手机连的是不是同一个 Wi-Fi; ③ 服务活着吗——systemctl status apache2; ④ 端口通不通——在 Windows 上执行 Test-NetConnection 192.168.1.100 -Port 80(PowerShell),TcpTestSucceeded 要是 True。 注意:Raspberry Pi OS 默认没装防火墙,所以不用像很多教程那样去开 ufw 端口——如果打不开,大概率不是防火墙,是 IP 或网段的问题。

六、这个默认页面是从哪来的:/var/www/html

Apache 装好后,网页的「家」在:

/var/www/html

你也可以在树莓派本机直接看:

ls -l /var/www/html
cat /var/www/html/index.html    # 就是刚才那个 It works! 页面

要放自己的网页,就放这个目录里。 但这里有个新手必踩的坎——权限:

ls -ld /var/www/html
# 期望看到:drwxr-xr-x 2 root root ...

看出来了吗?这个目录的主人是 root,不是你的用户(pi 或你自己起的名字)。所以:

echo "<h1>我的第一台服务器</h1>" > /var/www/html/index.html
# 报错:Permission denied

两条路可选,推荐第一条:

做法 命令 说明
① 加 sudo(推荐新手) sudo nano /var/www/html/index.html 简单直接、不改动系统权限
② 把目录改成你自己的 sudo chown -R $USER:www-data /var/www/html 以后不用 sudo,但要理解 4-3 的权限含义
📝 `www-data` 是谁?

Apache 在后台干活的专用低权限用户。它故意不用 root(万一网页程序被攻破,顶多抢到一个没权限的账号,而不是整台机器)。 你会在 /etc/apache2/apache2.conf 里看到 User www-data / Group www-data——这是安全设计的核心,别改成 root。

七、配置都在哪儿:一张地图

Apache 的配置文件散在一个目录里,新手最容易在这里迷路。记住这个结构:

/etc/apache2/
├── apache2.conf              ← 主配置(一般不用改)
├── ports.conf                ← 监听哪些端口(默认 80)
├── sites-available/          ← 【备用】所有站点配置都写在这
│   └── 000-default.conf      ← 默认站点的配置(网页目录就写在这)
├── sites-enabled/            ← 【生效】实际启用的站点(是指向 available 的软链接)
├── mods-available/           ← 【备用】所有可选模块
├── mods-enabled/             ← 【生效】实际启用的模块
└── conf-available/ · conf-enabled/   ← 全局片段,同理

这套 available / enabled 的设计是 Apache 的精髓:配置文件写好后先放在 available 里「备着」,用一条命令开关,而不是改来改去。三条命令要记:

命令 作用 大白话
sudo a2ensite 站点名 启用一个站点 「开」
sudo a2dissite 站点名 停用一个站点 「关」
sudo a2enmod 模块名 启用一个模块 「给 Apache 加个功能」

改完配置必须让 Apache 重读:

sudo systemctl reload apache2     # 温和地重读配置(不断连接)
# 配置写错了会报错;也可以先体检:
sudo apache2ctl configtest        # 期望输出:Syntax OK
💡 养成习惯

改配置 → configtest 看语法 → reload 生效。三步走完再去看效果。 如果 configtest 报 Syntax error,说明你刚写的那行有问题,回去改,别 reload。

八、出问题去哪儿看:日志

服务器不工作,第一件事不是重装,是看日志(4-2 学的 tail -f 就在这派上用场):

# 谁来过、要了什么、结果如何
sudo tail -f /var/log/apache2/access.log

# 出错了什么(404、权限被拒、PHP 报错都在这)
sudo tail -f /var/log/apache2/error.log

access.log 里一行长这样:

192.168.1.23 - - [24/Sep/2026:15:04:11 +0800] "GET /index.html HTTP/1.1" 200 612

最后那个三位的数字是状态码,最常遇到这几个:

状态码 含义 你该干什么
200 成功 正常
403 拒绝访问(Forbidden) 多半是权限问题(www-data 读不到那个文件)
404 找不到(Not Found) 文件路径写错了、放错目录了
500 服务器内部错误 多数是 PHP 代码报错,去 error.log 看

九、动手 Demo:把默认页换成自己的

目标:让别人在自己的电脑上看到你写的页面。全程五步,每步都有验收。

# ① 看清现状(当前是谁的页面、谁是主人)
ls -l /var/www/html
systemctl is-active apache2      # 期望:active
# ② 备份默认页面(好习惯:改之前先备份)
sudo cp /var/www/html/index.html /var/www/html/index.html.bak
# ③ 写一个自己的页面
sudo nano /var/www/html/index.html

在 nano 里输入(先清空原有内容,Ctrl + K 连按几次可快速删行):

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>我的树莓派</title></head>
<body>
  <h1>这台树莓派已经在当服务器了</h1>
  <p>主机名:raspberrypi</p>
  <p>它现在会一直开着,等着别人来访问。</p>
</body>
</html>

保存退出:Ctrl + O → 回车 → Ctrl + X。

# ④ 在树莓派本机先自测(不用开浏览器,看返回内容就行)
curl http://localhost

期望输出:你刚写的那段 HTML(能看到 <h1>这台树莓派已经在当服务器了</h1>)。

# ⑤ 再从另一台电脑验收
# 在 Windows 浏览器里打开 http://树莓派的IP ,应该看到同样的页面

读结果:

十、30 秒实验:亲眼看见「端口被占住」

# 看看谁在占用 80 端口(4-2 学的 ss 命令在这用上了)
sudo ss -tlnp | grep ':80'

期望看到 apache2 这个名字——这就是「一个程序长期占着一个端口」的实物证据。

接着做个反证实验:

# 把 Apache 停掉
sudo systemctl stop apache2

# 浏览器刷一下 —— 打不开了
# 看看端口现在什么样
sudo ss -tlnp | grep ':80'      # 什么都没了

# 再开回来
sudo systemctl start apache2

你会明白:所谓「架设服务器」,不过是让一个程序一直坐在端口上等。停掉它,服务就没了——这也是为什么服务器要 24 小时开机。

十一、常见误区

  1. 「服务器是特殊的电脑,得买专业设备」——错。服务器是角色不是硬件。这台树莓派、你的笔记本、云上的机器,只要「一直开着、等着别人来要东西」,它就是服务器。
  2. 「装了 Apache 就能被外网访问」——错。默认只在你家局域网内可见。想让外网访问要经过路由器端口转发,而本节强烈不推荐这么干(见下面第 6 条)。
  3. 「网页要放在 /etc/apache2 里」——错。/etc 放的是配置,网页放 /var/www/html。这也是 4-4 讲的「/etc 是设置、/var 是数据」在这门课里的具体体现。
  4. 「改完配置直接重启电脑」——不必。sudo systemctl reload apache2 就够了,甚至不用重启服务。重启电脑是最后手段。
  5. 「/var/www/html 报 Permission denied 是系统坏了」——不是。它属于 root,本来就不让你随便写(4-3 的权限概念)。加 sudo 就好。
  6. 「在路由器上把 80 端口转发出去,我就能随时随地访问了」——危险,别做。这意味着任何人扫到你家 IP 都能敲你的服务器;而这台机器上跑的是没打过安全补丁、没配过 SSL、可能还跑着没写完的 PHP 的系统。要在外网用,正确的路是走 SSH 隧道或 VPN(3-6 那条红线的延续)。
⚠️ 老教程里已失效的写法

这门课的原书写得早,中文教程也大多是旧的。本节这几处照抄会踩坑: - 装 php5 / libapache2-mod-php5 —— 那是十年前的包名,现在只有 PHP 8.x,包名里没有版本号后缀(下一节细说); - 编辑 /etc/apache2/httpd.conf —— 那是 CentOS / 老版 Apache 的路子,Debian 系根本没有这个文件,主配置是 apache2.conf,站点在 sites-available/; - 改完去开 ufw 的 80 端口 —— Raspberry Pi OS 默认没装 ufw、也没有防火墙,照抄这一句 ufw: command not found; - /etc/init.d/apache2 restart —— 老式服务管理写法,现在统一用 systemctl(4-2 讲过 service → systemctl 的换代)。

自测三问(点开对答案) 1. 「服务器」这个词指的是硬件还是角色?判据是什么?(**角色**——判据是「**是不是一直开着、等着别人来要东西**」。同一台笔记本装上 Apache 就是服务器,关掉就不是) 2. Apache 的 `sites-available` 和 `sites-enabled` 有什么区别?(**前者是「备着」的配置文件,后者是「真正生效」的**;`a2ensite` 就是在两者之间建/删软链接,这是 Apache 的开关设计) 3. 别人打不开你的网页,而你在树莓派上 `curl http://localhost` 是正常的——最可能的问题在哪?(**在网络层,不在服务器本身**——服务器已经证明能应答,问题多半是 IP 写错、不在同一网段,或用错了地址)

相关笔记