网站部署(一):前后端分离架构部署
前言
在当今的网站开发中,前后端分离架构已成为主流。本文将详细记录我部署 mask.alcmaple.cn 网站的完整过程,该网站采用 React 作为前端框架,Python 作为后端,并通过 Apache 服务器进行托管。通过这篇文章,你将了解到企业如何通过同域名不同路径方式部署一个完整的前后端分离网站。
前端部署过程
准备工作
在开始部署前,确保你已经:
- 租用了服务器(本文假设你已有配置基本的 Apache 服务器)
- 购买并配置了域名
- 开发完成了 React 前端项目
打包前端项目
首先,在本地项目目录中构建生产版本:
# React 项目打包
npm run build
# 注:Vue 项目使用相同命令,但会生成 dist 目录而非 build 目录创建网站目录并上传文件
在服务器上创建网站目录并上传打包好的文件:
# 连接到服务器
ssh root@your_server_ip
# 在服务器上创建网站目录
mkdir -p /var/www/mask.alcmaple.cn
# 从本地上传打包文件到服务器
rsync -avz ./build/ root@your_server_ip:/var/www/mask.alcmaple.cn/配置域名解析
在域名控制台中添加域名解析记录:
- 记录类型选择 A 记录(默认就是 A 记录,通常是网站使用)
- 主机记录填写子域名部分(例如:mask)
主机记录就是网址的域名部分,例如主域名:www.example.com 的主机记录就是 www 子域名例如:mask.example.com 的子域名就是 mask,主机记录就是 mask 你只需要填写 mask 和 www 即可,后面的 example.com 部分已经帮你填完了
- 记录值填写服务器 IP 地址,也就是上面链接服务器命令中的your_server_ip这部分
这样,访问 mask.alcmaple.cn 就会指向你的服务器 IP。
配置 Apache 虚拟主机
- 如果你的服务器已经上线过其他网站,此时你访问mask.alcmaple.cn
- 很有可能会访问到你已经上线过的其他网站,这是正常的
- 因为该网站的apache 还没有配置处理,导致请求被默认配置或者第一个匹配 SSL 配置的处理
- 证据就是,检查一下配置文件
cd /etc/apache2/sites-available/
ls -la /etc/apache2/sites-enabled/- 你应该能看到没有新增的 mask 的配置文件,所以还需要创建相对应的配置文件
创建 Apache 配置文件:
sudo nano /etc/apache2/sites-available/mask.alcmaple.cn.conf添加基本的虚拟主机配置:
<VirtualHost *:80>
ServerName mask.alcmaple.cn
DocumentRoot /var/www/mask.alcmaple.cn
ErrorLog ${APACHE_LOG_DIR}/mask.alcmaple.cn-error.log
CustomLog ${APACHE_LOG_DIR}/mask.alcmaple.cn-access.log combined
</VirtualHost>启用配置并重启 Apache:
sudo a2ensite mask.alcmaple.cn.conf
sudo systemctl restart apache2至此,前端部分已经可以通过 http://mask.alcmaple.cn 访问了。如果访问出现问题,可能是浏览器缓存,尝试清除缓存或使用无痕模式访问。
后端部署过程
准备工作
在部署后端之前,需要先调整前端项目的 API 请求路径。由于采用同域名不同路径的方式,API 请求前缀需要设置为相对路径。
在前端代码中(以 Axios 为例):
const apiClient = axios.create({
// baseURL: 'http://localhost:8000/api', // 开发环境
baseURL: '/api', // 生产环境
headers: {
'Content-Type': 'application/json'
}
});同样,后端路由也需要添加 /api 前缀:
# 获取所有任务
@app.get("/api/tasks")
def get_tasks():
data = read_tasks()
return data["tasks"]
# 获取单个任务
@app.get("/api/tasks/{task_id}")
def get_task(task_id: int):
data = read_tasks()
for task in data["tasks"]:
if task["id"] == task_id:
return task
raise HTTPException(status_code=404, detail="任务未找到")创建后端目录并上传代码
# 在服务器上创建后端目录
mkdir -p /root/MapleMaskAPI
# 从本地上传后端代码
scp -r ./server/* root@your_server_ip:/root/MapleMaskAPI/创建 Python 虚拟环境
为后端应用创建专用的 Python 虚拟环境:
- 这里要注意你的 Python 使用什么框架,flask 和 fastapi 都有自己不同的依赖,部署也会有点不一样,这里以 fastapi 为例
- 如果你用的是 flask 的话,就需要用gunicorn启动,而fastapi则直接用uvicorn启动,对于 flask 这里就不再赘述了,具体可以疑问可以评论区补充
# 检查系统Python版本
python3 --version
# 创建专用目录存放所有虚拟环境
mkdir -p /root/venvs
# 创建mask专用环境
python3 -m venv /root/venvs/mask_env
# 激活环境并安装依赖
source /root/venvs/mask_env/bin/activate
pip install --upgrade pip
pip install fastapi uvicorn pydantic
deactivate创建系统服务
创建系统服务文件使后端应用能够在后台持续运行:
sudo nano /etc/systemd/system/mask_api.service添加以下内容:
[Unit]
Description=FastAPI instance for Mask API
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/root/MapleMaskAPI
ExecStart=/root/venvs/mask_env/bin/python -m uvicorn app:app --host 127.0.0.1 --port 5002
Restart=always
[Install]
WantedBy=multi-user.target- 注意这里的端口,要和你的后端代码、apache 配置的端口保持一致
- 注意这里的WorkingDirectory,要指向你的后端代码的目录
- 注意这里的ExecStart,要指向你的后端代码的启动文件,比如
app.py或main.py
配置 Apache 反向代理
修改之前创建的 Apache 配置文件:
sudo nano /etc/apache2/sites-available/mask.alcmaple.cn.conf完整配置如下:
<VirtualHost *:80>
ServerName mask.alcmaple.cn
DocumentRoot /var/www/mask.alcmaple.cn
# 前端静态文件
<Directory /var/www/mask.alcmaple.cn>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# 后端API - 使用Location块
<Location /api/>
ProxyPass http://127.0.0.1:5002/api/
ProxyPassReverse http://127.0.0.1:5002/api/
# 添加这些行以确保请求被正确处理
RequestHeader set X-Forwarded-Proto "http"
RequestHeader set X-Forwarded-Port "80"
</Location>
ErrorLog ${APACHE_LOG_DIR}/mask.alcmaple.cn-error.log
CustomLog ${APACHE_LOG_DIR}/mask.alcmaple.cn-access.log combined
</VirtualHost>启用必要模块并启动服务
# 启用Apache代理模块
sudo a2enmod proxy
sudo a2enmod proxy_http
# 启用并启动API服务
sudo systemctl daemon-reload
sudo systemctl enable mask_api
sudo systemctl start mask_api
# 重启 Apache
sudo systemctl restart apache2问题探讨
检查后端服务是否正常运行:
sudo systemctl status mask_api这里只提到我在部署过程中遇到的问题:
后端服务启动失败
如果状态显示"failed"并且错误代码为203/EXEC,可能是路径或命令错误。检查虚拟环境路径和启动命令是否正确。
Python框架兼容性问题
不同的Python框架有不同的最佳启动方式。例如,Flask适合使用gunicorn,而FastAPI更适合使用uvicorn。确保使用正确的启动命令。
端口冲突
确保配置的端口(如5002)没有被其他服务占用,并且在Apache配置和服务文件中保持一致。
总结
通过以上步骤,我们成功部署了一个前后端分离的网站架构:
- 前端使用React构建,由Apache直接提供静态文件服务
- 后端使用Python(FastAPI)开发,通过专用虚拟环境运行
- Apache服务器通过反向代理将API请求转发到后端服务
这种架构既保持了开发的灵活性,又简化了部署和维护流程。下一步,你可以考虑添加SSL证书,让网站支持HTTPS安全访问。
如有任何问题或建议,欢迎在评论区交流。

暂无评论