Appearance
VUE 项目打包为 Debian 包与 Nginx 自动配置

在前一章中,我们将 Golang 后端项目打包成了标准的 Debian 包。本章将视角切换到前端,把一个 VUE 项目打包为 .deb 包,并实现与 Nginx 的自动化集成。
与后端打包不同,VUE 项目的打包关注点在于:
- 静态资源部署:将
dist目录部署到正确的位置 - Nginx 配置管理:自动配置 Nginx 站点,实现前后端联调
- 无状态清理:
remove和purge的区别相对简单
整体方案概述
VUE 打包 vs Golang 打包
| 对比维度 | Golang 后端 | VUE 前端 |
|---|---|---|
| 打包内容 | 二进制文件 + systemd 服务 | 静态资源(HTML/CSS/JS)+ Nginx 配置 |
| 核心依赖 | systemd | nginx |
| postinst 职责 | 启动服务 | 重载 Nginx |
| prerm 是否需要 | ✅ 需要(停止服务) | ❌ 通常不需要(无状态) |
| postrm 职责 | 清理 systemd 残留 | 清理部署目录 + 恢复 Nginx 配置 |
最终交付物
out/debian/cms-manager-1.7.0-amd64.deb这个 .deb 包包含:
- ✅ VUE 项目构建产物(
dist/目录) - ✅ Nginx 站点配置文件
- ✅ postinst / postrm 维护者脚本
项目目录结构
text
<cms-manager>/
├── docker/
│ └── debian/
│ ├── builder.Dockerfile # Docker 构建文件
│ ├── dist/ -> ../../dist # 构建产物软链接
│ ├── nginx/ -> ../../nginx/debian # Nginx 配置软链接
│ └── scripts/
│ ├── postinst # 安装后脚本
│ └── postrm # 卸载后脚本
├── dist/ # VUE 构建产物
│ ├── index.html
│ └── assets/
├── nginx/
│ └── debian/
│ └── cms-manager.nginx.conf # Nginx 站点配置
├── .dockerignore
└── Makefile📌 命名约定:本文以
cms-manager作为项目名称示例,你可以替换为实际的项目名称。
第一步:创建目录结构
bash
# 创建 Debian 打包构建目录
mkdir -p docker/debian
# 进入目录
cd docker/debian第二步:配置 Nginx 站点
创建 Nginx 配置目录(软链接)
bash
# 在 docker/debian 目录下执行
ln -s ../../nginx/debian ./nginxNginx 站点配置文件
创建 nginx/debian/cms-manager.nginx.conf:
nginx
server {
listen 80;
listen [::]:80;
server_name cms.server;
# VUE 项目静态资源
location / {
try_files $uri $uri/ @router;
root /var/www/html/cms-manager/dist;
index index.html;
}
# 代理后端 API 接口
location /api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:9400/v1/api/;
}
# 代理后端静态资源
location /resource/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:9400/static/;
}
# 代理 WebSocket 接口
location /websocket/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection Upgrade;
proxy_set_header Upgrade websocket;
proxy_pass http://127.0.0.1:9400/v1/websocket/;
}
# 解决 SPA 路由刷新 404 问题
location @router {
rewrite ^.*$ /index.html last;
}
}💡 关键点:
try_files $uri $uri/ @router和location @router是 VUE/React SPA 应用的核心配置,解决了前端路由刷新时的 404 问题。
第三步:构建产物目录
创建 dist 软链接
bash
# 在 docker/debian 目录下执行
ln -s ../../dist ./dist⚠️ 重要:在运行 Docker 构建之前,必须先执行
npm run build生成dist目录。
第四步:维护者脚本
与后端服务不同,前端项目的维护者脚本不需要 prerm(因为静态资源不需要"停止"),只需要 postinst 和 postrm。
postinst(安装后脚本)
bash
#!/bin/sh
set -e
log() {
logger -t "cms-manager-postinst" "$@"
}
case "$1" in
configure)
log "Starting cms-manager configuration"
# 1. 设置 dist 目录权限
DIST_DIR="/var/www/html/cms-manager/dist"
if [ -d "$DIST_DIR" ]; then
log "Setting $DIST_DIR permissions to 755"
chmod 755 "$DIST_DIR" || {
log "Failed to set $DIST_DIR permissions"
exit 1
}
else
log "$DIST_DIR does not exist, skipping permission setup"
fi
# 2. 重载 Nginx(优雅生效)
log "Attempting to reload nginx"
if command -v systemctl >/dev/null 2>&1; then
if systemctl is-active --quiet nginx; then
systemctl reload nginx && log "nginx reloaded successfully" || {
log "Failed to reload nginx"
exit 1
}
else
log "nginx is not running, skipping reload"
fi
elif command -v service >/dev/null 2>&1; then
service nginx reload && log "nginx reloaded successfully" || {
log "Failed to reload nginx"
exit 1
}
else
nginx -s reload && log "nginx reloaded successfully" || {
log "Failed to reload nginx"
exit 1
}
fi
log "cms-manager configuration completed"
;;
*)
log "Unknown operation: $1"
;;
esac
exit 0postrm(卸载后脚本)
bash
#!/bin/bash
set -e
case "$1" in
remove|purge)
echo "[cms-manager] Removing /etc/nginx/sites-enabled/default and restoring soft link..." >&2
# 1. 删除当前 default 配置(由本包覆盖的)
if [ -e /etc/nginx/sites-enabled/default ]; then
rm -f /etc/nginx/sites-enabled/default
fi
# 2. 删除部署目录
if [ -e /var/www/html/cms-manager ]; then
rm -rf /var/www/html/cms-manager
fi
# 3. 恢复系统默认 Nginx 配置
if [ -f /etc/nginx/sites-available/default ]; then
ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
echo "[cms-manager] Default soft link restored" >&2
fi
# 4. 重载 Nginx
if command -v systemctl >/dev/null 2>&1; then
systemctl reload nginx || true
elif command -v service >/dev/null 2>&1; then
service nginx reload || true
else
nginx -s reload || true
fi
;;
upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
# No action needed
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0⚠️ 注意:
postrm中我们操作的是/etc/nginx/sites-enabled/default,这意味着每个服务器只能部署一个前端项目。如果需要在同一台服务器部署多个前端项目,应该使用独立的配置文件(如sites-available/cms-manager.conf),而非覆盖default。
第五步:Docker 构建文件(builder.Dockerfile)
与 Golang 版本类似,VUE 打包也采用多阶段 Docker 构建,但只有打包阶段(因为 VUE 构建通常在宿主机或 CI 中完成)。
dockerfile
# ============================================================
# 全局构建参数
# ============================================================
ARG VERSION
ARG APPNAME=cms-manager
# ============================================================
# Stage: Debian 打包环境
# ============================================================
FROM ubuntu:20.04
ARG VERSION
ARG APPNAME
ENV VERSION=$VERSION
ENV APPNAME=$APPNAME
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
# 配置国内镜像源
RUN sed -i \
-e 's|http://.*archive.ubuntu.com|http://mirrors.aliyun.com|g' \
-e 's|http://.*security.ubuntu.com|http://mirrors.aliyun.com|g' \
/etc/apt/sources.list
# 配置时区
RUN apt-get update && \
apt-get install -y --no-install-recommends tzdata && \
ln -fs /usr/share/zoneinfo/$TZ /etc/localtime && \
dpkg-reconfigure --frontend noninteractive tzdata
# 安装打包工具
RUN apt-get update && \
apt-get install -y --no-install-recommends \
dpkg-dev \
ca-certificates \
curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
WORKDIR /workspace
# 复制 Nginx 配置文件(覆盖 default)
COPY docker/debian/nginx/${APPNAME}.nginx.conf /etc/nginx/sites-enabled/default
RUN chmod 644 /etc/nginx/sites-enabled/default
# 复制 VUE 构建产物
COPY docker/debian/dist /var/www/html/${APPNAME}/dist
RUN chmod -R 755 /var/www/html/${APPNAME}/dist
# 复制维护者脚本
COPY docker/debian/scripts/postinst docker/debian/scripts/postrm /tmp/
RUN chmod +x /tmp/postinst /tmp/postrm
# ============================================================
# 构建 Debian 包目录结构
# ============================================================
RUN mkdir -p package && \
# Nginx 配置
mkdir -p package/etc/nginx/sites-enabled/ && \
cp /etc/nginx/sites-enabled/default package/etc/nginx/sites-enabled/ && \
# VUE 静态资源
mkdir -p package/var/www/html/${APPNAME}/ && \
cp -r /var/www/html/${APPNAME}/dist package/var/www/html/${APPNAME}/ && \
# 维护者脚本
mkdir -p package/DEBIAN && \
mv /tmp/postinst package/DEBIAN/ && \
mv /tmp/postrm package/DEBIAN/
# 生成 control 文件
RUN echo "Package: ${APPNAME}" > package/DEBIAN/control && \
echo "Version: ${VERSION}" >> package/DEBIAN/control && \
echo "Architecture: amd64" >> package/DEBIAN/control && \
echo "Maintainer: Applyfly <[email protected]>" >> package/DEBIAN/control && \
echo "Description: A ${APPNAME} VUE3 Debian package" >> package/DEBIAN/control && \
echo "Installed-Size: $(du -s package/var/ | cut -f1)" >> package/DEBIAN/control && \
echo "Size: $(du -s package | cut -f1)" >> package/DEBIAN/control && \
echo "Depends: nginx" >> package/DEBIAN/control && \
echo "Pre-Depends: debconf" >> package/DEBIAN/control && \
echo "Section: utils" >> package/DEBIAN/control && \
echo "Priority: optional" >> package/DEBIAN/control
# 打包
RUN dpkg-deb --build package && \
mv package.deb /${APPNAME}-${VERSION}-amd64.deb
# 输出
VOLUME /workspace
CMD ["sh", "-c", "cp /${APPNAME}-${VERSION}-amd64.deb /output/"]Dockerfile 关键点解读
| 步骤 | 操作 | 说明 |
|---|---|---|
| 配置源 | 替换为阿里云镜像 | 加速 apt 包下载 |
| 时区设置 | TZ=Asia/Shanghai | 确保日志时间正确 |
| 安装工具 | dpkg-dev | 提供 dpkg-deb 打包命令 |
| 复制配置 | 覆盖 default | 将 Nginx 配置放入 sites-enabled |
| 复制静态资源 | dist/ → /var/www/html/ | 部署到标准 Web 目录 |
| 打包 | dpkg-deb --build | 生成 .deb 文件 |
第六步:.dockerignore
txt
.git
*.md
tmp/
node_modules
out💡 注意:
node_modules必须被排除,否则会大幅增加构建上下文大小。
第七步:Makefile 自动化构建
makefile
OUTPUT_DIR ?= ./out
.PHONY: builder-debian
builder-debian:
ifndef VERSION
$(error VERSION is required. Usage: make builder-debian VERSION=1.7.0)
endif
@echo "Building Debian package..."
@mkdir -p $(OUTPUT_DIR)/debian
DOCKER_BUILDKIT=1 docker build \
-f docker/debian/builder.Dockerfile \
-t cms-manager-builder:$(VERSION) \
--build-arg VERSION=$(VERSION) \
.
@docker run --rm -v $(abspath $(OUTPUT_DIR)/debian):/output cms-manager-builder:$(VERSION)
@echo "Package built: $(OUTPUT_DIR)/debian/cms-manager-$(VERSION)-amd64.deb"执行构建
bash
# 先构建 VUE 项目
npm run build
# 再打包为 Debian 包
make builder-debian VERSION=1.7.0⚠️ 注意:VUE 打包不需要 SSH agent(不像 Golang 需要拉取私有仓库),所以 Makefile 中省略了
ssh-agent相关命令。
第八步:部署与验证
上传到服务器
bash
scp out/debian/cms-manager-1.7.0-amd64.deb username@host:/tmp/安装软件包
bash
# 使用 apt(推荐)
sudo apt install /tmp/cms-manager-1.7.0-amd64.deb
# 或使用 dpkg
sudo dpkg -i /tmp/cms-manager-1.7.0-amd64.deb验证部署
bash
# 检查文件是否部署成功
ls -la /var/www/html/cms-manager/dist/
# 检查 Nginx 配置
cat /etc/nginx/sites-enabled/default
# 重载 Nginx(postinst 已自动执行)
systemctl status nginx
# 访问测试
curl http://localhost/查看 postinst 日志
bash
# postinst 使用 logger 记录日志
tail -f /var/log/syslog | grep cms-manager卸载与清理
普通卸载(保留配置)
bash
sudo apt remove cms-manager执行 remove 时,postrm 会:
- 删除
/var/www/html/cms-manager/目录 - 恢复 Nginx 默认配置
- 重载 Nginx
彻底清除
bash
sudo apt purge cms-managerpurge 与 remove 在前端项目中的行为基本一致(因为没有配置文件需要额外清理)。
常见问题排查
问题1:安装后访问页面 404
bash
# 检查 dist 目录是否存在
ls -la /var/www/html/cms-manager/dist/
# 检查 Nginx 配置是否正确
nginx -t
# 查看 Nginx 错误日志
tail -f /var/log/nginx/error.log问题2:Nginx 重载失败
bash
# 检查 Nginx 配置语法
nginx -t
# 查看详细错误
systemctl status nginx -l问题3:前端路由刷新 404
检查 Nginx 配置中是否包含:
nginx
location / {
try_files $uri $uri/ @router;
}
location @router {
rewrite ^.*$ /index.html last;
}问题4:多个前端项目冲突
如果需要在同一台服务器部署多个前端项目,不应覆盖 default 配置,而应使用独立的配置文件:
nginx
# /etc/nginx/sites-available/cms-manager.conf
server {
listen 80;
server_name cms.example.com;
# ...
}然后创建软链接:
bash
ln -s /etc/nginx/sites-available/cms-manager.conf /etc/nginx/sites-enabled/VUE vs Golang 打包对比总结
| 对比维度 | Golang 后端 | VUE 前端 |
|---|---|---|
| 核心产物 | 二进制文件 | 静态资源(dist/) |
| 服务管理 | systemd 服务 | Nginx 站点配置 |
| postinst 职责 | 启用服务 + 启动 | 设置权限 + 重载 Nginx |
| prerm 是否需要 | ✅ 需要(停止服务) | ❌ 不需要 |
| postrm 职责 | 清理 systemd 残留 | 清理部署目录 + 恢复 Nginx |
| 依赖包 | systemd | nginx |
| 构建工具 | go build | npm run build |
总结
通过本章,你将 VUE 前端项目打包为标准的 Debian 包,实现了:
| 目标 | 实现方式 |
|---|---|
| ✅ 静态资源部署 | 复制 dist/ 到 /var/www/html/ |
| ✅ Nginx 自动配置 | 覆盖 /etc/nginx/sites-enabled/default |
| ✅ 安装后自动生效 | postinst 重载 Nginx |
| ✅ 卸载时自动清理 | postrm 删除部署目录 + 恢复配置 |
| ✅ 标准化交付 | 输出 .deb 包,支持 apt/dpkg 管理 |
专题总结
至此,Debian 打包专题的六篇文章已全部完成:
| 章节 | 核心内容 |
|---|---|
| 第零章 | Debian 打包入门:control、rules、changelog |
| 第一章 | postinst 脚本完整解读与最佳实践 |
| 第二章 | prerm 脚本的作用与正确使用姿势 |
| 第三章 | postrm 脚本的清理逻辑与 purge 陷阱 |
| 第四章 | Golang 项目打包为 Debian 包完整指南 |
| 第五章 | VUE 项目打包为 Debian 包与 Nginx 自动配置 |
从维护者脚本的理论基础,到后端服务和前端静态资源的实战打包,这套专题覆盖了 Debian 打包的完整知识体系。希望这套指南能帮助你在实际项目中构建出规范、稳定、易维护的 Debian 软件包。
