部署工具踩坑记录:零基础入门教程
开篇:部署是什么?为什么要学这个?

如果你是一个刚接触编程的新手,可能对“部署”这个词不太熟悉。简单来说,部署(Deployment)就是把我们写的代码放到服务器上,让它变成一个别人可以访问的网站或应用的过程。就像你写了一本书,打印出来放在书店里出售一样,部署就是把你写的程序“发布”出去,让全世界的人都能使用。
但问题来了:代码怎么才能正确地运行在服务器上呢?不同的人有不同的电脑配置、不同的操作系统,甚至不同的网络环境。如果我们直接复制代码到服务器上运行,可能会遇到各种错误,比如“为什么我在本地跑得好好的,在服务器上却报错了?”、“这个依赖包为什么会找不到?”等等——这就是我们常说的“坑”。
为了减少这些“踩坑”的次数,我们就需要学习一些部署工具。比如常见的有:
- Docker:把整个开发环境打包起来,一键部署
- Nginx:负责处理网站流量,优化访问速度
- PM2:Node.js项目的进程管理工具
- Jenkins / GitLab CI/CD:自动化部署流程
这些工具虽然听起来高大上,但实际上只要理解了基本用法,任何人都可以掌握。本教程将从最基础开始,带着大家一步步体验部署过程,同时记录我们在实际操作中容易遇到的问题和解决办法,帮你避开那些“坑”,顺利走上部署之路。
环境准备:搭建开发和测试环境


在正式开始部署之前,我们需要先准备好自己的开发环境。这一步虽然看起来繁琐,但它是整个部署过程中非常关键的基础环节。很多新手一开始就“卡住”在这里,所以我们一定要仔细来做。
1. 安装操作系统推荐
如果你是初学者,建议使用以下系统之一:
- Windows 10/11:最容易上手,适合没有太多系统经验的朋友
- macOS:对于前端开发或者全栈项目来说是个不错的选择
- Linux(Ubuntu 或 CentOS):虽然稍微复杂一点,但更适合真实部署环境,建议想深入学习的朋友选择
✅ 新手常见问题:我能不能用学校的机房电脑做实验?
答案是:可以,但如果权限受限、不能安装软件的话,会很困难。推荐使用个人电脑或者申请一个云服务器练手。
2. 安装必要的开发工具
我们需要安装以下几个基本工具:
a. 文本编辑器或 IDE
- 推荐使用 VS Code:免费、开源、插件丰富
- 如果你是 Java 后端开发者,也可以考虑 IntelliJ IDEA 或 Eclipse
b. Node.js + npm(JavaScript 初学者必备)
- 下载地址:Node.js官网
- 安装完后在终端输入以下命令验证是否安装成功:
node -v # 查看 node 版本
npm -v # 查看 npm 版本
c. Git(版本控制工具)
- 官网:Git 官网
- 安装完成后输入:
git --version
来查看是否安装成功
d. Docker(核心部署工具之一)
- 官网:Docker Desktop
- 安装完成后输入:
docker --version
⚠️ 注意:
- Windows 用户如果使用的是旧版本系统,可能无法直接安装 Docker Desktop,建议升级系统或改用 WSL(Windows Subsystem for Linux)环境。
- 如果你不会用命令行也不要着急,后面我们会一起练习!
3. 搭建一个基础项目结构
我们要部署的是一个简单的网页应用。现在来创建一个最基础的 Node.js 小项目作为练习对象:
mkdir hello-deploy
cd hello-deploy
# 初始化一个 npm 项目
npm init -y
# 创建一个 server.js 文件
touch server.js
然后在 server.js 中写入下面这段简单的 Web 服务器代码:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello Deploy World!\n');
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
最后运行你的服务:
node server.js
打开浏览器访问 http://localhost:3000/,你应该能看到 Hello Deploy World! 的字样,说明你已经成功搭建了一个简单的服务!
接下来我们就来看看如何把这个小应用部署到服务器上,并记录在这个过程中可能出现的各种问题 😊
核心概念解释:理解部署中的关键技术名词

在真正开始部署之前,我们先来了解一下几个关键术语,它们会在整个部署过程中频繁出现。我们将用最通俗易懂的方式来解释这些概念。
1. 本地 vs 服务器
| 类型 | 特点 |
|---|---|
| 本地(Local Machine) | 你每天使用的电脑,用来写代码、调试程序的地方 |
| 服务器(Server) | 专门用于存储和运行应用程序的机器,一般远程访问 |
✅ 简单理解:
你写了一个网站程序,它只在你的电脑上能运行,别人是看不到的。只有当你把它上传到服务器之后,别人才能在浏览器里访问你的网站。
2. 进程守护 & PM2
什么是进程守护?
想象一下,你在本地启动了一个服务:
node server.js
然后关掉终端窗口,你会发现你的服务也跟着停止了。这是因为你的服务是在当前终端进程中运行的,窗口一关就结束了。
为了解决这个问题,我们可以使用一个叫 PM2(Process Manager 2) 的工具来守护进程。
npm install pm2 -g # 全局安装 pm2
pm2 start server.js # 使用 pm2 启动服务
✅ 特点:
- 即使关闭终端,服务依然在后台运行
- 支持日志管理、自动重启等功能
3. 负载均衡与 Nginx
随着访问人数增加,一台服务器可能撑不住了怎么办?
我们可以通过**负载均衡(Load Balancing)**的方式,把访问请求分配给多个服务器来处理,提高整体性能。
实现负载均衡的一种常用方法是使用 Nginx。
# 示例 nginx.conf 配置文件
upstream backend {
least_conn;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
✅ 作用:
- 提高性能(分担压力)
- 实现反向代理(隐藏真实服务器 IP)
- 支持 HTTPS、缓存等高级功能
4. 容器化与 Docker
传统的部署方式需要手动安装各种依赖、配置环境,费时又容易出错。
Docker 的出现就是为了解决这个问题。你可以把它理解成“一个可以运行整个应用的小盒子”,里面包含了所有必须的依赖和服务。
创建一个 Dockerfile 文件:
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]
构建并运行容器:
docker build -t hello-deploy .
docker run -p 3000:3000 hello-deploy
✅ 优势:
- 环境一致性(“在我电脑上能跑,在服务器上也能跑”)
- 快速部署和回滚
- 支持微服务架构
5. 自动化部署(CI/CD)
当我们的项目上线以后,每次更新都要手动上传代码、重新部署吗?显然效率很低。
我们可以使用 自动化部署工具,比如 Jenkins、GitLab CI/CD、GitHub Actions 等。这里我们以 GitHub Actions 为例,展示一个简单的 .github/workflows/deploy.yml 文件:
name: Deploy App
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v1
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build app
run: node server.js
✅ 优点:
- 每次提交代码后自动构建部署,节省时间
- 减少人为错误
- 可追踪每次部署的日志和结果
下一节我们将基于上面的知识,动手完成一个完整的部署实战项目,敬请期待!
实战项目:一步一步教你部署一个网页应用
现在我们已经了解了一些基本概念,并且完成了环境准备。接下来我们就要动手实践了——亲手把自己的网页应用部署到服务器上。这个项目虽然是最基础的,但它会让你清楚地看到整个部署流程是怎么进行的,以及可能会遇到哪些问题。
Step 1:整理项目结构
我们前面已经创建了一个简单的 Node.js 网页应用,现在再确认一下目录结构:
hello-deploy/
├── server.js # 主服务文件
└── package.json # npm 项目描述文件
确保你已经安装了必要的依赖。如果没有,请运行:
npm install
Step 2:测试本地运行情况
首先,让我们先确认这个项目在本地是可以正常运行的。执行:
node server.js
然后在浏览器中访问 http://localhost:3000,你应该看到页面显示:
Hello Deploy World!
✅ 成功!说明你的程序没问题,接下来就可以部署到服务器了。
Step 3:使用 PM2 让服务持续运行
刚刚我们用 node server.js 启动的服务,一旦你关闭终端,服务就会停止。为了解决这个问题,我们使用 PM2 来守护服务。
安装 PM2(如果是第一次使用):
npm install pm2 -g
然后启动服务:
pm2 start server.js
这时候你会看到类似下面的输出:
[PM2] Spawning PM2 daemon
[PM2] Process server.js launched
┌────┬────────────────────┬──────────┬──────┬─────────┬─────────┐
│ id │ name │ mode │ pid │ status │ restart │
├────┼────────────────────┼──────────┼──────┼─────────┼─────────┤
│ 0 │ server │ fork │ 1234 │ online │ 0 │
└────┴────────────────────┴──────────┴──────┴─────────┴─────────┘
✅ 看到 status 是 online,说明服务已经在后台稳定运行了。
如果你想要查看日志,可以运行:
pm2 logs
如果你想要停止服务:
pm2 stop server.js
Step 4:使用 Docker 构建镜像
接下来我们要用 Docker 把这个服务打包成一个可以随时运行的“容器”。
① 创建 Dockerfile
在你的项目根目录下新建一个文件叫做 Dockerfile,内容如下:
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]
② 构建 Docker 镜像
运行下面命令来构建镜像:
docker build -t hello-deploy .
构建完成后可以用下面命令查看已有的镜像:
docker images
你应该能看到一行类似于这样的输出:
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-deploy latest abcdefg... 1 minute ago 990MB
③ 运行 Docker 容器
现在让我们启动这个容器:
docker run -d -p 3000:3000 hello-deploy
解释参数含义:
-d表示在后台运行-p 3000:3000表示把容器的 3000 端口映射到主机的 3000 端口
你可以用下面命令查看正在运行的容器:
docker ps
Step 5:通过 Nginx 做反向代理(可选进阶)
如果你想让网站更容易访问(比如不带端口号),可以设置 Nginx 做反向代理。
① 安装 Nginx
如果你是在 Ubuntu 上操作,可以这样安装:
sudo apt update
sudo apt install nginx
② 配置 Nginx
修改默认配置文件:
sudo nano /etc/nginx/sites-available/default
删除原有内容,替换成下面的配置:
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

保存并退出,然后重启 Nginx:
sudo systemctl restart nginx
现在你可以尝试访问:http://your-server-ip/,而不再需要加 :3000 端口号了!
Step 6:使用 GitHub Actions 实现自动化部署(可选进阶)
这部分稍难一些,但非常实用。我们将配置一个 GitHub Action,使得每次你提交代码到主分支时,自动触发部署脚本。
① 在项目中创建工作流目录
在你的项目根目录下创建 .github/workflows 文件夹,并在其中添加一个 YAML 文件,例如 deploy.yml:
mkdir -p .github/workflows
touch .github/workflows/deploy.yml
② 编写部署脚本
打开 deploy.yml,输入以下内容:
name: Deploy Application
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: '18'
- name: Install Dependencies
run: npm install
- name: Start Server with PM2
run: |
npm install pm2 -g
pm2 start server.js --no-daemon
提交代码到 GitHub 后,前往仓库的 “Actions” 页面,你应该能看到部署流程已经开始执行。
总结
到这里为止,你已经完成了一个完整的部署流程:
✅ 写了一个简单的服务
✅ 使用 PM2 守护进程
✅ 使用 Docker 打包应用
✅ 设置 Nginx 做反向代理
✅ 使用 GitHub Actions 实现自动化部署
在接下来的部分,我们将汇总这些步骤中常见的错误和解决方案,帮助你更好地理解并避免踩坑 🚀
新手常见问题汇总:部署过程中容易踩的“坑”
在之前的实战部署过程中,你可能已经遇到了一些问题,或者是某些步骤没有顺利执行。不用担心——这是非常正常的。即使是老手也会遇到各种意想不到的情况。下面我们列出一些最常见的部署问题,并给出对应的详细解决方法。
Q1:启动服务时报错:“Error: Cannot find module ‘xxx’”
这是最常见的问题之一,意思是某个依赖模块没找到。
🔍 可能原因:
- 没有运行
npm install安装依赖 - 当前路径不对,导致读取不到
package.json - 模块未正确安装(如全局模块未安装)
🛠 解决方案:
- 确认当前目录中有
package.json文件:
ls
- 如果有,执行依赖安装:
npm install
- 如果你用了 PM2 或 Docker,也要确保在里面执行过安装。例如 Docker 中要确保 Dockerfile 包含
RUN npm install这一步。
Q2:服务启动成功但外部无法访问
也就是说,你在服务器上执行了服务启动命令,但用别人的电脑或手机去访问的时候,什么都看不到。
🔍 可能原因:
- 服务器防火墙屏蔽了对应端口(如 3000)
- 服务监听的 IP 地址不对
- 没有配置 Nginx 或没有正确暴露端口
🛠 解决方案:
- 查看服务是否绑定到了
0.0.0.0(而不是127.0.0.1)
server.listen(3000, '0.0.0.0', () => { ... })
确保服务器开放对应端口(例如 AWS EC2 安全组设置、阿里云安全组配置)
检查是否真的运行了服务
ps aux | grep node
- 测试本地能否访问服务
curl http://localhost:3000
Q3:使用 Docker 启动服务后,网页无法访问
你构建了镜像,也启动了容器,但就是打不开服务。
🔍 可能原因:
- 容器内部服务没有正确启动
- 端口映

评论 0