PES
ZH English 한국어 日本語 中文 हिन्दी বাংলা اردو Español Português Français Deutsch Русский العربية Bahasa Indonesia Tiếng Việt ไทย Türkçe

如何开启通知

此浏览器或网址无法使用通知。请使用支持通知的浏览器,通过安全连接访问PES。

如果通知被屏蔽,请在浏览器设置中允许通知。

  1. 打开地址栏旁的站点设置或浏览器的站点设置,将此网站的通知设为允许。
  2. 在设备设置中允许浏览器发送通知,并检查勿扰模式或专注模式。
  3. 返回PES,刷新页面,然后通过铃铛开启通知。

在iPhone或iPad上,将PES添加到主屏幕,从主屏幕打开后允许通知。

我的学习进度
  1. 人工智能用法
  2. 终端命令
  3. 人工智能进阶
  4. Vibe 编程
  5. 人工智能证书 准备中
  6. 键盘
查看详情
返回 Vibe 编程
VIBE 编程

Web 服务器

二十行 Shell,浏览器就肯跟它说话。

Web 服务器不过是一个等待请求、送出响应的程序。为了证明这一点,我们只用 bash、netcat 和一个命名管道做一台出来 —— 每一行你都读得懂。之后再走向 Caddy,那是连 HTTPS 一起带上、真正跑线上站点的服务器。

Docker:把 Caddy 装进盒子,再把真正的站点放上互联网

把一个程序连同它运行所需的一切 —— 库、配置,甚至一个小小的操作系统 —— 打包成一个 ,再把这个镜像作为运行。容器在你的笔记本上和在租来的服务器上表现完全一样,于是那句老借口「可在我电脑上是好的啊」就不复存在了。

Caddy 本来就只是一个文件,何必多此一举?因为真正的很快就要同时跑好几样东西 —— 一个站点、一个应用、一个。Docker 给每一样东西一个自己的盒子,用同样几条命令就能启动、停止、更新和删除,既不用在服务器上另装别的,也不会打扰左邻右舍。

先认识四个词

  1. 镜像把一个程序和它所需的一切冻结起来的包。可以直接下载(caddy:2),也可以用一份叫 Dockerfile 的配方文件自己构建。运行期间它从不改变。
  2. 容器正在运行的镜像。一个镜像可以启动许多个容器,删掉容器也碰不到镜像 —— 下次启动又是全新的。
  3. 端口映射容器有自己的端口,外面谁也看不见。-p 8080:80 把你电脑的 8080 端口接到容器里的 80 端口,浏览器才能连得上。
  4. 数据卷容器写在自己内部的文件,会随着容器被删而消失。数据卷,或者挂载进去的你自己的文件夹,才是能留下来的存储 —— 你的页面、配置和 Caddy 的证书都住在那里。

安装 Docker

在 Mac 或 Windows 电脑上,从 docker.com 安装 Docker Desktop 并启动一次,之后终端里的 docker 命令就能用了。在 Linux 服务器上,Docker 官方脚本一行就能装好一切。继续往下之前,两条检查命令都应该有回应。

install
# macOS · Windows: install Docker Desktop from docker.com and start it once

# Ubuntu / Debian server: Docker's official install script
curl -fsSL https://get.docker.com | sh

# check that both commands answer
docker --version
docker compose version

一条命令跑起 Caddy

进到放着 index.html 的文件夹,运行下面这一行。第一次 Docker 会下载 Caddy 镜像,之后大约一秒就能启动。打开 http://localhost:8080,你的页面就在那儿。

terminal
# serve this folder at http://localhost:8080 (Control-C stops it)
docker run --rm -p 8080:80 -v "$PWD":/usr/share/caddy caddy:2
  1. docker run用镜像创建一个容器并启动它。
  2. --rm容器一停就删掉它,免得停下的容器越积越多。镜像还在,所以下次运行一样快。
  3. -p 8080:80把你电脑的 8080 端口接到容器里 Caddy 监听的 80 端口。左边的数字随你挑,右边的数字由镜像定好。
  4. -v "$PWD":/usr/share/caddy让当前文件夹($PWD)在容器里显示为 /usr/share/caddy —— 官方镜像默认对外提供的就是这个文件夹。在这里改一个文件,下次刷新就能看到变化。
  5. caddy:2要运行的镜像:官方 Caddy 镜像,任意 2.x 版本。不带 :2 标签的话,Docker 会取 latest,而它哪天可能就在你脚下跳到一个新的大版本。

按 Control-C 停止。临时看一眼再合适不过,但命令很长,终端一关就忘了。凡是要长期放着的,就把它写进文件 —— 这就是下一个项目。

项目 1:一个 HTML 主页,从文件夹到互联网

整个项目就是三个小文件。index.html 是页面,Caddyfile 告诉 Caddy 要提供什么,compose.yaml 告诉 Docker 如何运行 Caddy。Docker Compose 会读这个文件,所以你再也不用重新敲一遍长长的 docker run 命令。

my-site
my-site/
├── compose.yaml
├── conf/
│   └── Caddyfile
└── site/
    └── index.html
compose.yaml
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./conf:/etc/caddy
      - ./site:/srv
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:

逐行看 compose.yaml

  1. image: caddy:2要运行的镜像 —— 和前面一样的官方 Caddy 镜像。
  2. restart: unless-stopped容器崩溃或服务器重启时,Docker 会自动把它重新启动,直到你有意把它停掉。
  3. "80:80" · "443:443"把机器的 80(http)和 443(https)端口开给 Caddy。Caddy 要拿到证书、把访客从 http 转到 https,两个都需要。
  4. "443:443/udp"还是 443 端口,不过走 UDP。它让浏览器能用上 HTTP 最新的版本 HTTP/3。省掉也无妨,站点就只用 HTTP/2。
  5. ./conf:/etc/caddy你的 conf 文件夹变成 /etc/caddy,Caddy 会在那里找它的 Caddyfile。Caddy 的文档挂载的是整个文件夹而不是单个文件,因为很多编辑器保存时会用新文件替换旧文件,只挂载单个文件的话会一直看到旧内容。
  6. ./site:/srv你的 site 文件夹变成 /srv —— Caddyfile 对外提供的文件夹。在磁盘上改一个页面,Caddy 立刻就提供新版本,不用重启。
  7. caddy_data:/data由 Docker 替你保管的具名数据卷。Caddy 把 HTTPS 证书和密钥存在这里,所以容器被删掉再重建时它们依然还在。旁边的 caddy_config 也以同样的方式保住 Caddy 的自动配置。

先在自己电脑上试

在 Caddyfile 的地址位置写上 :80。意思是「不管问的是哪个名字,都在 80 端口回答」 —— 不带证书的普通 http,对一台没有域名的电脑来说正合适。然后启动它,打开 http://localhost。

conf/Caddyfile
:80 {
	root * /srv
	file_server
}
terminal
cd my-site
docker compose up -d      # start Caddy in the background
open http://localhost     # or type the address into a browser
docker compose logs -f    # watch requests arrive (Control-C stops watching)

放上互联网

  1. 租一台服务器任何带公网 IP 地址的 VPS 都行 —— 小而便宜的就足够。用上面的脚本在上面装好 Docker,并确认它的防火墙放行 80 和 443 端口。
  2. 让域名指向它在你买的地方,添加一条 A 记录:名称填 example.com,值填服务器的 IP 地址。要等整个互联网都看到这个变化,可能需要几分钟到几个小时。
  3. 写上真正的地址在 Caddyfile 里把 :80 换成你的域名。正是这一处改动打开了自动 HTTPS:Caddy 会申请证书、安装、续期,并把 http 访客转到 https。
  4. 复制并启动用 rsync 把文件夹复制到服务器,用 ssh 登录,再用 docker compose up -d 启动。盯着日志看:出现一行说证书已经拿到,你的站点就上线了。
conf/Caddyfile
example.com {
	root * /srv
	file_server
	encode gzip zstd
}

下面的 203.0.113.10 是保留给示例用的地址,请换成你自己服务器的 IP。以后要改页面,就改 index.html,再运行一次同样的 rsync。site 文件夹是挂载进容器的,所以不用重启任何东西,下次刷新就是新页面。

terminal
# on your computer: copy the project folder to the server
rsync -av my-site/ root@203.0.113.10:~/my-site/

# on the server: start it — Caddy fetches the HTTPS certificate by itself
ssh root@203.0.113.10
cd ~/my-site
docker compose up -d
docker compose logs -f caddy

项目 2:一个 React 主页

是一个 ,用可以重复使用的小组件来搭建页面。对发布来说,要紧的只有一点:React 项目不能原样拿去提供。构建步骤会把它变成 dist 文件夹里普通的 HTML、CSS 和 JavaScript 文件 —— 从那以后,就和项目 1 是同一件事了。

下面的命令需要你电脑上装有 Node.js。Vite 会创建一个马上就能跑的 React 项目,npm run dev 在你工作时显示它,npm run build 写出完成的站点。

terminal
# needs Node.js (nodejs.org) — create a React project with Vite
npm create vite@latest my-react -- --template react
cd my-react
npm install
npm run dev      # development server at http://localhost:5173

npm run build    # the finished site is written to dist/

方法 A:在自己电脑上构建,只复制结果

最简单的路线是原样复用项目 1。先构建,然后只把 dist 文件夹复制到服务器的 site 文件夹。--delete 会删掉上一次构建留下、这次已经不存在的文件,旧的残留就不会越堆越多。

terminal
# way A: build here, copy only the result into Project 1's site folder
npm run build
rsync -av --delete dist/ root@203.0.113.10:~/my-site/site/
React 在 Caddyfile 里需要的那一行

React 应用从一个 index.html 出发,自己画出每一个页面。像 /about 这样的地址并不是磁盘上的文件,所以如果没人帮忙,一旦有人刷新那个页面或者打开分享给他的链接,Caddy 就会回答 404。try_files 告诉 Caddy:文件存在就给那个文件,否则交出 index.html,让 React 去画出正确的页面。

Caddyfile
example.com {
	root * /srv
	encode gzip zstd
	try_files {path} /index.html
	file_server
}

方法 B:用两阶段 Dockerfile,让 Docker 来构建

更稳妥的路线是在 Docker 里构建。这样无论是服务器还是同事的电脑,每次都以同样的方式构建,也没人需要在服务器上安装 Node。Dockerfile 分两个阶段:第一阶段用 Node 构建,第二阶段只留下结果。

Dockerfile
# stage 1: build the React app with Node
FROM node:24-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# stage 2: only the finished files go into the Caddy image
FROM caddy:2
COPY Caddyfile /etc/caddy/Caddyfile
COPY --from=build /app/dist /srv

逐行看 Dockerfile

  1. FROM node:24-alpine AS build第一阶段从一个带 Node.js 的镜像开始,并给这个阶段起名叫 build,好让下一阶段能从这里拿文件。
  2. COPY package*.json ./ · RUN npm ci先只复制软件包清单,然后严格按锁文件里的版本安装。只要清单不变,Docker 就会复用这一步,之后的构建便能跳过缓慢的安装。
  3. COPY . . · RUN npm run build复制其余的源代码并构建。完成的站点现在位于 build 阶段里的 /app/dist。
  4. FROM caddy:2第二阶段从一个干净的 Caddy 镜像重新开始。除非你复制过来,第一阶段的东西一样也不会跟过来。
  5. COPY --from=build /app/dist /srv只从 build 阶段取出构建好的文件,放到 Caddyfile 对外提供的位置。Node 和 node_modules 都留在后面,所以最终的镜像一直很小。

把加了 try_files 的 Caddyfile 放在 Dockerfile 旁边,并使用下面的 compose.yaml。build: . 的意思是「用这个文件夹里的 Dockerfile 来制作镜像」,而不是去下载一个。在服务器上 clone 代码后,一条命令就能构建并启动;以后每次修改,先 pull,再运行同一条命令。

compose.yaml
services:
  web:
    build: .
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:
terminal
# keep node_modules and old builds out of the image
printf 'node_modules\ndist\n' > .dockerignore

# on the server: get the code, then build and start in one step
git clone https://github.com/you/my-react.git
cd my-react
docker compose up -d --build

# after you push a change: pull it and rebuild
git pull && docker compose up -d --build

你会用到的命令

命令作用
docker compose up -d在后台启动 compose.yaml 里的一切。改了 compose.yaml 之后再运行一次,只有改动过的部分会被重新创建。
docker compose ps列出本项目的容器以及它们是否在运行。站点没有回应时,第一个要查的就是它。
docker compose logs -f实时跟踪日志。证书问题、路径写错、程序崩溃,都会最先在这里露面。Control-C 停下的只是观看,不是服务器。
docker compose exec -w /etc/caddy caddy caddy reload让 Caddy 在运行中的容器里重新加载 Caddyfile,一条连接也不中断。改完 Caddyfile 后用它。
docker compose down停止并删除容器。具名数据卷会保留下来,所以证书也还在。加上 -v 会把它们一并删掉 —— 别这么做。
docker compose pull下载更新版的 Caddy 镜像。接着运行 docker compose up -d 才会切换过去。
千万别丢掉 caddy_data

你的证书住在 caddy_data 数据卷里。如果它被删掉 —— 用了 docker compose down -v,或者在 compose.yaml 里漏写了这个卷 —— Caddy 每次启动都得重新申请证书。证书颁发机构会限制同一个域名一周内能拿到的证书数量,所以几次粗心的重启,就可能让你的站点好几天都没有 HTTPS。

Web 客户端

这一栏由你自己标记,这里不打分。

要把这一阶段标记为已理解吗?

目前还不能取消,请在真正理解后再标记。

已标记为理解

这一栏由你自己标记,这里不打分。

学习指南

人工智能

人工智能资格证

学习

Vibe 编程

游戏开发

练习

导师

聊天

论坛

创作

社区

更多

术语词典

选一个你不认识的词吧,可以看到简单的解释和相关术语。

还没有匹配的术语。

选择一个术语即可查看解释。