English
Packaging a VUE project into a Debian package and automatic Nginx configuration

In the previous chapter, we packaged the Golang backend project into a standard Debian package. This chapter will shift the perspective to Frontend, package a VUE project as .deb package, and implement automated integration with Nginx.
Unlike backend packaging, the focus of packaging a VUE project is on:
Static Asset Deployment: will
distDeploy the directory to the correct location.Nginx Configuration Management: Automatically configure Nginx sites to enable frontend-backend joint debugging
Stateless cleanup:
removeandpurgeThe difference is relatively simple.
Overall Solution Overview
VUE build vs Golang build
| Comparison dimension | Golang backend | VUE frontend |
|---|---|---|
| Package contents | binary file + systemd service | Static resources (HTML/CSS/JS) + Nginx configuration |
| Core dependency | systemd | nginx |
| postinst responsibilities | Start service | Reload Nginx |
| Is prerm required? | ✅ Required (stop service) | ❌ Usually not required (stateless) |
| postrm responsibilities | Clean up systemd remnants | Clean up deployment directory + restore Nginx configuration |
Final deliverable
out/debian/cms-manager-1.7.0-amd64.debthis .deb Package includes:
✅ VUE project build artifacts (
dist/Table of Contents)✅ Nginx site configuration file
✅ postinst / postrm maintainer scripts
Project directory structure
text
<cms-manager>/
├── docker/
│ └── debian/
│ ├── builder.Dockerfile # Docker build file
│ ├── dist/ -> ../../dist # Build artifact symlink
│ ├── nginx/ -> ../../nginx/debian # Nginx configuration symlink
│ └── scripts/
│ ├── postinst # post-install script
│ └── postrm # post-uninstall script
├── dist/ # VUE build artifacts
│ ├── index.html
│ └── assets/
├── nginx/
│ └── debian/
│ └── cms-manager.nginx.conf # Nginx site configuration
├── .dockerignore
└── Makefile📌Naming convention: This paper takes cms-manager As an example project name, you can replace it with the actual project name.
Step 1: Create the directory structure
bash
# Create Debian packaging build directory
mkdir -p docker/debian
# Enter the directory
cd docker/debianStep 2: Configure the Nginx site
Create Nginx configuration directory (symlink)
bash
# Execute in the docker/debian directory
ln -s ../../nginx/debian ./nginxNginx site configuration file
Create nginx/debian/cms-manager.nginx.conf:
nginx
server {
listen 80;
listen [::]:80;
server_name cms.server;
# VUE project static assets
location / {
try_files $uri $uri/ @router;
root /var/www/html/cms-manager/dist;
index index.html;
}
# Proxy backend API interface
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/;
}
# Proxy backend static resources
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/;
}
# Proxy WebSocket interface
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/;
}
# Fix the 404 issue when refreshing SPA routes
location @router {
rewrite ^.*$ /index.html last;
}
}💡Key points:try_files $uri $uri/ @router and location @router It is the core configuration of VUE/React SPA applications, solving the 404 issue when frontend routes are refreshed.
Step 3: Build the artifact directory
Create a dist symlink
bash
# Execute in the docker/debian directory
ln -s ../../dist ./dist⚠️Important: Before running the Docker build,Must be executed first.npm run build Generate dist Table of contents.
Step 4: Maintainer Script
Unlike backend services, the maintainer scripts of frontend projects No need prerm(Because static resources do not need to be "stopped"), only need postinst and postrm.
postinst (post-installation script)
bash
#!/bin/sh
set -e
log() {
logger -t "cms-manager-postinst" "$@"
}
case "$1" in
configure)
log "Starting cms-manager configuration"
# 1. Set dist directory permissions
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. Reload Nginx (gracefully takes effect)
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 (post-removal script)
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. Delete the current default configuration (overridden by this package)
if [ -e /etc/nginx/sites-enabled/default ]; then
rm -f /etc/nginx/sites-enabled/default
fi
# 2. Delete the deployment directory
if [ -e /var/www/html/cms-manager ]; then
rm -rf /var/www/html/cms-manager
fi
# 3. Restore the system default Nginx configuration
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. Reload 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⚠️Note:postrm What we operate in is /etc/nginx/sites-enabled/default, this means Each server can only deploy one frontend project. If you need to deploy multiple frontend projects on the same server, you should use separate configuration files (such as sites-available/cms-manager.conf), rather than overwrite default.
Step 5: Docker build file (builder.Dockerfile)
Similar to the Golang version, VUE packaging also uses a multi-stage Docker build, but Only the packaging stage(Because VUE builds are usually completed on the host machine or in CI).
dockerfile
# ============================================================
# Global build parameters
# ============================================================
ARG VERSION
ARG APPNAME=cms-manager
# ============================================================
# Stage: Debian packaging environment
# ============================================================
FROM ubuntu:20.04
ARG VERSION
ARG APPNAME
ENV VERSION=$VERSION
ENV APPNAME=$APPNAME
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
# Configure a domestic mirror source
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
# Configure time zone
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
# Install packaging tool
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
# Copy the Nginx configuration file (overwrite default)
COPY docker/debian/nginx/${APPNAME}.nginx.conf /etc/nginx/sites-enabled/default
RUN chmod 644 /etc/nginx/sites-enabled/default
# Copy VUE build artifacts
COPY docker/debian/dist /var/www/html/${APPNAME}/dist
RUN chmod -R 755 /var/www/html/${APPNAME}/dist
# Copy maintainer script
COPY docker/debian/scripts/postinst docker/debian/scripts/postrm /tmp/
RUN chmod +x /tmp/postinst /tmp/postrm
# ============================================================
# Build Debian package directory structure
# ============================================================
RUN mkdir -p package && \
# Nginx configuration
mkdir -p package/etc/nginx/sites-enabled/ && \
cp /etc/nginx/sites-enabled/default package/etc/nginx/sites-enabled/ && \
# VUE static assets
mkdir -p package/var/www/html/${APPNAME}/ && \
cp -r /var/www/html/${APPNAME}/dist package/var/www/html/${APPNAME}/ && \
# Maintainer script
mkdir -p package/DEBIAN && \
mv /tmp/postinst package/DEBIAN/ && \
mv /tmp/postrm package/DEBIAN/
# Generate the control file
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
# Package
RUN dpkg-deb --build package && \
mv package.deb /${APPNAME}-${VERSION}-amd64.deb
# Output
VOLUME /workspace
CMD ["sh", "-c", "cp /${APPNAME}-${VERSION}-amd64.deb /output/"]Dockerfile Key Points Explained
| Steps | Operation | Explanation |
|---|---|---|
| Configuration source | Replace with the Alibaba Cloud mirror | Speed up apt package downloads |
| Time zone settings | TZ=Asia/Shanghai | Ensure the log time is correct. |
| Installation tools | dpkg-dev | Provide dpkg-deb Packaging command |
| Copy configuration | Coverage default | Place the Nginx configuration in sites-enabled |
| Copy static assets | dist/→/var/www/html/ | Deploy to the standard web directory |
| Pack | dpkg-deb --build | Generate a .deb file |
Step 6: .dockerignore
txt
.git
*.md
tmp/
node_modules
out💡Note:node_modules Must be excluded, otherwise it will significantly increase the build context size.
Step 7: Makefile automated build
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"Execute build
bash
# Build the VUE project first
npm run build
# Then package it as a Debian package.
make builder-debian VERSION=1.7.0⚠️Attention: Building VUE does not require an SSH agent (unlike Golang, which requires pulling private repositories), so it is omitted in the Makefile.ssh-agent Related commands.
Step 8: Deployment and Verification
Upload to the server
bash
scp out/debian/cms-manager-1.7.0-amd64.deb username@host:/tmp/Install the software package
bash
# Use apt (recommended)
sudo apt install /tmp/cms-manager-1.7.0-amd64.deb
# or use dpkg
sudo dpkg -i /tmp/cms-manager-1.7.0-amd64.debVerify deployment
bash
# Check whether the file is deployed successfully
ls -la /var/www/html/cms-manager/dist/
# Check Nginx configuration
cat /etc/nginx/sites-enabled/default
# Reload Nginx (postinst has already been executed automatically)
systemctl status nginx
# Access test
curl http://localhost/View postinst log
bash
# postinst uses logger to log
tail -f /var/log/syslog | grep cms-managerUninstall and Cleanup
Normal uninstall (keep configuration)
bash
sudo apt remove cms-managerExecute remove when,postrm Will:
Delete
/var/www/html/cms-manager/ContentsRestore the default Nginx configuration
Reload Nginx
Completely remove
bash
sudo apt purge cms-managerpurge and remove Behavior in front-end projects Basically consistent(Because there are no configuration files that require extra cleanup.)
Common troubleshooting
Question 1: Accessing the page after installation returns 404
bash
# Check if the dist directory exists
ls -la /var/www/html/cms-manager/dist/
# Check whether the Nginx configuration is correct
nginx -t
# View Nginx error logs
tail -f /var/log/nginx/error.logProblem 2: Nginx reload failed
bash
# Check Nginx configuration syntax
nginx -t
# View detailed error
systemctl status nginx -lIssue 3: 404 on frontend route refresh
Check whether the Nginx configuration contains:
nginx
location / {
try_files $uri $uri/ @router;
}
location @router {
rewrite ^.*$ /index.html last;
}Issue 4: Conflicts among multiple frontend projects
If you need to deploy multiple frontend projects on the same server,Should not be overwritten default Configuration, but should use a separate configuration file:
nginx
# /etc/nginx/sites-available/cms-manager.conf
server {
listen 80;
server_name cms.example.com;
# ...
}Then create a symbolic link:
bash
ln -s /etc/nginx/sites-available/cms-manager.conf /etc/nginx/sites-enabled/VUE vs Golang Packaging Comparison Summary
| Comparison dimension | Golang backend | VUE frontend |
|---|---|---|
| Core deliverable | binary file | Static assets (dist/) |
| Service Management | systemd service | Nginx site configuration |
| postinst responsibilities | Enable service + Start | Set permissions + reload Nginx |
| Is prerm required? | ✅ Required (stop service) | ❌ Not needed |
| postrm responsibilities | Clean up systemd remnants | Clean up deployment directory + restore Nginx |
| dependency package | systemd | nginx |
| Build tool | go build | npm run build |
Summary
In this chapter, you packaged a Vue front-end project into a standard Debian package, achieving:
| Goal | Implementation method |
|---|---|
| ✅ Static resource deployment | Copy dist/ to /var/www/html/ |
| ✅ Nginx Auto Configuration | Coverage /etc/nginx/sites-enabled/default |
| ✅ Automatically takes effect after installation | postinst reloads Nginx |
| ✅ Automatically clean up on uninstall | postrm delete deployment directory + restore configuration |
| ✅ Standardized delivery | Output .deb package, supports apt/dpkg management |
Special Topic Summary
With this, all six articles in the Debian packaging series are now complete:
| Chapter | Core content |
|---|---|
| Chapter Zero | Debian Packaging Primer: control, rules, changelog |
| Chapter 1 | Complete Interpretation and Best Practices of the postinst Script |
| Chapter 2 | The role of the prerm script and how to use it correctly |
| Chapter 3 | Cleanup Logic in the postrm Script and the purge Pitfall |
| Chapter 4 | Complete Guide to Packaging a Golang Project as a Debian Package |
| Chapter 5 | Packaging a VUE project as a Debian package with automatic Nginx configuration |
From the theoretical foundations of maintainer scripts to hands-on packaging of backend services and frontend static assets, this series covers Debian packaging's Complete knowledge system. I hope this guide can help you build standardized, stable, and maintainable Debian packages in real projects.
