个人博客搭建-小白从0到1
概述
- web的结课作业是搭建一个个人博客,所以这里来记录一下搭建过程。
- 本文是以小白的视角来搭建,所以搭建过程中没有难以理解的点,然后搭建完之后,可以大概理解前端后端的区别,知道怎么搭建服务器等知识。
- 这是第二版,优化了排版,增加了一些必要的概念解释。
- 这是第三版,更新于25-05-28,增加了备案成功后的步骤!重大里程碑!
- 本教程构建的是静态网页
一、网页概念
1.1 目的
- 让其他人可以通过一个网址来访问到我们自己的网页。
1.2 网页区别
- 我们常看到的网页分为动态网页和静态网页
1.2.1 静态网页
- 将事先写好的前端代码放到服务器上,这里服务器的角色只是代码展现者。
- 优点:开发简单(不用进行太多后端的配置),访问速度非常快
- 缺点:个性化差(因为只是展示我们写好的代码,所以每个用户看到的数据都是一样的。比如我想写 你好*** ,这里只能是一样的名字)
1.2.2 动态网页
- 我们将前端代码上传至服务器,服务器可以在此基础上根据用户请求生成内容
- 优点:个性化搞(根据不同用户可以显示不同内容)
- 开发复杂度高
1.2.3 对比
特性 | 静态网页 (Static) | 动态网页 (Dynamic) |
---|---|---|
内容生成 | 预先写好,服务器直接发送文件 | 服务器端程序根据请求实时生成内容 |
服务器端处理 | 几乎没有 (仅文件伺服) | 大量 (运行后端代码, 访问数据库等) |
数据库 | 通常不需要 | 通常需要 |
个性化 | 低 (所有用户看一样的内容) | 高 (可根据用户显示不同内容) |
交互性 | 主要靠客户端 JavaScript | 客户端 JavaScript + 服务器端逻辑 |
开发复杂度 | 相对较低 | 相对较高 (需要前端+后端) |
托管 | 简单,便宜/免费 | 可能需要更复杂的服务器配置和更高的成本 |
速度 | 通常非常快 | 可能较慢 (需优化) |
安全性 | 相对较高 | 挑战更大 |
二、博客搭建方法指南
2.1 概述
- 网页分为静态网页和动态网页,每种网页的构建有两个大分支:前端部分,内容创建和管理;后端部分,网站如何部署和托管。
- 构建这两个分支有不同的实现方案,而不同的方案,操作难度和方式也不同。
2.2 内容创建
-
纯手动编写 HTML, CSS, JavaScript 文件(静态)
- 特点:网页内容、格式等全部代码完全由我们编写,纯手工
- 优点:网页格式内容等完全有我们掌控
- 缺点:代码维护成本高
-
使用静态网站生成器 (静态,Jekyll, Hugo, Eleventy, Next.js)
- 特点:会将我们写的文章等自动生成可以运行的代码,我们本次构建静态网站主要用到Eleventy。
- 优点:管理方面,功能丰富,是目前构建静态网站主流方式之一
-
静态网站构建平台(静态,Webflow 等)
- 特点:网页操作可视化,代码编写很少。
- 优点:上手快
- 缺点:生成的代码质量不确定,灵活性低。
-
动态内容与应用逻辑(动态)
- 特点:将数据交给服务器端来处理,并生成用户可以看到的HTML代码(手动)
-
Headless CMS(都适用)
- 特点:他负责后端格式构建,我们只关注前端展示。(半自动)
- 优点:前后端分离,灵活性高,前端可以选择最优技术栈。
-
内容管理系统(动态,WordPress (PHP), Drupal (PHP))
- 特点:预先构建好的动态网站应用程序,可视化操作,代码编写很少。(全自动)
2.3 网站部署和托管
-
静态网站托管平台(静态,GitHub Pages、Netlify、Vercel )
- 特点:专为伺服静态文件设计,极简后端运维
-
自己购买和管理云服务器(都适用,阿里云 ECS、腾讯云 CVM)
- 特点:完全控制权
- 用途:
- 静态:安装 Web 服务器(Nginx/Apache)伺服静态文件(当前方式)
- 动态:安装 Web 服务器、后端语言环境、数据库,运行后端应用程序
- 维护:用户完全负责
-
使用服务器管理面板在云服务器上部署(都适用,宝塔面板、aaPanel、cPanel)
- 特点:基于云服务器,通过图形面板简化管理
- 用途:
- 静态:通过面板创建网站并上传静态文件
- 动态:面板支持一键安装 PHP/MySQL/Node.js 等环境,方便部署动态应用(如 WordPress)
- 维护:用户需负责服务器基础管理,但面板简化了应用层操作
-
平台即服务(主要用于动态,也可用于特定静态框架,Heroku、Google App Engine)
- 特点:开发者只需上传代码,平台管理底层基础设施
- 用途:
- 动态:适合部署 Python/Node.js/Java/Ruby/PHP 等后端应用
- 维护:平台负责大部分
-
传统的虚拟主机((主要用于简单动态 PHP,也可用于静态)
- 特点:资源共享,通常预装 PHP+MySQL。服务商负责服务器,用户负责网站
- 用途:
- 静态:通过 FTP/SFTP 上传 HTML/CSS/JS 文件
- 动态:适合部署简单 PHP 网站(如 WordPress),对其他后端语言支持有限
2.4 对比
方式分类 | 具体方法/工具 | 主要特点 | 学习曲线/操作难度 | 灵活性/控制权 | 成本 (大致) |
---|---|---|---|---|---|
内容/应用逻辑 | 1. 手动 HTML/CSS/JS (静态) | 直接控制,基础 | 低(简单页)至高(复杂) | 非常高 | 无工具成本 |
2. 静态网站生成器 (SSG) (静态) | Markdown+模板, 自动化构建 | 中等 | 高 | 无工具成本 | |
3. 后端编程+框架+数据库 (动态) | 服务器端实时生成内容,数据驱动,复杂交互 | 高至非常高 | 非常高 | 开源框架免费,开发时间 | |
4. 内容管理系统 (CMS) (动态) (如 WordPress) | 后台管理内容,预置功能 | 低(使用)至中(定制) | 中等 | 开源CMS免费,主题/插件可能付费 | |
部署与托管 | A. 静态网站托管平台 (静态) (GitHub Pages, Netlify) | 极简后端运维,Git自动部署,CDN,自动HTTPS | 低 | 低 (对服务器) | 很多免费额度 |
B. 自购云服务器 + 手动配置 (都适用) (阿里云ECS+Nginx) | 完全控制,需手动完成所有配置维护 | 高 | 非常高 | 服务器和域名付费 | |
C. 自购云服务器 + 面板 (都适用) (宝塔) | 图形面板简化管理,仍需购服务器 | 中等 | 高 (对服务器) | 服务器和域名付费 | |
D. 平台即服务 (PaaS) (主要动态) (Heroku) | 上传代码,平台管理基础设施 | 中等 | 中等 | 免费额度有限,之后按需 | |
E. 传统虚拟主机 (主要简单动态PHP, 也可静态) |
三、静态网页搭建指南
3.1 步骤概览
-
我们的两个分支选择为:
- 前端部分,内容创建和管理:使用静态网站生成器
- 后端部分,网站如何部署和托管:自己购买和管理云服务器
-
阶段一:服务器准备与系统初始化
- 获取服务器资源(拥有一个可以 24/7 运行你网站的“在线电脑”)
- 安装操作系统并登录(为服务器安装“灵魂”(操作系统),并建立管理通道)
- 系统更新与基础工具安装
-
阶段二:Web 服务器安装与配置
- 安装 Nginx Web 服务器(安装一个能“理解”HTTP 请求并“展示”网页给访问者的软件。)
- 启动 Nginx 并验证
-
阶段三:准备和上传你的静态博客文件
- 在本地创建博客文件
- 在服务器上创建网站根目录
- 配置 SSH 密钥对认证 (由于阿里云服务器禁用密码登录)
- 上传博客文件到服务器
-
阶段四:配置 Nginx 托管你的博客并最终验证
- 创建 Nginx 站点配置文件
- 创建 Nginx 站点配置文件
- 最终验证
-
阶段五:配置域名并启用 HTTPS (安全访问)
- 购买域名
- 配置 DNS 解析
- 确保服务器防火墙/安全组开放 443 端口
- 安装 Certbot 及其 Nginx 插件
- 运行 Certbot 为域名获取并配置证书
-
阶段六:最终 HTTPS 验证
3.2 阶段一:服务器准备与系统初始化
3.2.1 服务器购买
- 我们这里购买阿里云的服务器,因为学生有 300元无门槛优惠卷,所以服务器我们相当于免费使用。
- 认证步骤:
- 进入阿里云官网 -> 上面一栏填点击“权益中心” -> 点击“高校学生通用权益” -> 认证学生并领取优惠券
- 直达网址:阿里云学生权益
- 购买步骤:
- 当前权益页面下拉 -> 选择ECS,e实例(按需购买)-> 立即购买 -> 右侧弹出购买页 -> 地域选离你近的地方,镜像的操作系统选择ubuntu,其他按要求填即可。
- 因为我已经买过了,有优惠卷可以直接0元购
3.2.2 运行服务器
- 运行步骤:
- a.上面点击控制台 -> 点击云服务器ECS -> 点击概览 -> 点击远程连接 ->立即登录
- - b.登录实例页面:网络连接点击公网 -> 连接方式点击免密连接 -> 登录
- c.登录服务器成功
- a.上面点击控制台 -> 点击云服务器ECS -> 点击概览 -> 点击远程连接 ->立即登录
3.2.3 安全组规则配置
-
- a.上面点击控制台 -> 点击云服务器ECS -> 安全组 -> 规则管理 -> 快速添加 (按需求添加,不知道全加上就行)
- 这一步是限制哪些IP可以访问我们的服务器。
3.3 阶段二:Web 服务器安装与配置
- 我们这里使用命令行来完成操作,因为相对于宝塔这种可视化操作,命令行可以让我们了解更加基础的知识。
3.3.1.系统初始化与准备
-
更新软件包列表: (确保系统知道最新的软件版本信息)
apt update
-
升级所有已安装的软件包: (将系统软件更新到最新,保持安全和稳定)
apt upgrade -y
-
安装常用基础工具: (方便后续操作)
apt install -y curl wget unzip git
3.3.2. 安装和配置 Web 服务器 (Nginx)
-
安装 Nginx: (安装“网站展示软件”)
apt install -y nginx
-
启动 Nginx 服务: (让 Nginx 开始工作)
systemctl start nginx
- 简单说: 这个命令告诉系统:“启动 Nginx 服务程序。”
- 预期行为: 这个命令通常执行后不会有任何输出,直接返回到命令提示符,表示命令已接受。
- 设置 Nginx 开机自启: (确保服务器重启后 Nginx 会自动运行)
systemctl enable nginx
- 简单说: 这个命令告诉系统:“以后每次服务器开机的时候,都自动把 Nginx 服务启动起来。”
- 预期输出: 你可能会看到类似
Synchronizing state of nginx.service with SysV service script with /lib/systemd/systemd-sysv-install. 和 Executing: /lib/systemd/systemd-sysv-install enable nginx
这样的输出,或者直接提示创建了符号链接 (symlink)。这都表示设置成功。
- 检查 Nginx 服务状态 (可选): (确认 Nginx 是否正常运行)
systemctl status nginx
- (按
q
退出状态显示)
- (按
- 最关键的一行是 Active: active (running),这表示 Nginx 正在正常运行。
- 验证 Nginx 默认页 (通过浏览器):
- 在浏览器地址栏输入:
http://<你的服务器公网IP>
- 预期看到:“Welcome to nginx!” 页面。
- 在浏览器地址栏输入:
3.3.3. 为你的博客网站做准备
- 创建网站根目录: (为你的博客文件建立一个“家”)
mkdir -p /var/www/myblog
- 简单说: 这个命令会在 /var/www/ 目录下创建一个名为 myblog 的新文件夹。
- (可选) 更改目录所有权 (如果你不是一直用root操作,或者为了特定上传方式):
chown -R root:root /var/www/myblog # 示例:赋给root用户和组
- (或者赋给你创建的普通用户名,例如
chown -R youruser:youruser /var/www/myblog
)
- (或者赋给你创建的普通用户名,例如
3.4.阶段三:准备和上传你的静态博客文件(注意,接下来是前端代码,在我们电脑命令窗进行,不是服务器的命令窗)
3.4.1 步骤概览
- 这里我们总体分为两步,第一步就是生成我们想展现的内容;第二步就是将我们编辑好的内容传输到我们的服务器。
- 第一步:2.2内容创建:这里我们选择方式二,使用静态网站生成器Eleventy - SSG,这会使我们的编写内容更加方便流畅。而我们如何部署Eleventy,这里就要用到Git Bash。
- 第二步:本地文件传输到服务器,以下有三种方式,我们使用方式一,直接用本地命令行就可以完成。
- 方法一:SCP (在你本地电脑的终端执行!)
- 方法二:SFTP 客户端 (如 FileZilla, WinSCP)
- 方法三:Git (在服务器上执行,前提是本地已推送到远程仓库)
3.4.2 安装Node.js和npm
- 前提:确保我们本地电脑已经安装了 Node.js 和 npm。
-
验证方式:(win系统为例,打开cmd命令行:ctrl+R -> cmd -> 回车)
node -v # 查看 Node.js 版本号(如 v22.15.11) npm -v # 查看 npm 版本号(如 10.2.3)
- 如果显示版本号,则说明安装成功
-
安装官网:NodeLTS版
-
步骤:登录官网点击下载 -> 安装,直接下一步即可,不过Tools for Native Modules这一步可以勾选上。
-
-
3.4.3.安装Git
-
选择构建Eleventy项目方式。
- 构建Eleventy项目,有不同的构建方式。我们用命令行的方式构建,但是命令行也有不同的类型。一种是cmd(win电脑自带命令行),另一种是Git Bash命令行。这里我们选择Git Bash,以下是原因:
- “Bash” 本身是 Linux 和 macOS 系统中非常流行的默认 Shell (命令行解释器)。Git Bash 提供了一个 模拟的 Bash 环境 在 Windows 上运行。这意味着我们可以在 Windows 上使用很多常用的 Linux/Unix 命令。
- 简单说就是在win系统下用linux的命令操作,因为我们的服务器搭建常用的就是Linux操作系统,所以使用Git Bash有助于我们之后的web开发。
- 构建Eleventy项目,有不同的构建方式。我们用命令行的方式构建,但是命令行也有不同的类型。一种是cmd(win电脑自带命令行),另一种是Git Bash命令行。这里我们选择Git Bash,以下是原因:
-
安装Git for Windows(就是下载win版的git,而我们用到的Git Bash是Git for Windows包中的一个命令行工具)
- 下载网址:Git for Windows
- 步骤:点击下载网址 -> 点击下载Windows版 ->安装,如果不知道什么意思,全部下一步完成安装。
- 完成后点击开始,就可以发现Git Bash,我们打开。建议右键建立快捷方式。
3.3.4.在本地电脑上设置 Eleventy 项目
4.创建项目骨架并初始化 npm:
# 1. 打开 Git Bash
# 2. 导航到D盘并导航到创建的文件夹0.mybolg中(位置可以自己选择,这里先在D盘测试)
cd /d
mkdir -p "0.myblog" # 在D盘创建0.mybolg文件夹
cd "0.myblog" # 导航到0.myblog文件夹
# 3. 创建 Eleventy 项目根文件夹并进入
mkdir my-eleventy-blog
cd my-eleventy-blog
# 4. 在项目根文件夹内,一次性创建所有需要的子文件夹
mkdir posts # 存放你的博客文章 (Markdown 文件)
mkdir _includes # 存放布局和可复用的模板片段 (Nunjucks 文件)
mkdir css # 存放你的 CSS 样式文件
mkdir images # (可选) 如果你计划有图片,可以现在创建
mkdir _data # (可选) 如果你计划使用全局数据文件,可以现在创建
# 5. 初始化 npm 项目
npm init -y
- 完成后,我们打开文件就可以看到这个结构:
0.myblog/ # 项目总目录 └── my-eleventy-blog/ # Eleventy项目根目录 ├── posts/ # 博客文章(Markdown格式) ├── _includes/ # 布局模板和组件(Nunjucks/HTML) ├── css/ # 样式文件(CSS或预处理语言) ├── images/ # 图片资源(可选) └── _data/ # 全局数据文件(可选) └── package.json # ```
-
安装 Eleventy 和其他必要依赖:
操作 (确保当前仍在 my-eleventy-blog 目录的终端中):npm install --save-dev @11ty/eleventy npm install --save-dev luxon
- 解释: 下载并安装 Eleventy 和 luxon。node_modules 文件夹和 package-lock.json 文件会自动生成。
- 现在,我们的文件目录是这样的:
-
创建和编辑核心文件内容:
-
这里编辑文件要用到VScode,下载并打开VScode -> 点击左上角文件 ->打开文件夹 -> 选择我们的my-eleventy-blog文件
-
a.在 my-eleventy-blog/posts/ 目录下创建:
- 文件名:hello-world.md
--- title: 你好,Eleventy 世界! date: 2023-11-01 # 你可以改成创建这篇文章的实际日期,格式 YYYY-MM-DD layout: layout-post.njk tags: - 介绍 - Eleventy基础 - 我的第一篇 --- ## 这是我的第一篇 Eleventy 博客文章 我正在使用 Eleventy 来搭建我的博客。到目前为止,感觉很棒! 用 Markdown 写文章确实比直接写 HTML 要方便得多,我可以更专注于内容本身。 ### Eleventy 的一些优点: * **灵活性高:** 它不强制特定的前端框架。 * **配置简单:** 上手相对容易。 * **性能好:** 生成的静态网站速度快。 下面是一个代码块示例: ```javascript function greet(name) { console.log(`Hello, ${name}!`); } greet("Eleventy User");
-
b.在 my-eleventy-blog/_includes/ 目录下创建:
- 文件名: layout-base.njk
- 内容
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ title }} - 我的博客</title> <link rel="stylesheet" href="{{ '/css/style.css' | url }}"> </head> <body> <header> <h1><a href="{{ '/' | url }}">我的 Eleventy 博客</a></h1> <nav> <a href="{{ '/' | url }}">首页</a> {# <a href="/about/">关于我</a> #} </nav> </header> <main> {{ content | safe }} </main> <footer> <p>© {% year %} 你的名字或博客名</p> </footer> </body> </html>
- 文件名: layout-post.njk
- 内容:
--- layout: layout-base.njk --- <article> <h2>{{ title }}</h2> <p>发布日期:<time datetime="{{ date | htmlDateString }}">{{ date | readableDate }}</time></p> {% if tags %} <p>标签: {% for tag in tags %} <span class="tag">{{ tag }}</span>{% if not loop.last %}, {% endif %} {% endfor %} </p> {% endif %} <hr> {{ content | safe }} </article>
-
c.在 my-eleventy-blog/css/ 目录下创建:
- 文件名: style.css
- 内容:
body { font-family: Arial, sans-serif; line-height: 1.6; margin: 20px auto; /* 页面水平居中 */ padding: 0 20px; /* 页面左右内边距 */ max-width: 900px; /* 内容最大宽度,避免在大屏幕上过宽 */ color: #333; /* 主要文字颜色 */ background-color: #f9f9f9; /* 页面背景色,淡灰色 */ } header, footer { background-color: #e9e9e9; /* 页眉页脚背景色 */ padding: 15px; text-align: center; margin-bottom: 25px; /* 与主要内容的间距 */ border-radius: 5px; /* 圆角 */ } header h1 { margin: 0; /* 移除h1的默认外边距 */ } header h1 a { text-decoration: none; /* 移除链接下划线 */ color: #2c3e50; /* 标题链接颜色,深蓝灰色 */ } nav a { margin: 0 15px; /* 导航链接间距 */ text-decoration: none; color: #3498db; /* 导航链接颜色,亮蓝色 */ font-weight: bold; } nav a:hover { text-decoration: underline; /* 鼠标悬停时显示下划线 */ } main { background-color: #ffffff; /* 主要内容区白色背景 */ padding: 25px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); /* 轻微的盒子阴影,增加立体感 */ } article h2 { color: #2c3e50; /* 文章标题颜色 */ margin-top: 0; /* 移除文章标题的上边距 */ } article p, article li { margin-bottom: 1em; /* 段落和列表项的下边距,增加可读性 */ } .tag { background-color: #3498db; /* 标签背景色 */ color: white; /* 标签文字颜色 */ padding: 3px 8px; /* 标签内边距 */ border-radius: 3px; /* 标签圆角 */ font-size: 0.85em; /* 标签字号 */ margin-right: 5px; /* 标签之间的右边距 */ text-decoration: none; /* 如果标签是链接,移除下划线 */ display: inline-block; /* 确保标签正确显示padding和margin */ } hr { border: 0; height: 1px; background: #dddddd; /* 分隔线颜色 */ margin: 20px 0; /* 分隔线上下边距 */ } footer { margin-top: 25px; /* 页脚与主要内容的间距 */ font-size: 0.9em; color: #777777; /* 页脚文字颜色,灰色 */ } ```
-
d.在 my-eleventy-blog/ 根目录下创建:
- 文件名: .eleventy.js (注意文件名前面的点)
- 内容:
const { DateTime } = require("luxon"); module.exports = function(eleventyConfig) { // 将 "css" 文件夹及其内容复制到输出目录 (_site/css) eleventyConfig.addPassthroughCopy("css"); // 如果你有图片文件夹,例如 "images",也可以像下面这样复制 // eleventyConfig.addPassthroughCopy("images"); // 添加一个易读的日期过滤器 eleventyConfig.addFilter("readableDate", dateObj => { // 检查传入的是否是有效的 Date 对象 if (dateObj instanceof Date && !isNaN(dateObj)) { return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat("yyyy年MM月dd日"); } // 如果日期无效或未定义,可以返回一个提示或空字符串 return "日期不可用"; }); // 添加一个用于 HTML datetime 属性的日期过滤器 eleventyConfig.addFilter("htmlDateString", (dateObj) => { if (dateObj instanceof Date && !isNaN(dateObj)) { return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-MM-dd'); } return ''; }); // 添加一个短代码,用于在模板中插入当前年份 eleventyConfig.addShortcode("year", () => `${new Date().getFullYear()}`); // 创建一个名为 "posts" 的集合,包含 posts 文件夹下所有的 Markdown 文件,并按日期降序排序 eleventyConfig.addCollection("posts", function(collectionApi) { return collectionApi.getFilteredByGlob("./posts/**/*.md").sort(function(a, b) { return b.date - a.date; // 最新的文章在前面 }); }); // Eleventy 的核心配置对象 return { // 定义 Eleventy 会处理哪些模板文件类型 templateFormats: [ "md", "njk", "html", "liquid" // Eleventy 也支持 liquid 模板 ], // 指定 Markdown 文件默认使用 Nunjucks (njk) 模板引擎进行处理 // 这允许你在 Markdown 文件中使用 Nunjucks 的特性 (如 front matter 中的变量) markdownTemplateEngine: "njk", // 指定 HTML 文件也默认使用 Nunjucks (njk) 模板引擎 // 这意味着如果你的 .html 文件中包含 Nunjucks 语法,它也会被处理 htmlTemplateEngine: "njk", // 定义输入输出目录等路径配置 dir: { input: ".", // 项目根目录作为输入目录 includes: "_includes", // 存放布局和可复用模板片段的文件夹 data: "_data", // (可选) 存放全局数据文件的文件夹 output: "_site" // 构建后的静态文件输出到 _site 文件夹 } }; };
- 文件名: index.md (博客首页)
- 内容:
--- layout: layout-base.njk title: 我的博客首页 permalink: /index.html # 或者 permalink: / eleventyNavigation: key: Home order: 1 --- # 欢迎来到我的博客 这里是最新的文章: {% if collections.posts.length > 0 %} <ul> {%- for post in collections.posts -%} <li> <h3><a href="{{ post.url | url }}">{{ post.data.title }}</a></h3> <p><time datetime="{{ post.date | htmlDateString }}">{{ post.date | readableDate }}</time></p> {% if post.data.tags and post.data.tags.length > 0 %} <p>标签: {% for tag in post.data.tags %} <span class="tag">{{ tag }}</span>{% if not loop.last %}, {% endif %} {% endfor %} </p> {% endif %} </li> {%- endfor -%} </ul> {% else %} <p>暂时还没有文章哦,敬请期待!</p> {% endif %}
-
e.文件概览:完成以上步骤,我们的网页框架就大概搭建好了。之后的网页优化另外出教程。我们需要做的就是在这个框架下,增加我们的功能。
-
概览
-
-
f. 配置 package.json 中的脚本:
- 操作:
- 打开 my-eleventy-blog/package.json 文件。
- 确保 “scripts” 部分包含(scripst内原有的内容删除):
"scripts": { "start": "eleventy --serve", "build": "eleventy" },
-
-
在本地启动开发服务器并预览
-
操作 (在 my-eleventy-blog 根目录的 Git Bash 终端中):
npm start
-
执行完该命令,我们的my-eleventy-blog下会出现"_site"文件夹。说明Eleventy已经成功运行并且将我们的代码文件打包为了静态文件。
-
效果:eleventy --serve 命令会持续运行,以便:提供一个本地 Web 服务器让你预览网站。监视文件变化并自动重新构建。
- 不要关闭这个 Git Bash 终端窗口。 让 Eleventy 继续运行。
- 打开你的网页浏览器 (Chrome, Firefox, Edge 等)。
- 在浏览器的地址栏中输入:
http://localhost:8080/
。按回车。你应该能看到你的博客首页 (由 index.md 生成)。 - 然后,在浏览器的地址栏中输入:
http://localhost:8080/posts/hello-world/
。按回车。你应该能看到你的第一篇博客文章 (由 posts/hello-world.md 生成)。
-
问题:
- 此时认真的伙伴可能有疑惑,为什么明明没有将我们的前端代码发送给我们的服务器,但是输入网址还是可以进入。
- 原因:简单说,我们现在通过 http://localhost:8080/ 访问的,是我们本地电脑上运行的一个临时 Web 服务器。localhost 是一个特殊的主机名,它总是指向我们自己的电脑 (IP 地址通常是 127.0.0.1)。8080 是这个临时服务器监听的端口号。所以,http://localhost:8080/ 意味着我们的浏览器正在请求我们自己电脑上运行的 Eleventy 开发服务器所提供的网页内容。这个网址只有我们自己能访问,其他人无法通过这个地址看到你的博客。它主要用于我们在开发过程中实时预览和调试你的网站。
-
-
更改
-
a.你以后主要修改和添加内容的文件/文件夹(你的“工作区”):
- posts/ 文件夹:
- 用途: 这里是你存放所有博客文章的地方。
- 操作: 你会在这里创建新的 .md (Markdown) 文件来写新文章,或者修改已有的 .md 文件来更新文章内容。每篇文章一个 .md 文件。
- index.md 文件 (在项目根目录,即 test1/ 下):
- 用途: 这是你博客首页的内容源文件。
- 操作: 修改这个文件来改变你博客首页上显示的内容,比如欢迎语、最新文章列表的展示方式等。
- css/style.css 文件:
- 用途: 控制你整个博客的外观和样式 (颜色、字体、布局等)。
- 操作: 修改这个文件来改变你博客的视觉效果。
- _includes/ 文件夹 (里面的 .njk 文件,如 layout-base.njk, layout-post.njk):
- 用途: 定义你博客不同类型页面的HTML结构和布局框架。比如所有页面都有的导航栏、页脚,或者文章页特有的结构。
- images/ 文件夹 (如果你创建了并使用它):
- 用途: 存放你博客中要使用的图片。
- 操作: 把图片放到这里,然后在你的 Markdown 文章或模板中引用它们。
- _data/ 文件夹 (如果你创建了并使用它,这是可选的高级用法):
- 用途: 存放一些全局数据,比如网站的配置信息、作者信息、导航链接列表等,这些数据可以在你所有的模板和页面中使用。
- posts/ 文件夹:
-
b.Eleventy(静态网站生成器-SSG)
- 你现在是否对Eleventy有了一些了解呢。
- 其实,如果不用静态网站生成器的方式,那么我们每更改一次网站内容形式,都需要手动全部重新配置。而Eleventy的作用就是让我们每次更新内容不用重新再来一遍。
3.4.5 一次性的 SSH 密钥对配置(接下来的步骤是使用SCP命令将文件传输到服务器上)
-
问题:
- 为什么要进行一次性的 SSH 密钥对配置:
- 什么是SSH密钥:
-
生成 SSH 密钥对
- 打开 Git Bash 终端。
- 执行:
ssh-keygen -t ed25519 -C "your_email@example.com" Use code with caution.
- (将 “your_email@example.com” 替换成你的邮箱作为注释)
- 按提示操作:
- 保存位置: 按回车使用默认路径 (通常是 ~/.ssh/id_ed25519)。
- 密码短语 (Passphrase): 可选,设置后之后用私钥登录要输入密码。
- 在你本地的 ~/.ssh/ 目录下生成 id_ed2551本地电脑和阿里云服务器之间安全且便捷的连接方式,避免每次 SCP/SSH 都输入密码(或只需9 (私钥) 和 id_ed25519.pub (公钥)。
-
复制公钥:
- a. 在本地 Git Bash 中显示并复制公钥:
cat ~/.ssh/id_ed25519.pub
- 完整复制输出的公钥内容。
- a. 在本地 Git Bash 中显示并复制公钥:
12.将公钥添加到阿里云服务器
-
b. 通过阿里云控制台的“远程连接”功能 (如 Workbench) 登录到你的服务器
- -
c. 创建 .ssh 目录 :
mkdir -p ~/.ssh
- 目的: 确保有一个专门存放 SSH 相关文件的目录。
-
d.设置 .ssh 目录的权限:
chmod 700 ~/.ssh
- 目的: SSH 服务对 .ssh 目录的权限有严格要求。这个目录必须只能被其所有者访问,否则 SSH 服务可能会因为安全原因拒绝使用里面的密钥。700 是最常见和推荐的权限。
-
e.创建 authorized_keys 文件 (如果它还不存在的话):
touch ~/.ssh/authorized_keys
- 目的: 确保这个关键文件存在。
-
f.设置 authorized_keys 文件的权限:
chmod 600 ~/.ssh/authorized_keys
- 目的: authorized_keys 文件同样有严格的权限要求,只能被其所有者读写。600 是推荐的权限。
-
g.使用 nano 文本编辑器打开 authorized_keys 文件进行编辑:
nano ~/.ssh/authorized_keys
- nano: 一个简单易用的命令行文本编辑器。执行后,你会进入 nano 的编辑界面。如果 authorized_keys 文件是新创建的,这个界面会是空白的(如果其中有文本,请)
- 将你本地复制的公钥内容粘贴到 nano 编辑器中:
- 保存文件并退出 nano:
- a. 按下键盘上的 Ctrl + X 组合键 (这是 nano 的退出命令)。-> 输入 Y -> 按回车键 (Enter) 确认。
-
k.在本地 Git Bash 中测试 SSH 密钥对连接:
ssh root@47.93.190.56
- (将 47.93.190.56 替换成你的服务器 IP)
- 预期: 如果配置正确,应能成功登录(可能提示输入私钥密码短语),不再要求输入服务器密码。登录成功后可输入 exit 退出。
3.4.6 部署构建好的静态文件到阿里云服务器 (在你本地 Git Bash 中完成)
-
注意⭐️:之后每次更新前端信息到服务器,都需要进行3.4.6这一步。
-
l.前提:
- SSH 密钥对) 已成功配置。
- 本地 Eleventy 项目 (D:\0.myblog\my-eleventy-blog) 已准备好
-
m.在本地构建生产版本的静态文件:
cd /d/0.myblog/my-eleventy-blog # 导航到目标文件夹 npm run build # 构建前端静态文件
-
n。(推荐) 通过 SSH 清理服务器上旧的网站文件(如果你的服务器之前传输过静态文件):
-
在当前本地 Git Bash 终端中执行:
-
a. 登录服务器:
ssh root@47.93.190.56
- (如果你的私钥设置了密码短语,此时会提示你输入。)
-
b. 登录成功后,我们现在已经在Git Bash命令行中登录并操控了我们的服务器的终端。执行清理目录命令:
rm -rf /var/www/myblog/*
- (请再次务必确认路径 /var/www/myblog/ 正确无误!这个操作会删除该目录下的所有内容。)
-
c. 清理完成后,退出服务器的 SSH 会话,返回到你本地的 Git Bash 提示符:
exit
-
-
o.在Git Bash命令行,通过SCP将静态文件上传到服务器
scp -r /d/0.myblog/my-eleventy-blog/_site/* root@47.93.190.56:/var/www/myblog/
3.5 阶段四:配置 Nginx 托管你的博客并最终验证
3.5.1 配置Nginx
- 创建新的 Nginx 站点配置文件: (告诉 Nginx 如何展示你的博客)
nano /etc/nginx/sites-available/myblog
- 解释: nano 是一个文本编辑器,这个命令会用 nano 打开(如果文件不存在则创建)/etc/nginx/sites-available/myblog 这个文件。
- 在打开的
nano
编辑器中,粘贴以下配置内容:
- 执行上一条命令后,你会进入 nano 编辑器界面。它是一个空白的文档,请将以下配置内容完整地复制,然后粘贴到 nano 编辑器中。
server { listen 80; listen [::]:80; server_name _; # 或你的IP,或后续你的域名 root /var/www/myblog; # 指向你的博客文件目录 index index.html index.htm; # 默认首页文件 location / { try_files $uri $uri/ =404; } }
- 保存并退出
nano
:Ctrl + X
->Y
->Enter
。
- 保存并退出
-
创建软链接以启用站点配置: (让 Nginx “看到”这个新配置)
ln -s /etc/nginx/sites-available/myblog /etc/nginx/sites-enabled/
- 保存并退出 nano 编辑器:
- 按下 Ctrl + X (表示退出)。
- nano 会在底部询问你 “Save modified buffer?” (是否保存修改?),输入 Y (表示 Yes)。
然后它会问你 “File Name to Write: /etc/nginx/sites-available/myblog” (要写入的文件名),直接按 回车键 (Enter) 确认即可。
- 保存并退出 nano 编辑器:
-
(可选) 移除默认的 Nginx 配置链接: (避免冲突)
rm /etc/nginx/sites-enabled/default
- (如果报错 “No such file or directory”,忽略即可)
- Nginx 不会直接加载 sites-available 目录下的所有配置。它只加载 sites-enabled 目录中存在的配置。我们需要在 sites-enabled 目录中创建一个指向我们刚刚创建的配置文件的“快捷方式”(软链接)
3.5.2.测试验证Nginx
-
测试 Nginx 配置语法: (检查配置写得对不对)
nginx -t
- 预期看到:“syntax is ok” 和 “test is successful”。
-
重新加载 Nginx 使配置生效: (让 Nginx 应用新配置)
systemctl reload nginx
- 解释: reload 会平滑地重新加载配置,而不会中断正在处理的连接(比 restart 更优雅)。
- 预期行为: 这个命令通常执行后没有输出,直接返回命令提示符。
-
最终验证!访问你的博客!
- 现在,Nginx 应该已经配置为使用你的博客文件了。
- 请再次打开你本地电脑的浏览器,在地址栏中输入你的服务器公网 IP 地址:
- http://<你的服务器公网IP地址>
- 预期结果:你应该不再看到 “Welcome to nginx!” 的页面了,而是看到你自己博客的 index.html 页面的内容!
-
初步效果
3.6 阶段五:配置域名并启用 HTTPS (安全访问)
3.6.1 知识点
-
问题1: 域名是什么,有什么用?
- 如果刚刚进行了3.3第8步,你会发现我们的网址是 http://47.93.190.56的形式。
- 特点:
- 方便记忆:简单说,因为我们的47.93.190.56不好记忆,所以我们需要创建我们自己的域名。有域名后,我们就可以通过输入如:https://yangjiayu.cn,来访问我们的网址。
- 品牌化和专业性: 拥有自己的域名可以让你的网站看起来更专业,有助于建立品牌形象。
- 指向服务器: 域名的核心作用是通过 DNS (Domain Name System) 系统,将这个易于记忆的域名“翻译”或“指向”到托管你网站的服务器的实际 IP 地址。当用户在浏览器输入你的域名时,DNS 系统会告诉浏览器你的服务器在哪里,浏览器才能向正确的服务器发送请求。
- 稳定性: 如果你将来更换了服务器(意味着 IP 地址可能会改变),你只需要在 DNS 设置中更新域名指向的 IP 地址即可,而访问者仍然使用同一个域名访问你的网站,不会受到影响。
启用 HTTPS 的前提: 正如我们接下来要做的,SSL/TLS 证书(用于启用 HTTPS)是颁发给特定域名的。你不能直接为 IP 地址申请常规的公开 SSL 证书。
-
问题2:为什么我们刚刚建立的网址是http//公网,显示不安全;而其他网址https//,没有不安全显示
- 简单说就是,http没有加密,所以网站和用户信息可能有被他人截获的风险。而https 就是 HTTP + SSL/TLS 加密,它确保你和网站服务器之间传输的数据是加密的,即使被截获,黑客也无法轻易解读内容。
- 而我们接下来的第五阶段就是让http变为https。
-
问题3:关于备案,为什么需要备案,只有搭建在中国的服务器才需要备案吗。
- ICP 备案是中国大陆的一项法规,由中华人民共和国工业和信息化部(简称“工信部”)规定和管理。
- 主要目的:
- 规范互联网信息服务活动,加强网络信息安全管理。
- 确认网站主办者的身份和责任,以便在网站出现违法违规内容时能够追溯到负责人。
- 维护网络秩序,防止网络犯罪。
- 而关于是否需要备案的问题,如果我们服务器的物理地址是中国大陆,并且你希望使用域名从中国大陆访问这个服务器上的网站,那么你的域名必须进行 ICP 备案。
- 注意:不同域名价格不同,然后备案因为需要工信部审核,所以备案完成需要大概4-7天的时间。
- 影响:
- 未备案: 如果服务器在大陆,域名未备案,直接解析使用可能会被服务商或监管部门阻断访问,或者强制跳转到备案提示页面。
- 已备案: 备案成功后,你会获得一个备案号(例如 京ICP备xxxxxxxx号-x),通常需要在网站底部显示。你的域名就可以正常解析并指向大陆服务器提供服务了。
-
总结⭐️
- 我们将网页和域名联系起来,之后我们可以通过输入域名“tarak.cn”来访问网页
- 服务器就相当于电脑,我们可以在服务器上运行多个网页,之后我们会将子域名“bolg.tatak.cn”与不同网页关联而达到一台服务器上访问不同网站的目的
- 购买一个域名后,可以拥有多个自定义的子域名,如主域名为“tarakcn”,而子域名可以是“blog.tarat.cn”或“www.tarak.cn”等
- 备案是中国大陆行政要求;HTTPS是一种安全传输协议,需要为域名配置SSL/TLS证书才可以;如果我们服务器在国内,如果没有备案信息,申请SSL/TLS 证书时有失败风险。
- 一个备案主体可以绑定多个主域名,主域名完成绑定后,其子域一般名会继承主域名的备案信息,所以备案只需要为主域名备案就可以。
3.6.2 购买域名并备案
- 域名购买:
- 阿里云官网
- 步骤:官网 -> 上面一栏的“产品” -> 左面点击 “域名与网站” -> 点击域名 -> 购买(一般.top的后缀比较便宜,.cn是中国大陆标志,.com是国际标志)
- 备案:
- 备案的话,阿里云首页,右上角就有备案。
- 备案有点繁琐,但是按要求填写就可以。一般会收到阿里云电话认证,之后就是交给工信部审核。总体下来要7天左右。
- 因为的备案还在审核中,等审核通过了再来更新接下来的内容吧。
3.6.3 配置 DNS 解析
-
作用: DNS 解析的核心作用是将你容易记住的域名 (如 tarak.cn) “翻译”或“映射”到你服务器的实际数字 IP 地址 (如 47.93.190.56)。当用户在浏览器输入你的域名时,浏览器会向 DNS 服务器查询这个域名对应的 IP 地址,然后才能向正确的服务器发送请求以获取网页内容。没有正确的 DNS 解析,你的域名就无法指向你的服务器,用户也就无法通过域名访问你的博客。
-
a.进入阿里云控制台 -> 云解析 -> 解析设置 -> 添加记录
-
b. 添加记录
- 分别添加两个记录,主机记录中,@是主域名;bolg是子域名。解析完成后,我们可以通过blog.tarak.cn来访问我们的博客网页。
-
c.检查是否解析成功
- 打开Git Bash,输入
ping tarat.cn
,ping blog.tarak.cn
。 - 如果看到以下输出,则说明我们的域名已经生效(一般要一到十分钟左右)
-
Pinging tarak.cn [47.93.190.56] with 32 bytes of data: Reply from 47.93.190.56: bytes=32 time=XXms TTL=YY Reply from 47.93.190.56: bytes=32 time=XXms TTL=YY Reply from 47.93.190.56: bytes=32 time=XXms TTL=YY Reply from 47.93.190.56: bytes=32 time=XXms TTL=YY Ping statistics for 47.93.190.56: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = XXms, Maximum = XXms, Average = XXms
- 打开Git Bash,输入
-
d.测试
- 现在我们就可以通过域名来访问我们的网页啦,浏览器直接输入
blog.tarak.cn
。 - 当然,如果域名还没有完成备案,一会就会被禁用啦
- 现在我们就可以通过域名来访问我们的网页啦,浏览器直接输入
3.6.3 备案成功🚩
- 历时七点,终是备案成功了,那还是一个平平无奇的早上。。。
- 此时我再输入自己的域名时,已经不是“域名无法访问的提升了”而是一团小云朵,下面提示“无法访问此页面”🥲🥲🥲
- 好吧,这其实是正常现象啦。
- 因为一旦域名备案成功,国内很多浏览器本身倾向尝试HTTPS(相信你已经注意到我们备案成功后输入域名,前缀已经从http变为了https)
- 但是如果我们的服务器还没有为这些域名正确配置HTTPS,那么当请求通过HTTPS (443端口) 进来时,服务器不知道如何处理,就会导致连接失败或关闭。
- 我们之前用的Nginx配置主要监听80端口(HTTP),接下来我们需要让服务器可以处理443端口(HTTPS)的请求,并且需要 SSL 证书来加密通信。
3.6.4 确保服务器防火墙/安全组允许 443 端口
HTTPS 通信使用 443 端口,我们需要确保服务器允许外部通过这个端口访问。
-
阿里云安全组:
- 登录阿里云控制台。
- 找到你的 ECS 实例。
- 进入安全组配置。
- 检查入方向规则,确保有一条规则允许 TCP 协议的 443 端口的流量。源地址可以设置0.0.0.0/0。
-
服务器内部防火墙 (ufw) - 如果启用的话:
- 远程连接服务器,查看是否开启防火墙:
-
sudo ufw reload sudo ufw status
- 如果有以下输出,则说明我们服务器上的ufw是未激活状态,就是没有防火墙,不用再进行其他额外设置了。
-
Firewall not enabled (skipping reload) Status: inactive
3.6.5 安装 Certbot 及其 Nginx 插件
- Certbot 是我们用来从 Let’s Encrypt 获取免费 SSL 证书并自动配置 Nginx 的工具。我们将使用 snap 来安装 Certbot,以确保是最新版本。
-
首先,确保 snapd 已安装并是最新状态 (很多现代 Ubuntu 系统默认已安装 snapd):
sudo apt update # 更新你的包列表 sudo apt install snapd # 安装 snapd(如果尚未安装) sudo snap install core # install、refresh:安装/更新 snap 的核心组件 sudo snap refresh core
-
(可选,但推荐)如果之前通过 apt 安装过旧版本的 Certbot,先将其卸载,以避免冲突:
sudo apt-get remove certbot
- 如果这条命令提示 “Package ‘certbot’ is not installed”,那说明没有旧版本,可以忽略这条。
-
通过 snap 安装 Certbot:
sudo snap install --classic certbot
- –classic 参数允许 snap 包像传统软件包一样访问系统
-
创建一个符号链接,以便你可以直接从任何路径运行 certbot 命令:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
- 这条命令使得在 /usr/bin/ 目录下创建一个指向 snap 安装的 certbot 的链接。
-
安装 Certbot 的 Nginx 插件 (通过 apt):
sudo apt install python3-certbot-nginx
- 这个插件帮助 Certbot 理解和修改 Nginx 的配置文件。
3.6.6 检查并确认 Nginx 博客配置文件中的 server_name
-
打开你的 Nginx 博客配置文件进行检查/编辑。我们之前的文件路径是
/etc/nginx/sites-available/myblog
sudo nano /etc/nginx/sites-available/myblog
-
找到 server_name 这一行,并仔细检查
- 确保它包含了你希望通过 HTTPS 访问博客的所有域名:tarak.cn,www.tarak.cn,以及 blog.tarak.cn。它们应该用空格隔开。
它应该看起来像这样:(修改后,请保存并退出 nano 编辑器 (Ctrl+X, Y, Enter)。)
server { listen 80; # listen [::]:80; # 如果你的服务器启用了IPv6并且DNS也解析了AAAA记录 server_name tarak.cn www.tarak.cn blog.tarak.cn; # <--- 关键行⭐️! root /var/www/myblog; # 你的博客文件根目录 index index.html index.htm; # 默认首页文件 location / { try_files $uri $uri/ =404; } # 你可能还有其他的配置,比如日志路径等 # access_log /var/log/nginx/tarak.cn.access.log; # error_log /var/log/nginx/tarak.cn.error.log; }
- 注意⚠️:这里可能有伙伴没有配置www.子域名(完全按照我们之前的步骤),因为配置www.子域名是非常普遍的一种做法,所以我们需要再次配置www.子域名。
- 这里的操作请看3.6.3
- 具体配置如下
- 确保它包含了你希望通过 HTTPS 访问博客的所有域名:tarak.cn,www.tarak.cn,以及 blog.tarak.cn。它们应该用空格隔开。
-
测试 Nginx 配置是否有语法错误:
sudo nginx -t
- 如果有
is ok
或is successful
这样的输出,表明语法没有问题。 - 如果有错误,请根据错误提醒修改该文件内容
- 如果有
-
如果 Nginx 配置测试成功,并且你刚才对文件进行了修改,请重载 Nginx 服务以使更改生效:
sudo systemctl reload nginx
3.6.7 使用 Certbot 申请 SSL 证书并自动配置 Nginx
- Certbot 会与 Let’s Encrypt 通信,验证你对这些域名的所有权,下载证书,并自动修改你的 Nginx 配置以启用 HTTPS。
-
执行 Certbot 命令:
- 请确保命令中的域名与你 Nginx 配置中 server_name 以及你希望启用 HTTPS 的域名完全一致
sudo certbot --nginx -d tarak.cn -d www.tarak.cn -d blog.tarak.cn
- sudo certbot: 以 root 权限运行 certbot。
- –nginx: 告诉 Certbot 使用 Nginx 插件,它会自动检测并修改你的 Nginx 配置。
- -d tarak.cn -d www.tarak.cn -d blog.tarak.cn: 指定要为其申请证书的域名。
-
Certbot 的交互式提问过程:
- Certbot 接下来会问你几个问题:
- 输入你的常用邮箱:你的电子邮箱
- 是否同意服务条款:y
- 是否愿意分享邮箱给EFF:y
- Certbot 接下来会问你几个问题:
-
域名验证和证书获取:
- 回答完问题,Certbot 会开始工作。你将会看到类似祝贺信息
Congratulations! You have successfully enabled HTTPS on https://tarak.cn, https://www.tarak.cn, and https://blog.tarak.cn
- 🎇:恭喜,到了这一步,我们就可以通过域名来正常访问我们的网站啦!现在请你输入你的域名:blog.tarak.cn,可以看到我们进入到了自己的个人博客网页!
3.7 总结
- 至此,我们的个人博客后端就已经全部搭建完成。
- 整体搭建过程我们多用Liux命令行进行操作,想必看到这里的伙伴们已经对liux命令有了一些基础的认识,这对于我们学习liux系统有很大的帮助。
- 同时,我们也通过亲自操作,了解了搭建静态网站的基本流程,并且在此期间了解了静态、动态网页;前端、后端;服务器、域名、备案等概念,想必已是收获满满啦☀️!
- 最后,静态网页搭建后端部分告一段落(之后可能会修改吧),然后基于Eleventy框架的前端网页构建,已经出了一篇文章,后续还会再更新。其次动态网页的教程近期也会更新(因为最近有作业和比赛,所以有点忙~)。
- 再说一点,对于物联网的伙伴来说,了解前后端知识这一步可以说是我们必不可少的一步了。因为嵌入式方面主要是硬件,而高级的硬件设备都会将一些数据传输到云端(网页或小程序或app),同时我们可以将大语言模型接入我们的网页或小程序来对我们硬件设备的信息进行分析操作等(动态网页可以实现,或者小程序)。这就实现了设备的全栈开发,结合了物联网+人工智能的应用(后续会出这方面的教程)。
—— 记录我的成长
—— 25-05-28