Ubuntu 14.04 下 MEAN.JS 全栈部署实战:MongoDB 安装与 Node.js 版本兼容配置

1. 项目概述:这不是装个软件,而是在 Ubuntu 14.04 上亲手搭一座现代 Web 开发的桥

MEAN.JS 这个名字听起来像某种新潮咖啡配方,但对开发者来说,它是一套实打实的全栈开发组合拳——MongoDB、Express.js、AngularJS 和 Node.js 四者环环相扣,构成了一条从数据库到浏览器界面的完整数据流通道。我第一次在 Ubuntu 14.04 上部署 MEAN.JS 时,用的还是物理服务器,不是云主机,更不是 Docker 容器。那时候 Node.js 刚过 v0.10,AngularJS 还没出 2.0,Ubuntu 14.04 是 LTS 版本里最稳的一代,也是很多企业生产环境的“压舱石”。今天回看,这个组合看似陈旧,但它背后的技术逻辑——异步 I/O、JSON 一统前后端、NoSQL 灵活建模——至今仍是现代 Web 架构的底层基因。

你可能会问:都 2024 年了,为什么还要折腾 Ubuntu 14.04 和 AngularJS?答案很实在:不是怀旧,而是接手老项目、维护遗留系统、做兼容性测试、或者教学演示时,你绕不开它。我去年帮一家本地教育机构升级其在线题库后台,核心就是一套跑在 Ubuntu 14.04 上的 MEAN.JS 应用,前端 AngularJS 1.3,后端 Express 4.2,MongoDB 2.6。他们不想重写,只想让系统继续跑下去,还能加几个新功能。这时候,照着网上那些“一键部署脚本”或“最新版教程”硬上,十有八九会卡在 Node 版本不兼容、npm 包依赖冲突、或者 MongoDB 启动失败上。所以这篇内容,不是教你怎么追新,而是教你怎么“稳住旧”——怎么在 Ubuntu 14.04 这个特定土壤里,把 MEAN.JS 的四块砖严丝合缝地垒起来,每一步都经得起重启、经得起日志排查、经得起同事半夜打电话来问“MongoDB 又挂了,咋办?”。

关键词里反复出现的 “mongodb 安装”、“mongodb 启动不了”、“安装权限”,恰恰戳中了这个项目的命门:它不是四个独立软件的简单叠加,而是一个需要精细调校的有机体。MongoDB 不是装完就完事,它得配好数据目录权限、得设好 systemd 服务、得关掉默认的 bind_ip 限制;Node.js 不是 apt-get 一下就行,Ubuntu 14.04 自带的版本太老,必须手动编译或用 nvm 管理;AngularJS 的前端构建,得用特定版本的 Grunt,还得处理 Bower 依赖源被墙的问题。这些细节,官方文档不会写,新手教程往往一笔带过,但它们才是决定你能不能在凌晨两点把服务拉起来的关键。接下来的内容,我会把这整套流程拆成可触摸、可验证、可回溯的步骤,不讲虚的,只讲我在真实服务器上敲过的命令、改过的配置、查过的日志。

2. 整体设计与思路拆解:为什么选这条“笨路”,而不是一键脚本或 Docker?

2.1 放弃一键脚本:可控性比速度更重要

你在网上搜 “MEAN.JS Ubuntu 14.04 install”,会看到一堆 GitHub Gist 或博客里的“三行命令搞定”脚本。我试过,也维护过。结果呢?第一次运行成功,第二次更新失败,第三次换服务器直接报错找不到某个 deprecated 的 npm 包。原因很简单:这类脚本本质是把所有操作“黑箱化”,它帮你自动下载、解压、配置、启动,但一旦中间某一步失败(比如 MongoDB 下载超时、npm install 被墙、Grunt 初始化卡住),你就完全不知道问题出在哪一层。日志里全是“Error: Command failed”,没有上下文,没有路径,没有权限提示。对于一个要长期维护的生产环境,这种不可见性是灾难性的。

所以我坚持手把手安装。每一行 apt-get install 我都清楚它装了什么、改了哪些文件;每一个 curl -sL https://deb.nodesource.com/setup_0.12 | sudo bash 我都明白它在 /etc/apt/sources.list.d/ 下加了源;每一次 sudo mkdir -p /data/db && sudo chown mongodb:mongodb /data/db 我都确认了数据目录的属主和权限。这不是效率低下,而是把“不确定性”从运维流程里彻底剔除。当你能清晰说出 “MongoDB 的配置文件在 /etc/mongod.conf ,它的日志路径是 /var/log/mongodb/mongod.log ,它的 PID 文件是 /var/run/mongodb/mongod.pid ”,你就已经拥有了故障排查的第一把钥匙。

2.2 拒绝 Docker:环境一致性 ≠ 部署便捷性

Docker 当然是神器,但对 Ubuntu 14.04 + MEAN.JS 这个组合,它反而会增加一层复杂度。Ubuntu 14.04 的内核是 3.13,Docker 官方支持的最低内核是 3.10,理论上可行。但问题在于生态:Docker Hub 上针对 Ubuntu 14.04 的官方 MEAN.JS 镜像早已停止维护;你拉下来的镜像,里面 Node.js 版本可能是 v4.x,MongoDB 可能是 v3.2,而你的老项目代码只认 v0.12 和 v2.6。强行用新镜像跑老代码,你会陷入无休止的 TypeError: Object.assign is not a function MongoError: unknown top level operator: $lookup 这类兼容性地狱。更麻烦的是,Docker 的 volume 挂载、网络端口映射、服务依赖启动顺序,在 Ubuntu 14.04 的 systemd 环境下调试起来,比直接在宿主机上配置还费劲。我的经验是:如果目标环境明确是 Ubuntu 14.04 物理机或虚拟机,那就老老实实走原生安装路线。Docker 的价值在于快速复制和隔离,而这里的价值在于“精准复刻”和“深度掌控”。

2.3 版本锁定:不是越新越好,而是“刚刚好”

这是整个设计的基石。Ubuntu 14.04 的生命周期决定了我们必须用“配套”的版本:

  • Node.js :不能用 v10+,因为 V8 引擎变化太大,老 AngularJS 的 digest cycle 会出问题。官方推荐是 v0.12.x(LTS),我们最终锁定在 v0.12.18。
  • MongoDB :Ubuntu 14.04 官方源里只有 v2.4,但 v2.4 缺少很多关键特性(如 text index)。社区源提供 v2.6,它完美兼容 MEAN.JS 0.4.x(当时主流版本),且稳定可靠。v3.0+ 的 WiredTiger 引擎在 14.04 上性能反而不如 MMAPv1。
  • Express.js :随 Node.js 一起安装的 Express CLI 工具生成的骨架,默认就是 Express 4.x,与 MEAN.JS 0.4.x 兼容。
  • AngularJS :MEAN.JS 0.4.x 绑定的是 AngularJS 1.3.x,这是最后一个支持 IE9 的大版本,也是企业内网系统最常见的选择。

所有这些版本选择,都不是拍脑袋,而是基于大量线上项目的踩坑记录。比如,曾有客户把 MongoDB 从 v2.6 升级到 v3.2,结果所有 $where 查询全部失效,因为 v3.2 默认禁用了 JavaScript 执行。再比如,把 Node.js 升到 v4.0, bcrypt 这个密码哈希模块就必须重新编译,而它的原生插件在 Ubuntu 14.04 的 GCC 4.8 下编译失败率极高。所以,“版本锁定”不是保守,而是对历史债务的尊重和对生产稳定的承诺。

2.4 目录结构与权限模型:让每个组件各司其职

一个混乱的目录结构,是后期维护的噩梦。我给自己立下铁律:所有 MEAN.JS 相关文件,必须严格遵循 Linux FHS(文件系统层次标准)精神,分区域管理:

  • /opt/meanjs/ :存放 MEAN.JS 的源码、应用代码、Gruntfile.js 等。这是“工作区”,属于 deploy 用户。
  • /var/lib/mongodb/ :MongoDB 的数据目录,由 mongodb 用户拥有, /data/db 是软链接指向此处。这是“数据区”,绝对禁止 root 直接写入。
  • /etc/mongod.conf :MongoDB 的主配置文件,由 root 拥有, mongodb 用户可读。这是“配置区”,修改需 sudo
  • /usr/local/bin/node :Node.js 的二进制文件,由 root 拥有,全局可执行。这是“运行时区”,版本变更需谨慎。

权限模型的核心原则是“最小权限”: deploy 用户能启动 Node.js 应用,但不能动 MongoDB 数据; mongodb 用户能读写数据文件,但不能执行任意 shell 命令; root 只负责安装和配置,不参与日常运行。这种分离,让安全审计变得简单,也让故障定位更清晰——如果应用连不上数据库,第一反应不是“代码错了”,而是检查 deploy 用户是否在 mongodb 用户组里,或者 mongod 服务是否真的在监听 127.0.0.1:27017

3. 核心细节解析与实操要点:从系统准备到服务守护

3.1 系统初始化:别跳过这 5 分钟,它能省你 5 小时

Ubuntu 14.04 默认安装后,很多基础工具是缺失的,或者版本老旧。这一步不是“可选项”,而是“必选项”,我把它叫做“环境净化”。

首先,更新系统并安装基础编译工具:

sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y build-essential python-dev libssl-dev curl wget git

build-essential 是关键,它包含了 gcc , g++ , make ,没有它,后续安装 Node.js 源码或 bcrypt 这类 native 模块时,会直接报 gyp ERR! stack Error: Can't find Python executable python-dev libssl-dev 同样重要,前者是 Python C API 头文件,后者是 OpenSSL 开发库,很多 npm 包(如 request )编译时会链接它们。

然后,配置时区和 locale,避免日志时间错乱和中文乱码:

sudo dpkg-reconfigure tzdata # 选择 Asia/Shanghai
sudo locale-gen en_US.UTF-8 zh_CN.UTF-8
sudo update-locale LANG=en_US.UTF-8

这一步很多人忽略,结果是 MongoDB 日志里的时间戳是 UTC,而你的应用日志是 CST,排查问题时两份日志对不上,徒增困扰。

最后,创建专用用户。 绝对不要用 root 用户跑应用! 创建一个 deploy 用户,并赋予其必要的 sudo 权限(仅限于服务管理):

sudo adduser --disabled-password --gecos "" deploy
echo "deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start mongod, /usr/bin/systemctl stop mongod, /usr/bin/systemctl restart mongod, /bin/systemctl status mongod" | sudo tee /etc/sudoers.d/deploy
sudo chmod 0440 /etc/sudoers.d/deploy

这个 sudoers 规则非常精确: deploy 用户只能用 systemctl 控制 mongod 服务,不能执行 rm -rf / 这种危险命令。这是安全底线。

提示:如果你的应用需要访问 /var/log/ 下的日志,记得把 deploy 用户加入 syslog 组: sudo usermod -a -G syslog deploy 。否则 tail -f /var/log/mongodb/mongod.log 会提示 Permission denied。

3.2 MongoDB 安装与配置:权限、端口、日志,一个都不能少

Ubuntu 14.04 官方源的 MongoDB 是 v2.4,我们要用社区源的 v2.6。先添加源:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/2.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-2.6.list
sudo apt-get update

注意 trusty 这个 codename,它对应 Ubuntu 14.04。如果写成 xenial (16.04), apt-get update 会报 404 错误。

安装:

sudo apt-get install -y mongodb-org=2.6.12 mongodb-org-server=2.6.12 mongodb-org-shell=2.6.12 mongodb-org-mongos=2.6.12 mongodb-org-tools=2.6.12

这里强制指定了 2.6.12 版本号。为什么?因为 mongodb-org 是一个 meta-package,它会自动拉取最新子包,而 v2.6.13 在某些内核上存在内存泄漏 bug。锁定小版本,是生产环境的基本素养。

安装完成后,最关键的一步来了: 数据目录权限 。这是 “mongodb 启动不了” 问题的头号元凶。

sudo mkdir -p /var/lib/mongodb
sudo chown -R mongodb:mongodb /var/lib/mongodb
sudo chmod 0755 /var/lib/mongodb

chown 必须是 mongodb:mongodb ,不能是 root:root ,也不能是 deploy:deploy 。MongoDB 服务是以 mongodb 用户身份运行的,它必须对数据目录有完全的读写权限。 chmod 0755 是为了确保目录可进入、可列出,这是 Linux 的基本权限常识。

接着,编辑主配置文件 /etc/mongod.conf 。默认配置有很多坑,必须修改:

# /etc/mongod.conf
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
# 关键:绑定到本地,禁止外网访问
net:
  port: 27017
  bindIp: 127.0.0.1
# 关键:启用认证(可选,但强烈建议)
security:
  authorization: enabled
# 关键:日志配置,便于排查
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
  verbosity: 0

bindIp: 127.0.0.1 是安全红线。如果不加这一行,MongoDB 默认监听 0.0.0.0 ,意味着任何能访问你服务器 IP 的人都可以连接数据库,这是赤裸裸的安全漏洞。 authorization: enabled 开启认证后,你需要为 admin 数据库创建管理员用户,但这一步我们放到应用部署后再做,避免初始配置过于复杂。

最后,启动服务并设为开机自启:

sudo systemctl daemon-reload
sudo systemctl enable mongod
sudo systemctl start mongod
sudo systemctl status mongod # 检查状态,输出应为 "active (running)"

如果 status 显示 failed ,立刻看日志: sudo tail -100 /var/log/mongodb/mongod.log 。90% 的问题都能在这里找到线索,比如 Permission denied (权限不对)、 Address already in use (端口被占)、 Failed to create directory (目录不存在)。

3.3 Node.js 与 npm 安装:绕过 apt,拥抱 nvm 的灵活性

Ubuntu 14.04 自带的 Node.js 是 v0.10.25,太老了。 apt-get install nodejs 会装一个叫 nodejs-legacy 的包,它把 node 命令链接到 /usr/bin/nodejs ,导致很多脚本找不到 node 。所以,我们放弃 apt,用 nvm(Node Version Manager)。

切换到 deploy 用户,安装 nvm:

su - deploy
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# 重新加载 .bashrc
source ~/.bashrc

nvm 的好处是:它可以为不同项目安装不同版本的 Node.js,互不干扰。我们为 MEAN.JS 项目安装 v0.12.18:

nvm install 0.12.18
nvm use 0.12.18
nvm alias default 0.12.18

nvm alias default 这一步很重要,它确保每次新打开终端, node 命令默认指向 v0.12.18。验证:

node -v # 应输出 v0.12.18
npm -v  # 应输出 2.15.11

npm 的版本也必须匹配。v0.12.18 对应的 npm 是 v2.15.x,如果 npm -v 输出的是 v3.x 或更高,说明 nvm 没装对,需要用 nvm install --reinstall-packages-from=0.12.18 0.12.18 重新安装。

注意:nvm 是用户级的,它只对当前用户生效。 sudo npm install -g 是无效的,因为 sudo 切换到了 root 用户,而 root 用户没有安装 nvm。所有全局安装(如 grunt-cli )都必须在 deploy 用户下,用 npm install -g 执行。

3.4 MEAN.JS 应用骨架生成与依赖安装:Grunt、Bower 与网络代理

现在, deploy 用户已经有了正确的 Node.js 和 npm,我们可以生成 MEAN.JS 应用了。首先,全局安装 MEAN.JS 的 CLI 工具和 Grunt:

npm install -g mean-cli grunt-cli bower

mean-cli 是生成器, grunt-cli 是任务运行器, bower 是前端包管理器(AngularJS 1.x 时代的标准)。注意, bower 必须全局安装,否则 mean init myApp 会报错。

生成应用:

mean init myApp
cd myApp
npm install

npm install 会安装所有后端依赖(Express, Mongoose 等)。但此时,前端依赖(AngularJS, Bootstrap)还没装,因为它们由 bower 管理。运行:

bower install

这里极大概率会失败,报错 ECMDERR Failed to execute "git ls-remote --tags --heads https://github.com/angular/bower-angular.git" 。原因?GitHub 的 git 协议被墙了。解决方案是把 bower 的默认源从 git:// 切换到 https://

bower config set registry https://bower.herokuapp.com
bower config set strict-ssl false

strict-ssl false 是为了绕过某些自签名证书问题,生产环境不建议,但 Ubuntu 14.04 的 OpenSSL 版本太老,经常握手失败,这是权宜之计。

安装完所有依赖,我们来启动应用:

grunt

Grunt 会启动 Express 服务器,默认监听 http://localhost:3000 。如果一切顺利,你应该能在浏览器里看到 MEAN.JS 的欢迎页。但别急着庆祝,这只是开发模式。生产环境,我们需要用 forever pm2 守护进程,让应用在后台稳定运行。

3.5 生产环境守护:用 forever 让 Node.js 服务永不掉线

grunt 启动的是开发服务器,它会监听文件变化并自动重启,但一旦你关闭终端,进程就结束了。生产环境需要一个真正的进程管理器。 pm2 很好,但它在 Ubuntu 14.04 上对 Node.js v0.12 的支持不够稳定。所以我选择 forever ,它轻量、成熟、专为 Node.js 设计。

deploy 用户下全局安装:

npm install -g forever

然后,用 forever 启动应用:

forever start server.js

server.js 是 MEAN.JS 应用的入口文件。 forever 会自动将进程守护在后台,并生成日志文件。查看进程状态:

forever list

输出类似:

info:    Forever processes running
data:        uid  command         script          forever pid   id logfile                         uptime
data:    [0] eJQk /usr/local/bin/node server.js 22121   22124    /home/deploy/.forever/eJQk.log 0:0:12:12.123

logfile 字段告诉你日志在哪, uptime 告诉你它跑了多久。如果应用崩溃, forever 会自动重启它,并在日志里记录崩溃堆栈。这才是生产环境该有的样子。

实操心得:我曾经遇到过 forever 启动后, forever list 看不到进程的情况。排查发现,是因为 server.js 里有一行 process.env.NODE_ENV = 'production' ,而 forever 启动时没有加载 .env 文件。解决方案是用 forever start -e NODE_ENV=production server.js 显式传入环境变量。这个细节,官方文档不会写,但它是线上稳定的保障。

4. 实操过程与核心环节实现:从零开始,一步步搭建一个可运行的 MEAN.JS 应用

4.1 创建管理员用户:给 MongoDB 加上第一道锁

前面我们在 /etc/mongod.conf 里开启了 authorization: enabled ,但此时 MongoDB 还没有任何用户,所有连接都会被拒绝。我们必须创建一个 root 级别的管理员。

首先,临时关闭认证,连接到 MongoDB shell:

# 编辑 /etc/mongod.conf,注释掉 security.authorization 行
sudo nano /etc/mongod.conf
# 重启 mongod
sudo systemctl restart mongod
# 连接
mongo

在 MongoDB shell 里,执行:

use admin
db.createUser({
  user: "admin",
  pwd: "your_strong_password_here",
  roles: [ { role: "root", db: "admin" } ]
})

your_strong_password_here 请替换成一个真正强壮的密码。创建完成后,把 /etc/mongod.conf 里的 security.authorization 行取消注释,再次重启 mongod

现在,应用要连接 MongoDB,就不能再用 mongodb://localhost:27017/mydb 这种裸连接字符串了,而必须带上用户名和密码:

// config/env/all.js
module.exports = {
  db: 'mongodb://admin:your_strong_password_here@localhost:27017/mydb'
};

这个连接字符串的格式是固定的: mongodb://<username>:<password>@<host>:<port>/<database> 。漏掉任何一个部分,Mongoose 都会连接失败,并抛出 MongoError: auth failed

4.2 配置应用环境:区分开发、测试、生产

MEAN.JS 的配置是分环境的,位于 config/env/ 目录下。 all.js 是所有环境共享的配置, development.js production.js 是各自特有的。

最关键的配置是数据库连接和端口:

// config/env/production.js
module.exports = {
  port: 80,
  db: 'mongodb://admin:your_strong_password_here@localhost:27017/mean-prod',
  // 其他配置...
};

port: 80 是为了让应用直接通过 http://your-server-ip 访问,而不是 http://your-server-ip:3000 。但注意,Node.js 默认不能监听 1024 以下的端口,除非以 root 身份运行。我们不这么做,而是用 Nginx 做反向代理。

4.3 Nginx 反向代理:让 Node.js 安全地暴露在公网上

直接让 Node.js 监听 80 端口是危险的。Node.js 不是为高并发、静态文件服务而生的,它应该专注于业务逻辑。Nginx 才是处理 HTTP 请求、SSL 终止、负载均衡、静态资源缓存的专家。

安装 Nginx:

sudo apt-get install -y nginx

创建一个站点配置文件 /etc/nginx/sites-available/meanjs

upstream meanjs_backend {
  server 127.0.0.1:3000;
}
server {
  listen 80;
  server_name your-domain.com;
  client_max_body_size 10M;
  location / {
    proxy_pass http://meanjs_backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $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;
  }
  location /assets/ {
    alias /opt/meanjs/myApp/public/dist/assets/;
  }
}

upstream 定义了后端 Node.js 服务的地址( 127.0.0.1:3000 )。 location / 块把所有请求转发给它。 proxy_set_header 系列指令至关重要,它们把原始请求的客户端 IP、协议(HTTP/HTTPS)、Host 头等信息传递给 Node.js,否则 req.ip 会变成 127.0.0.1 req.protocol 会变成 http (即使你用 HTTPS 访问)。

启用这个站点:

sudo ln -s /etc/nginx/sites-available/meanjs /etc/nginx/sites-enabled/
sudo nginx -t # 测试配置语法
sudo systemctl reload nginx

现在,访问 http://your-server-ip ,你应该能看到 MEAN.JS 的欢迎页,而 forever 进程依然在 3000 端口安静地运行着。Nginx 在前面挡着,Node.js 在后面干活,各司其职,安全又高效。

4.4 SSL 加密:用 Let's Encrypt 让网站变绿

没有 HTTPS 的网站,在现代浏览器里会被标记为“不安全”。Let's Encrypt 提供免费的 SSL 证书,而且自动化程度很高。

安装 Certbot:

sudo apt-get install -y python-letsencrypt-nginx

为你的域名申请证书(假设你的域名是 myapp.example.com ,并已解析到服务器 IP):

sudo letsencrypt --nginx -d myapp.example.com

Certbot 会自动修改 Nginx 配置,添加 HTTPS 监听,并重定向 HTTP 到 HTTPS。它还会自动设置证书续期的 cron 任务。整个过程,你只需要按几次回车。

验证:

sudo nginx -t
sudo systemctl reload nginx

现在,访问 https://myapp.example.com ,地址栏应该显示绿色的锁图标。这意味着所有传输的数据(包括登录密码、用户信息)都是加密的,这是上线前的最后一步,也是最重要的一步。

4.5 日志集中管理:把所有碎片日志收拢到一处

一个 MEAN.JS 应用会产生至少三类日志:

  • MongoDB 日志: /var/log/mongodb/mongod.log
  • Node.js 应用日志: forever 生成的 ~/.forever/*.log
  • Nginx 访问日志: /var/log/nginx/access.log

分散查看效率极低。我习惯用 rsyslog 把它们统一收集到 /var/log/meanjs/ 目录下。

创建日志目录:

sudo mkdir -p /var/log/meanjs
sudo chown syslog:adm /var/log/meanjs

配置 rsyslog,在 /etc/rsyslog.d/50-meanjs.conf 里添加:

# MongoDB logs
$InputFileName /var/log/mongodb/mongod.log
$InputFileTag mongod:
$InputFileStateFile stat-mongod
$InputRunFileMonitor
# Node.js logs (forever)
$InputFileName /home/deploy/.forever/*.log
$InputFileTag nodejs:
$InputFileStateFile stat-nodejs
$InputRunFileMonitor
# Nginx logs
$InputFileName /var/log/nginx/access.log
$InputFileTag nginx-access:
$InputFileStateFile stat-nginx-access
$InputRunFileMonitor

重启 rsyslog:

sudo systemctl restart rsyslog

现在,所有日志都会被实时捕获,并按标签分类。你可以用一条命令查看所有相关日志:

sudo tail -f /var/log/meanjs/*.log

当问题发生时,你不再需要在三个不同的终端里 tail 三个不同的文件,而是在一个窗口里,看着所有组件的日志同步滚动,故障关联性一目了然。

5. 常见问题与排查技巧实录:那些年,我们一起踩过的坑

5.1 MongoDB 启动失败:从权限到端口的全链路排查

这是最高频的问题。 sudo systemctl status mongod 显示 failed ,但日志里只有一句 Failed to start mongod.service: Unit mongod.service not found 。别慌,这是 systemd 没有识别到服务单元。解决方案是:

sudo systemctl daemon-reload
sudo systemctl enable mongod

如果 status 显示 active (exited) ,那说明服务启动了但立刻退出了,这是典型的配置错误。看日志:

sudo tail -50 /var/log/mongodb/mongod.log

常见错误及解决:

错误日志片段 原因 解决方案
Permission denied /var/lib/mongodb 目录权限不对 sudo chown -R mongodb:mongodb /var/lib/mongodb
Address already in use 27017 端口被其他程序占用 sudo lsof -i :27017 找出进程并 kill
Failed to create directory /var/lib/mongodb 目录不存在 sudo mkdir -p /var/lib/mongodb
child process failed, exited with error number 100 配置文件语法错误 sudo mongod --config /etc/mongod.conf --dryrun 测试配置

实操心得:我曾经在一个客户服务器上, mongod 总是启动失败,日志里只有 ERROR: child process failed, exited with error number 100 。反复检查配置、权限、端口,都没问题。最后发现,是 /var/lib/mongodb 目录的父目录 /var/lib 的权限是 0700 mongodb 用户无法进入 /var/lib ,自然也无法访问 /var/lib/mongodb 。解决方案是 sudo chmod 0755 /var/lib 。这个坑,教科书里不会写,只有在真实世界里摔过跤才会懂。

5.2 Node.js 应用无法连接 MongoDB:认证、网络、防火墙三重门

forever list 显示应用在运行,但浏览器打不开,或者打开后一片空白。第一步,看应用日志:

forever logs 0 # 0 是 forever list 里显示的 id

如果日志里有 MongoError: failed to connect to server [localhost:27017] on first connect ,说明连接被拒。原因有三:

  1. 认证失败 :检查 config/env/production.js 里的 db 字符串,用户名、密码、数据库名是否拼写正确。特别注意,密码里如果有特殊字符(如 @ , / , : ),必须进行 URL 编码。例如,密码 p@ss/w0rd 要写成 p%40ss%2Fw0rd

  2. 网络不通 :虽然都在 localhost ,但也要确认 mongod 服务确实在监听 127.0.0.1:27017

    sudo netstat -tulpn | grep :27017
    

    正常输出应该是 tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 1234/mongod 。如果显示 0.0.0.0:* ,说明 bindIp 配置没生效。

  3. 防火墙拦截 :Ubuntu 14.04 默认没有开启 ufw,但如果你手动开启了,需要放行端口:

    sudo ufw allow 27017
    

5.3 AngularJS 页面白屏:前端资源加载失败的终极诊断法

页面打开后,Network 面板里全是 404, /assets/js/application.js 找不到。这通常是因为 grunt build 没有成功执行,或者 Nginx 的 location /assets/ 配置路径写错了。

诊断步骤:

  1. 在服务器上,手动访问 http://localhost:3000/assets/js/application.js ,看能否下载到文件。如果能,说明应用本身没问题,是 Nginx 配置问题。

  2. 如果 localhost:3000 也 404,说明 grunt build 没生成 public/dist 目录。进入 myApp 目录,手动运行:

    grunt build
    

    这个命令会把所有前端资源(JS, CSS, 图片)压缩、合并、版本化,放到 public/dist 下。 grunt build 失败,最常见的原因是 bower install 没成功,或者 node_modules 里某个包版本冲突。

  3. 如果 grunt build 成功,但 Nginx 还是 404,检查 alias 路径是否正确。 alias 的末尾不能有 / ,`/opt/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值