Node.js 入门:简介、API、数据库、跨域与部署(含 Docker)
Node.js 入门:简介、API、数据库、跨域与部署(含 Docker)
Node.js 是基于 Chrome V8 的 JavaScript 运行时,可在服务端运行 JS,配合 npm 生态做 Web API、CLI、构建工具等。下面按「能跑起来 → 连库 → 跨域与路由 → 部署 → Docker 与数据库容器」顺序说明。
1. 简介
| 要点 | 说明 |
|---|---|
| 定位 | 事件驱动、非阻塞 I/O,适合 I/O 密集(HTTP、数据库、文件)。 |
| 包管理 | 官方自带 npm;也可用 pnpm、yarn。 |
| 典型用途 | REST/GraphQL 服务、BFF、实时服务(WebSocket)、脚本与工程化工具链。 |
安装后验证:
node -v
npm -v
2. 基本用法
2.1 运行脚本
node app.js
2.2 初始化项目
mkdir my-api && cd my-api
npm init -y
2.3 安装依赖(下文示例用 Express)
npm install express cors mysql2
npm install -D nodemon
在 package.json 中配置脚本:
{
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js"
}
}
开发时用 npm run dev,生产用 npm start。
3. 编写 API、注册路由(Express)
路由即「路径 + HTTP 方法」与处理函数的映射;用 Router 拆分模块,再用 app.use 挂载前缀。
3.1 入口 src/index.js
const express = require("express");
const cors = require("cors");
const apiRouter = require("./routes");
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.json());
app.use(cors({ origin: process.env.CORS_ORIGIN || "*" }));
app.get("/health", (req, res) => res.json({ ok: true }));
app.use("/api", apiRouter);
app.listen(PORT, () => console.log(`listening on ${PORT}`));
3.2 src/routes/index.js(聚合子路由)
const { Router } = require("express");
const userRouter = require("./users");
const router = Router();
router.use("/users", userRouter);
module.exports = router;
3.3 src/routes/users.js
const { Router } = require("express");
const router = Router();
router.get("/", (req, res) => {
res.json([{ id: 1, name: "demo" }]);
});
router.post("/", (req, res) => {
res.status(201).json({ id: 2, ...req.body });
});
module.exports = router;
访问示例:GET http://localhost:3000/api/users。
4. 跨域(CORS)
浏览器 同源策略 会拦截「前端域名/端口与 API 不一致」的请求;服务端需返回 Access-Control-* 头。
- 开发:常用
cors中间件,允许指定源或*(生产建议收紧为具体前端域名)。 - 预检:带自定义头、
PUT/DELETE等会先发 OPTIONS,cors会处理。
上文示例中:
app.use(cors({ origin: "https://your-frontend.com" }));
多个源可用数组或函数动态判断;仅内网调试可临时用 origin: true 反射请求源(仍需谨慎)。
5. 连接数据库(以 MySQL 为例)
使用 mysql2 的 Promise 连接池,避免每次请求新建连接。
5.1 src/db/pool.js
const mysql = require("mysql2/promise");
const pool = mysql.createPool({
host: process.env.DB_HOST || "127.0.0.1",
port: Number(process.env.DB_PORT || 3306),
user: process.env.DB_USER || "root",
password: process.env.DB_PASSWORD || "",
database: process.env.DB_NAME || "app",
waitForConnections: true,
connectionLimit: 10,
});
module.exports = pool;
5.2 在路由中查询(示例)
const pool = require("../db/pool");
router.get("/:id", async (req, res, next) => {
try {
const [rows] = await pool.query("SELECT id, name FROM users WHERE id = ?", [
req.params.id,
]);
res.json(rows[0] || null);
} catch (e) {
next(e);
}
});
PostgreSQL 可用 pg 的 Pool,用法类似;MongoDB 常用 mongoose 连接字符串。原则一致:连接信息来自环境变量,勿写死在代码里。
6. 部署到服务器(简要)
常见流程:
- 服务器安装 Node(或用 nvm 固定版本)、Git,克隆代码。
npm ci --production(或npm install --production)安装依赖。- 环境变量:用
.env(配合dotenv)或系统环境变量 / systemdEnvironment=注入PORT、DB_*、CORS_ORIGIN。 - 进程守护:PM2(
pm2 start src/index.js --name api)或 systemd,保证崩溃重启。 - 反向代理:Nginx 把
443/80转到127.0.0.1:3000,HTTPS 证书放在 Nginx。 - 防火墙只开放 80/443,数据库端口不对公网开放。
7. 用 Docker 部署 Node 服务
7.1 Dockerfile(单阶段示例)
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "src/index.js"]
构建与运行:
docker build -t my-api:1.0 .
docker run -d --name api -p 3000:3000 \
-e DB_HOST=host.docker.internal \
-e DB_USER=root -e DB_PASSWORD=secret -e DB_NAME=app \
my-api:1.0
(Linux 上连接宿主机 MySQL 可用 host.docker.internal 需在 Docker 20.10+ 配置,或改用宿主机局域网 IP。)
8. Docker Compose:应用 + 数据库容器互联
核心思路:应用与数据库放在同一 Compose 工程,通过 服务名 作为 主机名 访问数据库,不要写死 127.0.0.1(在容器内 127.0.0.1 指向自身,不是数据库容器)。
8.1 docker-compose.yml 示例
services:
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: app
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 5s
retries: 10
api:
build: .
ports:
- "3000:3000"
environment:
NODE_ENV: production
DB_HOST: db
DB_PORT: 3306
DB_USER: root
DB_PASSWORD: secret
DB_NAME: app
CORS_ORIGIN: "*"
depends_on:
db:
condition: service_healthy
volumes:
db_data: {}
要点:
DB_HOST: db与services.db同名,Docker 内置 DNS 会解析到数据库容器。depends_on+healthcheck:尽量等数据库可连后再启动 API(仍建议在应用内做重试连接)。- 生产环境请收紧
CORS_ORIGIN、使用强密码、不把数据库端口映射到公网(可去掉ports中3306:3306,仅api通过内网访问db)。
启动与停止:
docker compose up -d --build
docker compose logs -f api
docker compose down
down 默认保留命名卷 db_data(数据仍在);若需清空数据可加 docker compose down -v(慎用)。
9. 小结
| 主题 | 要点 |
|---|---|
| 用法 | node 运行脚本,npm 管理依赖与脚本。 |
| API / 路由 | Express Router + app.use 前缀 分层注册。 |
| 跨域 | cors 中间件,生产指定前端源。 |
| 数据库 | 连接池 + 环境变量;Compose 里 DB_HOST=服务名。 |
| 服务器部署 | 环境变量、PM2/systemd、Nginx 反代。 |
| Docker | Dockerfile 构建镜像;Compose 编排 API 与 DB,同一网络内用服务名互联。 |
更复杂的场景(迁移脚本、只读副本、密钥管理)可再引入 Prisma/TypeORM、K8s Secret 等,但上述模式足以覆盖多数中小型项目骨架。
