嘿,老朋友。
我知道你现在的处境。CentOS 8 停服的日子像是一场突如其来的暴雨,把你精心搭建的服务器环境淋得透湿。以前那种 yum install 一把梭、重启即好的日子一去不复返,现在的你看着阿里云或腾讯云的后台,心里可能在犯嘀咕:换系统?怎么换?会不会把我的项目搞崩?
别慌。这封信就是写给你的。
AlmaLinux 9 不仅仅是 CentOS 的“平替”,它是社区驱动、企业级稳定的“正统继承者”。今天,我们不整那些虚头巴脑的理论,直接上干货。我会带你从零开始,在云服务器上搭建起 Nginx + Python + Node.js 的生产级环境,顺便把那些让人头秃的“坑”一个个填平。
准备好了吗?咱们开始。
第一章:为什么是 AlmaLinux 9?(给你的服务器换个“强心脏”)
在动手之前,你得先明白,我们为什么要抛弃 CentOS,拥抱 AlmaLinux。
很多人问我:“能不能继续用 CentOS 7?” 答案很残酷:不行,或者说不建议。 CentOS 7 内核版本太老(3.10),不支持很多现代特性(比如新的文件系统、更新的硬件驱动),而且社区支持已近尾声。而 CentOS Stream 虽然延续了红帽的脉络,但它是一个“滚动预览版”,对于追求绝对稳定的生产环境来说,偶尔的“意外”是老板们不愿接受的。
AlmaLinux 9 的优势在于:
- 二进制兼容 RHEL 9:它是 1:1 的二进制兼容,这意味着你在 CentOS 7⁄8 上写的很多脚本逻辑,迁移过来基本不用改。
- ELRepo 和 EPEL 支持更完善:相比 CentOS,Alma 对第三方仓库的兼容性做得更好。
- AppStream 模块流(Module Streams):这是 AlmaLinux 9(以及 RHEL 9、Rocky Linux 9)最大的变革。Python、Node.js、Ruby 这些语言不再像以前那样只有单一版本,你可以通过模块流轻松切换版本。
一句话总结:AlmaLinux 9 是你迁移后的“安全屋”,稳定、长久支持(到 2032 年),而且生态更现代。
第二章:开局第一步——安全初始化(别跳过这步!)
很多教程一上来就教装软件,这是大错特错。在云服务器上,裸奔是找死。
假设你刚刚在云厂商后台重置了 AlmaLinux 9 系统,拿到了初始密码或密钥。请用 SSH 登录进去:
ssh root@你的服务器IP
2.1 更新系统并清理缓存
# 更新所有系统包,确保漏洞补丁到位
dnf update -y
# 清理旧的依赖缓存,这能避免很多诡异的依赖冲突
dnf clean all
dnf makecache
2.2 配置防火墙(firewalld)
AlmaLinux 9 默认启用 firewalld。很多人(包括以前的我)习惯用 iptables,但在 RHEL 系的新版本中,firewalld 是标准。
# 启动并启用防火墙
systemctl enable --now firewalld
# 打开常用端口:HTTP(80), HTTPS(443), SSH(22)
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=ssh
# 如果你需要 Python Web 服务跑在 8000 端口,记得加这条
# firewall-cmd --permanent --add-port=8000/tcp
# 重载防火墙配置
firewall-cmd --reload
2.3 禁用 SELinux?别傻了,学会驾驭它
这是新手最大的坑之一! 网上很多教程说“直接关掉 SELinux 吧,省事”。错! 关掉 SELinux 会让你的服务器在面对 webshell 上传、越权访问时毫无还手之力。
在 AlmaLinux 9 上,我们推荐将 SELinux 设置为 Permissive(警告模式) 而不是 Disabled。这样既能保留保护机制,又能避免因权限问题导致服务启动失败。
# 查看当前状态
sestatus
# 临时设置为 Permissive(重启后失效,但立即生效)
setenforce 0
# 永久修改配置文件
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
专家提示:如果你的应用因为 SELinux 报 403 Forbidden,不要急着关它。用
audit2why查看被阻止的原因,然后用semanage fcontext和restorecon修复标签。这才是高手的做法。
2.4 创建普通用户(拒绝用 root 裸奔)
永远不要用 root 日常操作。创建一个运维用户:
# 创建用户 devops,并加入 wheel 组(拥有 sudo 权限)
useradd -m -s /bin/bash devops
usermod -aG wheel devops
# 设置密码
passwd devops
# 配置 SSH 免密登录(假设你本地有公钥)
ssh-copy-id devops@你的服务器IP
测试一下:用 devops 用户登录,尝试 sudo dnf update,确认权限正常。
第三章:一键部署脚本(Nginx + Python + Node.js)
接下来,我们要部署核心环境。为了让你能“一键搞定”,我写了一个 bash 脚本。这个脚本利用 AlmaLinux 9 的 AppStream 模块 特性,能灵活选择 Python 和 Node.js 的版本。
将以下代码保存为 setup_stack.sh:
#!/bin/bash
set -e # 遇到错误立即退出
echo "=========================================="
echo " AlmaLinux 9 全栈环境一键部署脚本"
echo " 支持: Nginx, Python 3.11, Node.js 20"
echo "=========================================="
# 检查是否以 root 运行
if [[ $EUID -ne 0 ]]; then
echo "请以 root 用户运行此脚本 (或使用 sudo)"
exit 1
fi
# 1. 安装基础工具和 EPEL 仓库
echo "[1/5] 安装基础依赖..."
dnf install -y epel-release
dnf install -y git curl wget vim net-tools unzip
# 2. 启用并安装 Python 3.11 (AlmaLinux 9 默认带 3.9,推荐 3.11)
echo "[2/5] 配置 Python 3.11..."
dnf module reset python3 -y
dnf module enable python311 -y
dnf install -y python311 python311-pip python311-devel
ln -sf /usr/bin/python3.11 /usr/bin/python3
ln -sf /usr/bin/pip3.11 /usr/bin/pip3
# 3. 启用并安装 Node.js 20 (LTS)
echo "[3/5] 配置 Node.js 20..."
dnf module reset nodejs -y
dnf module enable nodejs:20 -y
dnf install -y nodejs
# 4. 安装 Nginx
echo "[4/5] 安装 Nginx..."
dnf install -y nginx
systemctl enable --now nginx
# 5. 配置防火墙
echo "[5/5] 配置防火墙..."
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
echo "=========================================="
echo " 部署完成!"
echo " Python 版本: $(python3 --version)"
echo " Node.js 版本: $(node --version)"
echo " Nginx 状态: $(systemctl is-active nginx)"
echo "=========================================="
echo "请访问 http://你的服务器IP 查看 Nginx 默认页"
赋予执行权限并运行:
chmod +x setup_stack.sh
./setup_stack.sh
运行完毕后,浏览器访问你的服务器 IP,如果看到 “Welcome to nginx!“,恭喜,基础环境已经就绪。
第四章:深度解析——为什么用模块流(Module Streams)?
你可能注意到了,脚本里用了 dnf module。这是 AlmaLinux 9 与 CentOS 7⁄8 最大的不同。
在旧系统中,如果你想升级 Python,你可能得去官网下载源码编译,或者引入第三方仓库,这会导致依赖冲突,甚至搞挂系统自带的工具(因为 CentOS 7 的 yum 依赖 Python 2)。
在 AlmaLinux 9 中:
- 隔离性:Python 3.9(系统默认)和 Python 3.11(开发使用)可以共存。
- 切换便捷:通过
dnf module你可以轻松切换版本,而不需要手动编译。
常见操作命令:
# 查看所有可用的 Python 模块流
dnf module list python311
# 启用特定版本
dnf module enable python311 -y
# 如果不小心装错了,可以重置
dnf module reset python311 -y
对 Node.js 同理:你可以选择 Node.js 18 (LTS) 或 Node.js 20 (Current LTS),互不干扰。
第五章:实战部署——Python Flask 应用 + Nginx 反向代理
环境好了,怎么跑起来?我们用 Flask 做一个简单的例子。
5.1 编写 Flask 应用
创建项目目录:
mkdir -p /var/www/myapp
cd /var/www/myapp
创建 app.py:
from flask import Flask
import os
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from AlmaLinux 9 + Python Flask!"
@app.route('/status')
def status():
return "Nginx -> Gunicorn -> Flask 链路正常"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
安装依赖(注意使用之前配置好的 pip3.11):
pip3 install flask gunicorn
5.2 创建 systemd 服务管理 Gunicorn
不要用 python app.py 直接跑,生产环境必须用 Gunicorn。
创建服务文件 /etc/systemd/system/myapp.service:
[Unit]
Description=My Flask App
After=network.target
[Service]
User=devops
Group=www-data
WorkingDirectory=/var/www/myapp
Environment="PATH=/home/devops/.local/bin:/usr/bin"
ExecStart=/home/devops/.local/bin/gunicorn --workers 3 --bind unix:myapp.sock myapp:app
[Install]
WantedBy=multi-user.target
注意:由于我们用的是非 root 用户 devops 运行,且 pip 安装在用户目录下,所以路径指向了
/home/devops/.local/bin/gunicorn。启动服务前,请确保 devops 用户已经安装了 gunicorn,或者将 User 改为 root(不推荐)。
启动并启用服务:
systemctl daemon-reload
systemctl enable --now myapp
systemctl status myapp
检查服务状态,确保没有报错。如果报错 Permission denied,通常是 SELinux 或文件权限问题。
5.3 配置 Nginx 反向代理
创建配置文件 /etc/nginx/conf.d/myapp.conf:
server {
listen 80;
server_name _; # 或者写你的域名
location / {
include proxy_params;
proxy_pass http://unix:/var/www/myapp/myapp.sock;
}
}
测试并重载 Nginx:
nginx -t
systemctl reload nginx
现在,访问你的服务器 IP,应该能看到 “Hello from AlmaLinux 9 + Python Flask!“。
第六章:常见坑点排查指南(血泪总结)
部署过程中,99% 的问题都集中在以下几个方面。我把它们整理出来,帮你省下几个小时。
坑点 1:SELinux 阻止 Nginx 连接后端
现象:Nginx 返回 502 Bad Gateway,systemctl status nginx 显示正常,但 journalctl -xe 里有大量的 avc: denied 错误。
排查:
# 查看 SELinux 拒绝日志
audit2allow -w -a | grep nginx
解决:
# 允许 nginx 连接网络 socket(如果需要)
setsebool -P httpd_can_network_connect 1
# 或者,如果使用的是 unix socket,确保 sock 文件标签正确
restorecon -v /var/www/myapp/myapp.sock
坑点 2:Python 虚拟环境路径问题
现象:在终端里 pip install 能装,但 systemd 服务启动失败,报 ModuleNotFoundError。
原因:systemd 的服务环境非常干净,它不知道你的 ~/.local 路径下的 pip 包。
解决:
- 最佳实践:在系统级安装依赖,或者在
/etc/systemd/system/myapp.service中明确指定PATH。 - 或者:使用
venv激活脚本,并在ExecStart中调用 venv 里的 gunicorn:ExecStart=/var/www/myapp/venv/bin/gunicorn --workers 3 --bind unix:myapp.sock myapp:app
坑点 3:Node.js 模块编译失败
现象:安装 node-sass 或 bcrypt 等需要编译原生模块的包时失败,报 g++ 缺失。
解决: AlmaLinux 9 默认没有安装编译工具链。
dnf groupinstall -y "Development Tools"
dnf install -y python3-devel
坑点 4:firewalld 阻断了内部通信
现象:应用跑在 8080 端口,外部访问不了,但 localhost 可以。
解决:
# 开放 8080 端口
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
坑点 5:CentOS 脚本在 AlmaLinux 上“水土不服”
现象:以前用的 .spec 文件或 yum 命令报错。
解决:
- 将所有
yum替换为dnf(虽然 yum 还在,但 dnf 是推荐)。 - 检查路径变化:CentOS 7 的
/etc/init.d/服务现在应改为 systemd 服务(.service文件)。 - 注意 Python 版本:CentOS 7 默认 Python 2.7,AlmaLinux 9 默认 Python 3.9+。如果你的老脚本硬编码了
#!/usr/bin/python,记得修改或创建软链接。
第七章:运维小贴士——让服务器更稳定
部署只是开始,长期的维护才是关键。
定期更新:
dnf update -y --security设置 cron 任务每周自动检查更新。
监控资源: 安装
htop和netstat工具,或者使用node_exporter+ Prometheus 进行更专业的监控。日志轮转: Nginx 和 Gunicorn 的日志会随时间增长。配置
logrotate定期压缩和删除旧日志,防止磁盘写满。# 编辑 /etc/logrotate.d/nginx /var/log/nginx/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 nginx nginx sharedscripts postrotate [ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid) endscript }备份策略: 定期备份
/etc/nginx、你的应用代码和数据库。可以使用tar打包,上传到对象存储(如 AWS S3 或阿里云 OSS)。
结语:拥抱变化,保持冷静
从 CentOS 迁移到 AlmaLinux 9,表面上看只是换了一个系统镜像,但实际上,这是一次让你重新审视服务器架构、拥抱现代 Linux 生态的好机会。
不要害怕那些报错。每一个 Permission denied 背后,都藏着一个让你更懂 Linux 的机会。 当你搞定 SELinux 标签、调通 systemd 服务、看着 Nginx 流畅地反向代理你的 Python 应用时,你会感觉到一种作为运维人员的成就感。
AlmaLinux 9 是一个成熟、稳定、充满活力的平台。它不会像 CentOS 8 那样让你措手不及。只要你按照上述步骤,耐心配置,细心排查,你的云服务器将比以往更加安全、稳定。
现在,去试试那个一键脚本吧。如果遇到问题,记得先看日志,日志是系统给你的“情书”,虽然有时候写得有点隐晦。
祝部署顺利!如果有具体的报错信息,欢迎随时回来提问。
