Skip to content

标准 Web 服务目录结构

假设我们在 /data/web 下部署一个全栈项目(例如包含 Next.js 前端页面、NestJS 或 Go 编写的后端 API,以及相关的数据库和服务)。

Plaintext

/data/web/my_project/          # 项目主目录
├── docker-compose.yml         # 核心!统筹整个项目的容器编排文件
├── .env                       # 全局环境变量配置(数据库密码、API密钥等)

├── apps/                      # 1. 业务代码与构建区
│   ├── frontend/              # 前端应用 (如 Next.js) 源码或构建产物
│   │   ├── Dockerfile
│   │   └── package.json
│   ├── backend_api/           # 后端核心服务 (如 NestJS 或 Go 设定的 API)
│   │   ├── Dockerfile
│   │   └── main.go / main.ts
│   └── python_service/        # 独立的微服务 (如基于 FastAPI 的数据处理服务)

├── conf/                      # 2. 基础设施配置文件区
│   ├── nginx/
│   │   ├── nginx.conf         # Nginx 全局配置
│   │   ├── conf.d/            # 各个子域名的代理配置 (如 api.conf, web.conf)
│   │   └── ssl/               # HTTPS 证书存放处 (.crt, .key)
│   ├── redis/
│   │   └── redis.conf         # Redis 配置文件
│   └── mysql/
│       └── my.cnf             # 数据库配置文件

├── data/                      # 3. 持久化数据区 (绝对不能轻易删除!)
│   ├── mysql_data/            # MySQL 数据库的真实物理文件挂载点
│   ├── redis_data/            # Redis 持久化数据挂载点
│   └── uploads/               # 用户上传的静态文件、图片、自动生成的文档等

└── logs/                      # 4. 集中日志区
    ├── nginx/                 # Nginx 的 access.log 和 error.log
    ├── backend_api/           # 后端服务输出的业务日志
    └── mysql/                 # 数据库慢查询日志等

二、 为什么要这样设计?(设计哲学)

这种结构完美契合了容器化和现代化部署的需求,具体优势如下:

1. 极简的备份与迁移 (针对 data/conf/)

如果你使用的是类似 Proxmox VE 这样的虚拟化环境,或者需要跨云服务器迁移项目,你只需要打包 /data/web/my_project 这个文件夹(排除 apps/ 里的源码和 logs/)。 由于所有容器产生的数据都挂载在 data/ 目录下,配置文件都在 conf/ 目录下,迁移到新机器后,只需运行一句 docker-compose up -d,整个系统就能瞬间 1:1 恢复。

2. 无痛升级 (针对 apps/)

当你需要更新后端 API 时,你只需要在 apps/backend_api/ 下拉取最新的代码并重新构建镜像。因为数据存在 data/ 里,日志在 logs/ 里,所以你随时可以把旧的容器销毁掉并启动新容器,完全不用担心丢失业务数据(比如用户新上传的空气质量监测报表或微信支付的凭证)。

3. 快速排障 (针对 logs/)

当系统出现 502 报错或接口超时时,你不需要进入一个个 Docker 容器内部去大海捞针。所有的日志都已经通过 Docker Volume 映射到了宿主机的 logs/ 目录下。你可以直接在宿主机使用 tail -f logs/nginx/error.loggrep 命令快速定位问题。

4. 安全与权限隔离 (针对 .envconf/ssl/)

将敏感的环境变量和 SSL 证书统一放在特定的目录和文件中,可以很方便地通过 Linux 的 chmod 命令限制权限(例如设置 .env600,仅所有者可读写),防止其他非特权用户窃取数据库密码。


三、 实际部署落地建议

  1. 关于 Nginx 的位置:

    • 方式一(推荐): 将 Nginx 也作为一个 Docker 容器运行,并用 docker-compose 和其他业务放在一起网络互通。这时的配置如上图的 conf/nginx/
    • 方式二(传统): 直接在宿主机上通过 apt install nginx 安装 Nginx 作为最外层网关,将流量反向代理到本地的各个 Docker 端口。此时 Nginx 的配置依然放在宿主机的 /etc/nginx/ 中,而业务代码放在 /data/web/
  2. 创建专用执行用户: 为了安全,千万不要一直用 root 用户跑业务。建议在系统中创建一个名为 wwwdeploy 的用户: Bash

    useradd -m -s /bin/bash deploy
    chown -R deploy:deploy /data/web/my_project

    让这个用户加入 docker 用户组,专门负责该项目的启动和更新。

  3. CI/CD 预留: 在这个结构下,如果未来你引入了自动化发布(比如 GitHub Actions 或 n8n 的自动化工作流),脚本只需要做两件事:把新代码推送到 apps/ 下的对应目录,然后执行 docker-compose builddocker-compose up -d,整个过程非常清爽。