本文记录了在 1Panel 环境下,使用 Docker 容器部署 Astro 的 astro-theme-pure 主题的全过程。
全程可视化操作,少量命令,部署完后添加1panel的计划任务,自动构建发布文章,
适用于只会html,而且还不会docker的小白,对,就是我,我也不会
纯记录,下次安装就会忘了踩过的坑,忘了怎么装,会的大佬不用看了。
目录#
- 环境准备
- 创建静态网站与上传源码
- 创建 Node 运行环境容器
- 安装依赖
- 修改构建配置为静态模式
- 修复远程头像域名问题
- 构建项目
- 修改网站运行目录为 dist
- 配置 HTTPS(如果在第一步未完成)
- 后续更新流程
- (可选)本地开发调试
- 常见问题
环境准备#
- 已安装 1Panel 的 Linux 服务器。
- 域名解析:建议提前在域名服务商处将
你的域名.com和www.你的域名.com解析到你的服务器 IP。 - 已在 1Panel“应用商店”中安装并启动 OpenResty。已将主题源码下载到本地,当然,也可以直接克隆到你的服务器上。
创建静态网站与上传源码#
-
打开 1Panel 左侧菜单 → “网站” → “创建网站”。
-
选择 “静态网站”。
-
填写信息:
- 域名配置:
- 在“域名”一栏,点击 “批量编辑” 按钮。
- 在弹出的文本框中输入两个域名(顺序不限):
你的域名.comwww.你的域名.com - 注意:1Panel 会根据你输入的第一个域名自动生成项目目录。
- 如果
你的域名.com在第一行,目录为/opt/1panel/www/sites/你的域名.com/index。 - 如果
www.你的域名.com在第一行,目录为/opt/1panel/www/sites/www.你的域名.com/index。 - 顺序均可,请记下页面下方显示的“根目录”路径,后续步骤需保持一致。
- 如果
- 备注:如“Astro Blog”。
- 根目录:保持默认(1Panel 会根据第一个域名自动填入),请记下此路径。
- 启用 HTTPS(可选但推荐):
- 如果你的域名已解析生效,且服务器开放了 80/443 端口,你可以直接勾选此项,并选择“Let’s Encrypt”来自动申请证书。
- 如果你已有证书(如购买的证书),可勾选后选择“已有证书”并上传。
- 注:如果暂时不确定,可以不勾选,等待网站创建完成后,在“网站设置”中再申请也可以。
- 域名配置:
-
点击“确认”。
-
打开“网站”列表,找到刚创建的网站,点击“网站目录”下的文件夹图标,进入
index目录。 -
在“文件”界面:
- 点击“上传”,将主题源码压缩包上传到
index目录。 - 选中压缩包,点击“解压”。
- 确保解压后的项目文件直接位于
index目录下(能直接看到package.json、astro.config.ts等)。
- 点击“上传”,将主题源码压缩包上传到
创建 Node 运行环境容器#
使用官方 Node 镜像作为构建环境,并设置启动命令让容器保持常驻。
- 打开 1Panel 左侧菜单 → “网站” → “运行环境”。
- 选择 “Node” → “创建运行环境”。
- 填写配置:
- 环境名称:自定义,如
astro-node。 - Node 版本:选择最新 LTS(如 22)。
- 项目目录:填写你在上一步“创建静态网站”时看到的根目录路径。
- 例如:
/opt/1panel/www/sites/你的域名.com/index(或其他实际生成的路径)。 - 关键点:此处必须与静态网站的实际代码目录完全一致,否则容器无法读取源码。
- 例如:
- 端口映射:填写
4321:4321(用于开发调试,生产环境构建不需要)。 - 启动命令(关键步骤):
- 选择“自定义启动命令”。
- 填入:
tail -f /dev/null - 解释:Astro 是静态构建,不需要常驻的 Node 服务。如果选择默认的
npm start等命令,容器启动后会找不到服务入口并自动退出,导致你无法进入终端敲命令。tail -f /dev/null是一个“占位”命令,能让容器保持**一直运行(Running)**的状态,这样你随时都可以通过 1Panel 进入容器终端去执行npm run build。此命令资源占用极低,不会影响服务器性能。
- 环境名称:自定义,如
- 点击“确认”,等待容器创建并启动。
- 确认容器状态为“运行中”。
安装依赖#
为了保证在不同服务器架构下(如从 Mac 到 Linux)的兼容性,建议进行全新安装(也可直接安装)。
- 打开 1Panel 左侧菜单 → “容器”。
- 在容器列表中找到刚创建的 Node 环境容器,点击右侧 “终端”。
- 确认目录:进入终端后,通常会自动处于
/app目录。你可以输入pwd确认。如果不在,请执行cd /app。 - 依次执行以下命令:
rm -rf node_modules package-lock.json
npm installbash直接安装可不执行:rm -rf node_modules
解释:删除旧依赖(可能包含不兼容的二进制文件),然后在当前容器环境中重新编译安装。
💡 提示:为什么要删除
package-lock.json?package-lock.json记录了本地环境的精确依赖版本。在 Docker 容器中直接复用本地锁文件可能会导致二进制文件(如 Sharp)因系统架构不同(如 Mac vs Linux)而加载失败。删除它会强制 npm 根据package.json在当前容器环境中重新生成锁文件,确保兼容性。
-
安装成功的标志: 执行完毕后,如果看到类似以下输出(包含
added ... packages和audited ... packages),即表示安装成功:added 685 packages, and audited 686 packages in 4m 283 packages are looking for funding run npm fund for details 6 vulnerabilities (2 low, 4 high)
注意:提示中出现的
vulnerabilities(安全漏洞)是 npm 的安全审计警告。在开发/构建阶段,这些通常不会导致构建失败,建议忽略即可,不影响后续操作。
修改构建配置为静态模式#
默认 astro-theme-pure 为 Server 模式(SSR),需要改为 Static 模式。
- 在 1Panel 左侧菜单打开 “文件”。
- 进入你的项目目录(例如
/opt/1panel/www/sites/你的域名.com/index/)。 - 找到
astro.config.ts,点击右侧 “编辑”。 - 在编辑器中进行如下修改:
- 将
site改为你的主域名(建议使用不带 www 的版本作为规范域名),例如:
site: ‘https://timingme.com’, - 将
output: 'server'改为:output: 'static', - 删除以下整行(Static 模式不需要适配器):
adapter: vercel({ imageService: true }), - 同时删除顶部的导入语句(如果不再需要):
import vercel from ‘@astrojs/vercel’
- 将
- 点击“保存”。
远程头像域名#
确认为 cravatar.cn 而不是 www.gravatar.com。
如不是请修改,或自行替换为其他头像源
方法一:使用 1Panel 可视化编辑(推荐)
- 在 1Panel“文件”中,进入项目目录下的
public/文件夹。 - 找到
links.json,点击“编辑”。 - 使用编辑器的“查找/替换”功能:
- 查找:
cravatar.com - 替换为:
www.gravatar.cn
- 查找:
- 保存文件。
方法二:使用命令行快速替换(可选)
- 进入 Node 容器的“终端”。
- 执行以下命令即可批量替换:
bashsed -i ‘s/cravatar.com/www.gravatar.cn/g’ /app/public/links.json
构建项目#
- 回到 1Panel“容器”页面,进入 Node 容器的“终端”。
- 确保当前目录为
/app(通常默认就是),然后执行:
bashnpm run build
情况 A:构建成功#
如果看到末尾提示 [build] Complete!,说明一切顺利,请跳至下一步 修改网站运行目录为 dist。
情况 B:构建报错 MissingSharp#
如果构建过程中报错 MissingSharp: Could not find Sharp,这是图片处理库兼容性问题。请按以下步骤修复:
1. 为什么会报错?#
- Sharp 是什么:Sharp 是 Node.js 中最快、最高性能的图片处理库,用于在构建时自动压缩、转换图片格式(如转 WebP)并调整尺寸,以提升网站加载速度。
- 报错原因:Docker 容器环境有时无法正确加载 Sharp 的预编译二进制文件(可能是因为系统架构差异或库版本过新),导致构建失败。
2. 解决方法:安装稳定版 Sharp#
请在容器终端中执行以下命令,安装兼容性最好的 0.32.6 版本:
npm install --save sharp@0.32.6bash3. 验证安装#
执行完命令后,如果看到 added 56 packages, changed 1 package,说明安装成功。可以执行以下命令静默验证(无输出即成功):
node -e “require(‘sharp’)”bash4. 重新构建#
安装成功后,再次执行构建命令:
npm run buildbash此时应该能看到 generating optimized images 的日志,并显示图片压缩比例(例如 before: 253kB, after: 14kB),最后提示 [build] Complete!。
修改网站运行目录为 dist#
让静态网站真正指向构建好的 dist 目录。
- 打开 1Panel 左侧菜单 → “网站”。
- 在网站列表中,找到你创建的静态网站,点击 “设置”。
- 切换到 “网站目录” 标签页。
- 在 “运行目录” 处,从下拉列表选择或手动输入:
/dist
- 点击“保存”或“保存并重载”。
现在,访问你的域名将看到 Astro 构建后的静态网站内容,且头像应正常显示。
配置 HTTPS(如果在第一步未完成)#
如果你在第一步创建网站时没有勾选“启用 HTTPS”,可以在这里补充配置。
- 在网站“设置”→ “HTTPS” 页面。
- 选择 “申请 Let’s Encrypt 证书”。
- 建议开启 “HTTP 自动跳转到 HTTPS”。
后续更新流程#
发布新文章或修改配置时,只需重复以下步骤:
-
在 1Panel“文件”中,将 Markdown 文件上传到
content/blog目录,或修改src/site.config.ts等配置。 -
进入 Node 容器“终端”,执行:
bashnpm run build -
静态网站指向的是
dist目录,构建完成后刷新浏览器即可看到更新内容。
(可选)本地开发调试#
如果你希望在开发时实时预览,可以使用映射的 4321 端口进行调试。请注意:本步骤依赖已安装的依赖(node_modules),在执行前请确保已按照“安装依赖”章节完成安装,否则会提示 astro: not found。
本地开发调试的用途与定位#
- 用途:用于开发过程中快速看到修改效果,支持文件变化时自动刷新页面(热重载),便于调试布局、样式与交互。不应用于对外提供访问服务。
- 与生产部署的区别:
- 本地调试执行
npm run dev,启动的是 Astro 的开发服务器,仅用于开发与预览,不适合长期或对外运行;Astro 官方明确说明开发服务器仅用于本地开发。 - 生产部署执行
npm run build,生成优化的静态文件到dist目录,再由 OpenResty 对外提供服务。这是线上正式访问的方式。
- 本地调试执行
操作步骤#
-
进入 Node 容器的“终端”。
-
执行启动命令:
bashnpm run dev -
你会看到类似
Local: http://localhost:4321/的提示。 -
在浏览器中访问
http://你的服务器IP:4321,即可看到实时预览效果。
注意:开发服务器仅供临时调试使用,生产环境请始终使用 npm run build + 静态站点的方式对外提供服务。
计划任务#
设置计划任务会自动监测blog目录的文章变化,你所写的md格式文章都要放在这里,构建生成纯静态文章显示在你的博客前台。有变动就触发构建命令发布文章,所以,你想发布或修改文章后还要敲一遍命令才能发布成功吗???反正我不想。
添加shell计划命令,把下面代码贴进去,自动检测时间设置为5分钟,ai推荐的5分钟,咱也不知道合不合理,但我改成了10分钟,反正平时发文章后也不急着看到效果,因为你在编辑markdown文章时已经预见或已经看到了效果,这里只负责构建。如果真急的话,5分钟你也嫌长。真急的话,计划任务能手动点执行,立刻就能看到效果。
注意:
1.只有当blog目录下的文件有变动,这个计划任务命令才会触发构建,这个目录以外的任何文件有变动就不能执行了,手动也不行!
2.下面代码配置的路径和域名记得修改,人和人是不一样的,所以人和人的网站路径和域名也不一定一样的:
#!/bin/bash
set -e
# ===== 配置区域 =====
CONTAINER_NAME="astro"
# 宿主机上的项目根目录
PROJECT_DIR="/opt/1panel/www/sites/你的域名.com/index"
# 监控的博客文章目录
WATCH_DIR="$PROJECT_DIR/src/content/blog"
# 日志文件
LOG_FILE="/tmp/astro-build.log"
# 时间戳文件
STAMP_FILE="/tmp/astro-blog-stamp"
# 锁文件 (防止并发构建)
LOCK_FILE="/tmp/astro-build.lock"
# =====================
# 0. 清理函数
cleanup() {
rm -f "$LOCK_FILE"
}
trap cleanup EXIT
# 1. 检查锁文件
if [ -f "$LOCK_FILE" ]; then
echo "$(date) 检测到已有构建任务在运行,跳过本次执行。" >> "$LOG_FILE"
exit 0
fi
touch "$LOCK_FILE"
# 初始化时间戳文件
[ -f "$STAMP_FILE" ] || touch "$STAMP_FILE"
# 2. 【重点修改】检查是否有文件更新 (包含图片)
NEW_FILE=$(find "$WATCH_DIR" -type f \
\( -name '*.md' -o -name '*.mdx' \
-o -name '*.jpg' -o -name '*.jpeg' \
-o -name '*.png' -o -name '*.gif' \
-o -name '*.webp' -o -name '*.svg' \
-o -name '*.avif' \) \
-newer "$STAMP_FILE" 2>/dev/null | head -1)
if [ -z "$NEW_FILE" ]; then
# 这一步就是刚才导致“秒成功”但没有变化的原因
exit 0
fi
echo "$(date) =============================" >> "$LOG_FILE"
echo "$(date) 检测到新文件: $NEW_FILE,开始在容器内构建..." >> "$LOG_FILE"
# 3. 备份旧的 dist 目录
BACKUP_DIR="$PROJECT_DIR/dist_backup"
rm -rf "$BACKUP_DIR"
if [ -d "$PROJECT_DIR/dist" ]; then
cp -r "$PROJECT_DIR/dist" "$BACKUP_DIR"
echo "$(date) 已备份旧版本" >> "$LOG_FILE"
fi
# 4. 执行构建
docker exec "$CONTAINER_NAME" sh -c "cd /app && npm run build" >> "$LOG_FILE" 2>&1
# 5. 检查结果
if [ $? -eq 0 ]; then
echo "$(date) ✅ 构建成功!" >> "$LOG_FILE"
touch "$STAMP_FILE"
rm -rf "$BACKUP_DIR"
echo "$(date) 流程结束。" >> "$LOG_FILE"
else
echo "$(date) ❌ 构建失败!正在回滚..." >> "$LOG_FILE"
if [ -d "$BACKUP_DIR" ]; then
rm -rf "$PROJECT_DIR/dist"
mv "$BACKUP_DIR" "$PROJECT_DIR/dist"
echo "$(date) ✅ 已回滚。" >> "$LOG_FILE"
fi
touch "$STAMP_FILE"
exit 1
fi
bash
常见问题#
Q1: 构建时报错 Failed to load remote image ... The request was redirected.#
A: 某些远程图片在构建时发生重定向,Astro 的图片优化无法跟随。解决:参考教程 修复远程头像域名问题 章节进行替换。
Q2: 构建成功,但访问网站白屏或样式丢失。#
A:
- 检查
astro.config.ts中site是否填写正确。 - 检查“网站目录 → 运行目录”是否设置为
/dist。 - 确认
dist下是否包含_astro等资源目录。
Q3: Node 容器里 npm install 报错。#
A: 建议在容器内执行 rm -rf node_modules 彻底清理旧依赖后,再执行 npm install。
Q4: 创建 Node 容器后,状态一直显示“已停止”或“重启中”。#
A: 这是启动命令配置错误导致的。请检查容器配置,确保勾选了“自定义启动命令”并填写了 tail -f /dev/null。
Q5: 容器一直运行会不会占用很多资源?#
A: 不会。tail -f /dev/null 命令仅仅维持一个空闲进程,几乎不占用 CPU 和内存,且数据盘已经映射到宿主机,对磁盘占用也无额外消耗。
Q6: 在容器终端执行 npm run dev 提示 astro: not found?#
A: 这表示依赖未安装或被删除。请在容器终端中先执行 npm install,然后再运行 npm run dev。
Q7: 构建时提示 MissingSharp: Could not find Sharp?#
A: 这是因为缺少图片处理库。请参考教程 构建项目 章节中的“情况 B”部分,执行 npm install --save sharp@0.32.6 即可解决。
本教程已根据实际部署与优化,配置修改采用 1Panel 可视化完成,命令行仅用于构建与替换操作。