使用 MongoDB Atlas 的云端服务替代本地 MongoDB 部署是一个方便且高效的选择,特别适合云端项目。以下是如何在当前项目中集成 MongoDB Atlas 的具体步骤。
步骤 1:创建 MongoDB Atlas 集群
-
注册 MongoDB Atlas:
- 前往 MongoDB Atlas 注册账号。
- 登录后,点击 “Build a Database” 创建一个新集群。
-
选择集群配置:
- 选择免费层(M0 Shared Cluster)或付费层。
- 选择集群位置(建议选择离服务器最近的地区)。
-
创建数据库用户:
- 在 Security > Database Access 中,点击 “Add New Database User”。
- 设置用户名和密码(如
astro-user
和astro-password
)。 - 分配权限为 “Read and Write to Any Database”。
-
允许 IP 访问:
- 在 Security > Network Access 中,点击 “Add IP Address”。
- 选择 “Allow Access from Anywhere”(仅限开发阶段),或添加特定服务器的 IP。
-
获取连接字符串:
- 在集群页面,点击 “Connect” > “Drivers”,复制连接字符串,例如:
mongodb+srv://astro-user:[email protected]/blog?retryWrites=true&w=majority
- 在集群页面,点击 “Connect” > “Drivers”,复制连接字符串,例如:
步骤 2:修改 docker-compose.yaml
将 MongoDB Atlas 的连接字符串集成到 astro
服务的环境变量中:
修改 docker-compose.yaml
services:
astro:
build:
context: ./astro
container_name: astro
ports:
- "9090:3000"
environment:
MONGO_URI: mongodb+srv://astro-user:[email protected]/blog?retryWrites=true&w=majority
env_file:
- ./astro/.env
command: npm start
步骤 3:Astro 项目中集成 MongoDB Atlas
在 Astro 项目中,使用连接字符串连接到 MongoDB Atlas。
示例:获取博客文章
在 src/pages/blog/index.astro
中:
---
import { MongoClient } from "mongodb";
const uri = import.meta.env.MONGO_URI; // 从环境变量获取 MongoDB URI
const client = new MongoClient(uri);
await client.connect();
const db = client.db("blog"); // 使用数据库名称
const posts = await db.collection("posts").find({}).toArray();
---
<html>
<body>
<h1>博客文章列表</h1>
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post._id}`}>{post.title}</a>
<p>{post.content.slice(0, 100)}...</p>
</li>
))}
</ul>
</body>
</html>
步骤 4:隐藏敏感信息
将敏感信息(如连接字符串)存储在 .env
文件中,确保不会直接写入代码。
创建 .env
文件
在 astro
目录下创建 .env
:
MONGO_URI=mongodb+srv://astro-user:[email protected]/blog?retryWrites=true&w=majority
S3_ENDPOINT=http://*****
S3_BUCKET=astro
S3_ACCESS_KEY=*****
S3_SECRET_KEY=*****
修改 docker-compose.yaml
将环境变量文件加载到 astro
服务中:
services:
astro:
build:
context: ./astro
container_name: astro
ports:
- "9090:3000"
env_file:
- ./astro/.env
command: npm start
步骤 5:从 WordPress 导入文章和图片
为了将 WordPress 的文章和图片导入 MongoDB,可以使用 WordPress 的导出工具生成 XML 文件,然后编写脚本解析并导入。
1. 导出 WordPress 数据
在 WordPress 管理后台:
- 转到 工具 > 导出。
- 选择 所有内容,生成一个 XML 文件并下载。
2. 编写导入脚本
创建一个 Node.js 脚本解析 WordPress 的 XML 并导入到 MongoDB,同时将图片上传到 MinIO。
在 astro/scripts/importWordPress.js
:
import { MongoClient } from "mongodb";
import fs from "fs";
import { parseStringPromise } from "xml2js";
import AWS from "aws-sdk";
const MONGO_URI = process.env.MONGO_URI || "mongodb+srv://astro-user:[email protected]/blog?retryWrites=true&w=majority";
const S3_ENDPOINT = process.env.S3_ENDPOINT;
const S3_BUCKET = process.env.S3_BUCKET;
const S3_ACCESS_KEY = process.env.S3_ACCESS_KEY;
const S3_SECRET_KEY = process.env.S3_SECRET_KEY;
const s3 = new AWS.S3({
endpoint: S3_ENDPOINT,
accessKeyId: S3_ACCESS_KEY,
secretAccessKey: S3_SECRET_KEY,
s3ForcePathStyle: true,
});
async function uploadImageToS3(imageUrl) {
const response = await fetch(imageUrl);
const imageData = await response.buffer();
const fileName = imageUrl.split("/").pop();
const uploadParams = {
Bucket: S3_BUCKET,
Key: fileName,
Body: imageData,
};
const uploadResult = await s3.upload(uploadParams).promise();
return uploadResult.Location; // 返回 S3 存储的图片 URL
}
async function importWordPress(filePath) {
const xmlData = fs.readFileSync(filePath, "utf-8");
const jsonData = await parseStringPromise(xmlData);
const posts = jsonData.rss.channel[0].item.map(async (item) => {
const content = item["content:encoded"][0];
const imageUrls = Array.from(content.matchAll(/<img src=\"(.*?)\"/g)).map(match => match[1]);
const uploadedImages = await Promise.all(
imageUrls.map(async (url) => {
try {
return await uploadImageToS3(url);
} catch (err) {
console.error(`上传图片失败:${url}`, err);
return url; // 保留原始图片地址
}
})
);
let updatedContent = content;
imageUrls.forEach((url, index) => {
updatedContent = updatedContent.replace(url, uploadedImages[index]);
});
return {
title: item.title[0],
content: updatedContent,
categories: item.category ? item.category.map((cat) => cat._) : [],
pubDate: new Date(item.pubDate[0]),
};
});
const resolvedPosts = await Promise.all(posts);
const client = new MongoClient(MONGO_URI);
await client.connect();
const db = client.db("blog");
await db.collection("posts").insertMany(resolvedPosts);
console.log(`成功导入 ${resolvedPosts.length} 篇文章!`);
await client.close();
}
const filePath = process.argv[2];
if (!filePath) {
console.error("请提供 WordPress 导出的 XML 文件路径。");
process.exit(1);
}
importWordPress(filePath).catch((err) => {
console.error("导入失败:", err);
});
3. 运行导入脚本
在终端运行以下命令:
node scripts/importWordPress.js /path/to/wordpress-export.xml
4. 图片处理
- 确保 MinIO 的连接信息已正确配置。
- 将图片存储后的新地址替换文章中的旧地址。
步骤 6:验证部署
- 启动服务:
docker-compose up -d
- 确保文章和图片已经成功导入到 MongoDB。
- 在浏览器访问
http://<NAS_IP>:9090
,验证是否能够正常显示博客文章。
附加说明
- MongoDB Atlas 数据库名:确保连接字符串中的
blog
对应的是 Atlas 集群中实际存在的数据库名。 - 性能优化:对于高流量站点,可以启用 Atlas 的付费层,提供更强的读写性能。
- 安全性:在生产环境中限制 IP 访问,仅允许服务器的 IP 地址访问数据库。
如果有更多需求,例如复杂查询或动态内容扩展,可以进一步调整数据库结构!