游客发表

把web应用程序部署到目录

发帖时间:2026-10-17 04:43:33

把 Flask 应用塞进 /var/www/myapp 这种目录里跑,把w部署和直接在本机 5000 端口裸奔,应用完全是程序两码事。去年帮朋友调一个 Django 项目,到目他图省事把代码扔在 /root/project 下,把w部署用 root 跑 gunicorn,应用结果一次依赖升级把系统 Python 搞崩了。程序目录选不对,到目后面全是把w部署坑。

Web 应用部署到目录,应用核心就一件事:让 Web 服务器(Nginx、程序Apache 或 Caddy)知道去哪里找你的到目应用入口,同时保证那个目录的把w部署权限、路径、应用依赖都干净可控。程序这不是复制粘贴几个文件就完事的操作。

先想清楚“目录”指什么

有人说的目录是代码存放位置,比如 /srv/myapp;有人指的是 URL 路径前缀,比如 https://example.com/app/。这两个经常被混在一起聊,但处理方式完全不同。

代码目录的选择有讲究。/var/www 是 Debian 系的老传统,/srv 更符合 FHS 标准,/opt 适合第三方独立应用。我个人的习惯是用 /srv/<appname>,权限设成 www-data:www-data,代码属主单独一个部署用户。这样 Nginx 能读静态文件,应用进程能写日志和缓存,但谁都不能随便改代码。

URL 路径前缀更麻烦。Flask 的 APPLICATION_ROOT、Django 的 FORCE_SCRIPT_NAME、前端构建时的 publicPath,三个地方对不齐,页面就白屏或者 404。我见过最离谱的案例是前端资源全部 404,查了半天发现是 Vite 构建时 base 没改,Nginx 的 location /app/ 又没做 rewrite。

Nginx 配置里的目录映射

假设应用跑在 127.0.0.1:8000,想通过 /myapp/ 访问。Nginx 配置大概长这样:

location /myapp/ {  proxy_pass http://127.0.0.1:8000/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Prefix /myapp; } location /myapp/static/ {  alias /srv/myapp/static/; expires 30d; }

proxy_pass 末尾那个斜杠很关键。带斜杠,Nginx 会把 /myapp/foo 转成 /foo 发给后端;不带,后端收到的是 /myapp/foo。选哪个取决于你的应用是否感知路径前缀。FastAPI 用 root_path,Flask 用中间件,Django 用 FORCE_SCRIPT_NAME,各家方案不一样。

静态文件的 alias 和 root 也容易搞混。alias 是替换匹配到的路径部分,root 是拼接。用 alias /srv/myapp/static/ 时,请求 /myapp/static/css/app.css 会映射到 /srv/myapp/static/css/app.css。用 root /srv/myapp 的话,实际找的是 /srv/myapp/myapp/static/css/app.css,多了一层。这个细节坑过不少人。

应用进程的工作目录

systemd 服务文件里 WorkingDirectory 不写,默认是 /。有些应用用相对路径读配置文件,比如 ./config.yaml,工作目录不对就直接报错。更隐蔽的是 Python 的 sys.path,如果项目里有同名模块,工作目录会影响导入优先级。

[Service] WorkingDirectory=/srv/myapp ExecStart=/srv/myapp/venv/bin/gunicorn -w 4 -b 127.0.0.1:8000 app:app User=www-data Group=www-data

虚拟环境放在项目目录里,路径写绝对路径。别用 source venv/bin/activate 那套,systemd 不认 shell 语法。

权限和 SELinux 的坑

CentOS 或 RHEL 上 SELinux 开着的话,Nginx 读 /srv/myapp/static 会直接被拒。日志里报 Permission denied,但 ls -l 看权限明明是 755。这时候要 chcon -R -t httpd_sys_content_t /srv/myapp/static,或者干脆 setenforce 0 先验证是不是 SELinux 的问题。

Ubuntu 的 AppArmor 相对宽松,但如果你把应用放在 /home 下,也可能触发限制。部署目录尽量避开用户主目录,这是省事的做法。

目录选对了,路径映射对齐了,权限和上下文配好了,剩下的就是重启服务、看日志、调错。没什么高深技术,全是细节堆出来的稳定性。

    热门排行

    友情链接