✅ 纯命令行完整部署流程(无图形化/无Portainer)

适用环境:Ubuntu服务器、无防火墙/安全组权限、80端口可用、本地原生Nginx、多SpringBoot项目(前后端分离)、域名访问、纯Docker命令行操作

核心原则:全程 root 用户执行、所有命令复制即用、每步带【成功校验】、多项目彻底隔离无冲突、最终实现「域名+路径」访问所有项目


✅ 整体流程划分(5大核心流程,循序渐进,无任何冗余步骤)

流程一:服务器基础环境初始化(安装Docker+Docker-Compose+本地Nginx,必装依赖)

流程二:标准化目录结构搭建(多项目隔离、前后端分离,统一目录规范,避免混乱)

流程三:Docker容器化部署(SpringBoot后端+MySQL+Redis,纯docker-compose命令,持久化配置,本机通信无端口暴露)

流程四:本地Nginx反向代理核心配置(80端口唯一入口,多项目路由隔离、前后端请求转发,彻底解决跳转/跨域/访问问题)

流程五:域名解析+最终访问校验+运维常用命令(生产级维护,一键启停/日志查看/更新项目)


— 流程一:服务器基础环境初始化(基础依赖全装完,后续所有操作的前提)

核心说明:Ubuntu系统默认无Docker/Docker-Compose,Nginx按需安装;所有命令均为Ubuntu专属,无需任何图形化操作

1.1 更新服务器系统源+安装基础依赖

apt update && apt upgrade -y
apt install -y vim net-tools curl wget

1.2 卸载系统旧版本Docker(如有),避免冲突

apt remove -y docker docker-engine docker.io containerd runc

1.3 安装Docker官方稳定版+配置开机自启

# 安装Docker依赖
apt install -y ca-certificates curl gnupg lsb-release
# 添加Docker官方密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 配置Docker源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker核心组件
apt update && apt install -y docker-ce docker-ce-cli containerd.io
# 启动Docker+开机自启
systemctl start docker && systemctl enable docker

✅ 【成功校验1.3】Docker安装成功

docker --version && docker run hello-world
  • 成功标志:打印Docker版本号 + 输出 Hello from Docker! 相关内容,无报错

1.4 安装Docker-Compose(容器编排必备,管理多容器项目)

# 下载稳定版docker-compose
curl -L "https://github.com/docker/compose/releases/download/v2.24.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 赋予执行权限
chmod +x /usr/local/bin/docker-compose
# 建立软链接
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

✅ 【成功校验1.4】Docker-Compose安装成功

docker-compose --version
  • 成功标志:打印docker-compose版本号,无报错

1.5 安装本地原生Nginx(80端口唯一入口,核心转发组件,服务器必备)

apt install -y nginx
# 启动Nginx+开机自启
systemctl start nginx && systemctl enable nginx

✅ 【成功校验1.5】Nginx安装启动成功

systemctl status nginx && curl http://127.0.0.1
  • 成功标志:状态显示 active (running) + curl返回Nginx默认欢迎页HTML内容

— 流程二:标准化目录结构搭建(多项目隔离+前后端分离,重中之重,杜绝混乱)

核心说明

  1. 所有项目统一放在 /opt/ 目录下,分为【前端目录】和【后端目录】,彻底分离
  2. 每个SpringBoot项目独立一个文件夹,包含:后端jar包、docker-compose.yml、数据库/Redis持久化目录,互不干扰
  3. 所有目录权限全开,避免Docker挂载/访问权限问题
  4. 示例:本次搭建2个SpringBoot项目 gy-booking(预约系统) + oa-system(办公系统),适配「多项目」场景,可无限扩展

2.1 创建全局统一根目录(所有项目的父目录)

# 前端静态文件根目录(所有项目的前端打包文件都放这里)
mkdir -p /opt/frontend && chmod -R 777 /opt/frontend
# 后端项目根目录(所有项目的后端Docker配置都放这里)
mkdir -p /opt/backend && chmod -R 777 /opt/backend

2.2 创建单个项目的标准化目录(示例:gy-booking 预约系统,复制可创建多个项目)

# ========== 项目1:gy-booking 预约系统 ==========
mkdir -p /opt/backend/gy-booking/{app,mysql/conf,mysql/data,mysql/init,redis/conf,redis/data}
mkdir -p /opt/frontend/gy-booking
# ========== 项目2:oa-system 办公系统(多项目扩展示例) ==========
mkdir -p /opt/backend/oa-system/{app,mysql/conf,mysql/data,mysql/init,redis/conf,redis/data}
mkdir -p /opt/frontend/oa-system

2.3 上传项目文件到对应目录(纯命令行/ftp工具均可,核心路径对应)

# 1. 后端:将SpringBoot打包好的 app.jar 上传至【对应项目】的app目录
# 例:gy-booking的jar包 → /opt/backend/gy-booking/app/app.jar
# oa-system的jar包 → /opt/backend/oa-system/app/app.jar
# 2. 前端:将前端打包好的静态文件(Vue/React打包后的dist目录所有文件)上传至前端目录
# 例:gy-booking的前端 → /opt/frontend/gy-booking/
# oa-system的前端 → /opt/frontend/oa-system/
# 3. 可选:上传mysql初始化sql、redis.conf配置文件到对应目录

✅ 【成功校验2.3】文件上传成功

# 校验后端jar包是否存在
ls -l /opt/backend/gy-booking/app/app.jar
# 校验前端文件是否存在
ls -l /opt/frontend/gy-booking/index.html
  • 成功标志:能看到对应文件,无 No such file or directory 报错

✅ 目录结构规范(必看,所有项目通用,记死)

/opt
├── frontend/ # 所有项目前端静态文件根目录
│ ├── gy-booking/ # gy-booking项目前端(Vue/React打包文件)
│ └── oa-system/ # oa-system项目前端
└── backend/ # 所有项目后端Docker根目录
├── gy-booking/ # gy-booking项目后端
│ ├── app/ # 存放springboot的app.jar
│ ├── mysql/ # mysql持久化目录(配置/数据/初始化sql)
│ └── redis/ # redis持久化目录(配置/数据)
└── oa-system/ # oa-system项目后端(同gy-booking结构)

— 流程三:Docker容器化部署(SpringBoot+MySQL+Redis,纯命令行,无Portainer,核心流程)

核心说明

  1. 每个项目独立编写 docker-compose.yml多项目完全隔离,启停互不影响
  2. 所有容器的端口均映射到 127.0.0.1(本机回环地址),不暴露外网端口 → 无需防火墙/安全组权限,彻底规避端口占用/访问限制
  3. 配置MySQL/Redis持久化挂载,容器删除后数据不丢失,生产级必备
  4. SpringBoot项目无需修改任何配置(端口默认8080,上下文路径如/gy-booking)
  5. 纯docker-compose命令操作,一键启动/停止/重启/查看日志,无图形化

3.1 编写项目的docker-compose.yml(纯命令行vim编写,核心配置,复制即用)

示例:gy-booking项目的docker-compose.yml(路径:/opt/backend/gy-booking/docker-compose.yml)

vim /opt/backend/gy-booking/docker-compose.yml

粘贴以下配置(无需修改,直接用,生产级稳定版,适配所有SpringBoot项目):

version: '3.8'
services:
# SpringBoot后端服务
app:
image: openjdk:17-jre-slim
restart: always
volumes:
- ./app:/app
environment:
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on:
- mysql
- redis
command: java -jar /app/app.jar
# 核心:仅本机访问,映射到127.0.0.1,不暴露外网
ports:
- "127.0.0.1:8081:8080"
networks:
- gy-network

# MySQL数据库
mysql:
image: mysql:8.0
restart: always
volumes:
- ./mysql/conf:/etc/mysql/conf.d
- ./mysql/data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=gy_booking
networks:
- gy-network

# Redis缓存
redis:
image: redis:7.0
restart: always
volumes:
- ./redis/conf/redis.conf:/etc/redis/redis.conf
- ./redis/data:/data
command: redis-server /etc/redis/redis.conf
networks:
- gy-network

# 独立网络,项目间隔离,避免容器通信冲突
networks:
gy-network:
driver: bridge

3.2 启动项目容器(纯命令行,一键启动,核心命令)

# 进入项目目录
cd /opt/backend/gy-booking
# 构建+启动容器(后台运行,首次启动加--build,后续无需)
docker-compose up -d --build

3.3 多项目扩展:重复3.1-3.2步骤,编写其他项目的docker-compose.yml并启动即可,无冲突

✅ 容器相关核心命令(纯命令行,必备,所有项目通用)

# 1. 查看当前项目容器运行状态
docker-compose ps
# 2. 查看SpringBoot启动日志(排查项目启动报错)
docker-compose logs -f app
# 3. 重启当前项目所有容器
docker-compose restart
# 4. 停止当前项目所有容器(不删除数据)
docker-compose stop
# 5. 停止并删除当前项目所有容器(数据持久化目录不会删除)
docker-compose down
# 6. 查看服务器所有容器状态
docker ps -a

✅ 【成功校验3.2】容器部署启动成功

# 校验容器状态
docker-compose ps
# 本机访问SpringBoot接口,验证是否启动成功
curl http://127.0.0.1:8081/gy-booking/role/getList
  • 成功标志:
    1. docker-compose ps 显示所有容器状态为 Up
    2. curl返回接口JSON数据(无超时/拒绝),无报错
  • 核心关键:本机能访问,外网访问不到 → 正常,后续由Nginx转发

— 流程四:本地Nginx反向代理核心配置(80端口唯一入口,多项目隔离,域名访问核心,无任何权限要求)

核心说明【重中之重,解决所有访问问题】

  1. 服务器仅开放80端口,所有外部请求通过80端口进入,由Nginx统一转发,无需防火墙/安全组权限
  2. 核心价值:Nginx通过「路径前缀」实现多项目彻底隔离,不同项目对应不同路径,互不干扰,完美解决原有项目跳转问题
  3. 前后端分离转发规则
    • 前端:Nginx直接读取本地静态文件,速度最快
    • 后端:Nginx将请求本机内部转发到SpringBoot容器的本机端口,无外网暴露,无超时
  4. 配置中加入「防跳转/防污染」指令,彻底屏蔽服务器原有项目的跳转规则,你的项目绝对不会被强制跳转登录页
  5. 所有配置为生产级最优配置,包含跨域、IP透传、Cookie/Session保持、静态文件缓存,缺一不可

4.1 Nginx核心规则:不修改原有配置,新增独立配置文件(最佳实践,不影响其他项目)

# 进入Nginx自定义配置目录(Ubuntu固定路径)
cd /etc/nginx/conf.d
# 创建多项目转发配置文件(核心配置文件,所有项目的转发规则都写这里)
vim all-projects.conf

4.2 粘贴【完整无错的Nginx多项目转发配置】(直接复制,一行不改,生产级稳定版,前后端分离+多项目隔离)

# 服务器唯一入口:80端口 + 公网IP + 域名,所有项目共用一个server即可
server {
listen 80;
server_name 106.15.90.217 synyingx.cn; # 你的服务器公网IP + 绑定的域名

# ===================== 项目1:gy-booking 预约系统 【前后端分离完整配置】 =====================
# ★ 后端接口转发:外部访问 → 域名/gy-api/xxx → 转发到本机8081端口的SpringBoot后端
location /gy-api/ {
# 核心防跳转:终止所有后续跳转规则,彻底屏蔽原有项目的强制跳转,解决你的核心痛点
rewrite ^(.*)$ $1 break;
proxy_redirect off;
proxy_cookie_path off;
# 转发到gy-booking的SpringBoot容器本机地址
proxy_pass http://127.0.0.1:8081/gy-booking/;
# 必备请求头:解决跨域、IP获取、Cookie/Session失效、接口报错,缺一不可
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;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# ★ 前端页面转发:外部访问 → 域名/gy-web/ → 直接读取本地前端静态文件,前后端分离
location /gy-web/ {
root /opt/frontend;
index index.html index.htm;
# Vue/React history路由模式必备,解决刷新404问题
try_files $uri $uri/ /gy-web/index.html;
# 防跳转+静态文件缓存,提升访问速度
rewrite ^(.*)$ $1 break;
proxy_redirect off;
expires 30d;
}

# ===================== 项目2:oa-system 办公系统 【多项目扩展示例,复制即可新增】 =====================
location /oa-api/ {
rewrite ^(.*)$ $1 break;
proxy_redirect off;
proxy_pass http://127.0.0.1:8082/oa-system/; # 对应oa-system的本机端口
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /oa-web/ {
root /opt/frontend;
try_files $uri $uri/ /oa-web/index.html;
rewrite ^(.*)$ $1 break;
proxy_redirect off;
}

# ===================== 原有项目规则:完全保留,无任何修改 =====================
# 原有项目的请求会自动匹配原有配置,和你的新项目完全隔离,互不影响
}

4.3 校验Nginx配置语法+平滑重启Nginx(核心步骤,配置生效,不影响其他项目)

# 1. 校验配置语法是否正确(必做,有错误会精准提示,无错误则显示success)
nginx -t
# 2. 平滑重启Nginx,配置生效(关键:不中断现有服务,原有项目无感知)
systemctl reload nginx

✅ 【成功校验4.3】Nginx配置生效成功

systemctl status nginx
  • 成功标志:Nginx状态显示 active (running),无报错

✅ Nginx核心规则总结(终身受用,多项目隔离的底层逻辑)

  1. 精准前缀匹配location /前缀/ 只匹配以该前缀开头的请求,不同项目不同前缀,绝对无冲突
  2. 独立规则隔离:每个项目的前端/后端规则都是独立的,A项目的配置不会影响B项目
  3. 本机内部转发:Nginx转发是服务器本机通信,不走外网,无需防火墙放行,速度极快,永不超时

— 流程五:域名解析+最终访问校验+运维常用命令(收尾,生产级维护,一键搞定)

5.1 域名解析配置(无需服务器操作,域名控制台配置,1分钟搞定)

  • 操作平台:你的域名服务商控制台(阿里云/腾讯云/华为云)
  • 配置规则:添加一条【A记录】,将你的域名 synyingx.cn 解析到服务器公网IP 106.15.90.217
  • 生效时间:配置后1-5分钟生效,无需重启服务器/容器/Nginx

5.2 最终访问规则(核心!所有项目通用,无端口、无跳转、直接访问,域名访问成功的标准)

✅ 核心口诀:前端走 /项目-web 后缀,后端走 /项目-api 后缀,无端口号,直接域名访问

示例:gy-booking 预约系统(前后端分离)

  1. 前端页面访问地址:http://synyingx.cn/gy-web/
  2. 后端接口访问地址:http://synyingx.cn/gy-api/role/getList

示例:oa-system 办公系统(多项目扩展)

  1. 前端页面访问地址:http://synyingx.cn/oa-web/
  2. 后端接口访问地址:http://synyingx.cn/oa-api/user/getInfo

✅ 【终极成功校验】纯命令行+浏览器双校验(100%确认所有功能正常)

校验1:纯命令行校验(服务器本地访问,最精准)

# 校验后端接口是否正常返回数据
curl -X GET http://synyingx.cn/gy-api/role/getList
# 校验前端页面是否正常返回
curl http://synyingx.cn/gy-web/index.html
  • 成功标志:接口返回JSON业务数据,前端返回HTML代码,无超时/404/跳转

校验2:浏览器校验(外网访问,最终形态)

  • 打开浏览器,输入上述访问地址,能正常加载前端页面、调用后端接口、查询数据库数据,无跳转登录页、无超时、无跨域报错 → 部署成功!

5.3 生产级运维常用命令(纯命令行,所有操作一键搞定,无图形化,必备收藏)

✅ 一、Docker容器相关(项目启停/日志/更新,所有项目通用)

# 1. 进入指定项目目录(如gy-booking)
cd /opt/backend/gy-booking
# 2. 查看项目启动日志(排查接口报错)
docker-compose logs -f app
# 3. 重启项目容器(更新jar包后必用)
docker-compose restart app
# 4. 停止项目容器(维护时用)
docker-compose stop
# 5. 彻底重建容器(配置修改后必用)
docker-compose down && docker-compose up -d --build

✅ 二、Nginx相关(配置修改/重启/状态)

# 1. 校验Nginx配置语法
nginx -t
# 2. 平滑重启Nginx(配置修改后生效)
systemctl reload nginx
# 3. 查看Nginx运行状态
systemctl status nginx
# 4. 查看Nginx访问日志(排查转发问题)
tail -f /var/log/nginx/access.log

✅ 三、项目更新最简流程(前后端通用,1分钟搞定,无需复杂操作)

✔️ 后端更新(SpringBoot)
  1. 本地打包新的 app.jar → 上传覆盖 /opt/backend/项目名/app/app.jar
  2. 执行命令:cd /opt/backend/项目名 && docker-compose restart app → 生效
✔️ 前端更新(Vue/React)
  1. 本地打包新的前端静态文件 → 上传覆盖 /opt/frontend/项目名/ 下所有文件
  2. 执行命令:systemctl reload nginx → 生效(无需重启容器)

✅ 补充:多项目扩展极简方法(未来新增项目,仅需3步,1分钟搞定)

  1. 按流程二创建新项目的目录结构 → /opt/backend/新项目名 + /opt/frontend/新项目名
  2. 按流程三编写docker-compose.yml,启动容器(映射本机新端口如8083)
  3. 按流程四在Nginx的all-projects.conf中新增2个location规则(/新项目-api/ + /新项目-web/),重启Nginx即可

✅ 最终完美架构总结(无任何坑,生产级稳定,你的最终形态)

外网浏览器 → 域名(synyingx.cn) → 服务器80端口 → 本地Nginx反向代理
├─ 前端请求 → Nginx直接读取 /opt/frontend/项目名 静态文件 → 返回页面
└─ 后端请求 → Nginx本机转发 → 127.0.0.1:端口 → SpringBoot容器 → 返回接口数据
Docker容器:SpringBoot+MySQL+Redis 本机运行,无外网暴露,安全稳定

✅ 架构核心优势(完美适配你的所有限制)

  1. ✔️ 无防火墙/安全组权限:仅用80端口,无需开任何新端口
  2. ✔️ 多项目隔离:不同项目不同路径,互不干扰,无冲突
  3. ✔️ 前后端分离:前端静态文件独立部署,后端容器化运行,维护方便
  4. ✔️ 纯命令行操作:无图形化,所有操作可自动化,适合生产环境
  5. ✔️ 数据持久化:MySQL/Redis数据不丢失,项目更新无风险

✅ 常见问题排查(纯命令行,精准定位,无需额外工具)

  1. 接口访问超时:检查容器是否Up → docker-compose ps,检查本机是否能访问 → curl 127.0.0.1:8081/xxx
  2. 前端404:检查前端文件路径是否正确 → ls /opt/frontend/项目名/index.html,检查Nginx的root路径是否正确
  3. 接口404:检查SpringBoot上下文路径是否和Nginx的proxy_pass一致,检查接口路径拼写
  4. 被强制跳转登录页:确认Nginx配置中加了 rewrite ^(.*)$ $1 break; proxy_redirect off;,重启Nginx即可

🎉 至此,你已完成「从Docker安装到域名访问多项目」的全流程纯命令行部署,所有步骤均为生产级标准,无任何冗余,项目稳定运行,后续维护极简!恭喜你掌握了云服务器多项目部署的核心精髓! 🎉