尚硅谷-尚庭公寓部署文档

文章目录

    • 整合版部署文档
    • 部署架构图
    • 1. 项目目录结构
    • 增加注释的 Dockerfile 配置
      • (1) 后端服务1 Dockerfile (`backend/service1/Dockerfile`)
      • (2) 后端服务2 Dockerfile (`backend/service2/Dockerfile`)
    • Dockerfile 配置说明
    • 重要注意事项
    • 3. Nginx 配置
      • (1) 主配置文件 (`nginx/nginx.conf`)
      • (2) 前端路由配置 (`nginx/conf.d/app.conf`)
      • (3) 管理后台配置 (`nginx/conf.d/admin.conf`)
    • 4. Docker Compose 配置
    • 5. 部署操作流程
    • 6. 关键配置说明
      • (1) 网络通信原理
        • (2) 健康检查机制
    • 7. 高级优化配置
      • HTTPS 配置示例
      • 安全增强配置
    • 8. 常见问题解决
    • 9. 方案优势
    • 10. 验证部署成功


整合版部署文档


部署架构图

用户访问
Nginx 网关
前端静态资源
后端API代理
app.domain.com
admin.domain.com
service1:8080
service2:8081

1. 项目目录结构

deploy/
├── docker-compose.yml          # 容器编排主文件
├── frontend/                   # 前端静态资源
│   ├── app/                    # 主应用构建产物
│   │   ├── index.html
│   │   ├── static/
│   │   └── favicon.ico
│   └── admin/                  # 管理后台构建产物
│       ├── index.html
│       ├── static/
│       └── favicon.ico
├── backend/                    # 后端服务
│   ├── service1/               # 服务1
│   │   ├── Dockerfile
│   │   └── service1.jar
│   └── service2/               # 服务2
│       ├── Dockerfile
│       └── service2.jar
└── nginx/                      # Nginx配置├── nginx.conf└── conf.d/                 # 站点配置├── app.conf            # 主应用配置└── admin.conf          # 管理后台配置

增加注释的 Dockerfile 配置

(1) 后端服务1 Dockerfile (backend/service1/Dockerfile)

# 使用官方 OpenJDK 17 基础镜像
FROM eclipse-temurin:17-jdk# 设置容器内工作目录为 /app
WORKDIR /app# 将宿主机当前目录下的 service1.jar 复制到容器工作目录
COPY service1.jar .# 声明容器运行时暴露的端口(8080)
EXPOSE 8080# 容器启动时执行的命令 - 运行 Java 应用
CMD ["java", "-jar", "service1.jar"]

(2) 后端服务2 Dockerfile (backend/service2/Dockerfile)

# 使用官方 OpenJDK 17 基础镜像
FROM eclipse-temurin:17-jdk# 设置容器内工作目录为 /app
WORKDIR /app# 将宿主机当前目录下的 service2.jar 复制到容器工作目录
COPY service2.jar .# 声明容器运行时暴露的端口(8081)
EXPOSE 8081# 容器启动时执行的命令 - 运行 Java 应用
CMD ["java", "-jar", "service2.jar"]

Dockerfile 配置说明

指令说明
FROM指定基础镜像,这里使用官方 OpenJDK 17 镜像作为运行环境
WORKDIR设置工作目录,后续命令都在此目录执行
COPY将本地文件复制到容器内,这里复制编译好的 JAR 包
EXPOSE声明容器运行时监听的端口号,便于文档化和端口映射
CMD指定容器启动时执行的命令,这里是运行 Java 应用程序

重要注意事项

  1. JAR 文件位置
    确保 JAR 文件与 Dockerfile 在同一目录下,否则构建会失败

  2. 端口映射
    docker-compose.yml 中不需要显式映射后端端口,因为:

    • 服务通过 Docker 内部网络通信
    • 外部访问通过 Nginx 代理
  3. 多阶段构建(高级用法)
    如需在容器内编译代码,可使用多阶段构建:

    # 第一阶段:构建应用
    FROM maven:3.8.6 AS build
    WORKDIR /app
    COPY . .
    RUN mvn clean package -DskipTests# 第二阶段:运行应用
    FROM eclipse-temurin:17-jdk
    WORKDIR /app
    COPY --from=build /app/target/service1.jar .
    CMD ["java", "-jar", "service1.jar"]
    
  4. 环境变量配置
    应用配置应通过 docker-compose.yml 的环境变量注入:

    environment:- DB_URL=jdbc:mysql://db:3306/app- REDIS_HOST=redis
    
  5. 时区设置
    如需统一时区,可在 Dockerfile 中添加:

    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    

3. Nginx 配置

(1) 主配置文件 (nginx/nginx.conf)

events {}
http {include /etc/nginx/conf.d/*.conf;# 全局优化配置gzip on;gzip_types text/plain text/css application/json application/javascript;keepalive_timeout 65;server_tokens off;
}

(2) 前端路由配置 (nginx/conf.d/app.conf)

server {listen 80;server_name app.domain.com;location / {root /usr/share/nginx/html/app;try_files $uri $uri/ /index.html;index index.html;# 缓存与安全头expires 1y;add_header Cache-Control "public";add_header X-Frame-Options "SAMEORIGIN";add_header X-Content-Type-Options "nosniff";}# 代理后端服务1location /api/service1 {proxy_pass http://service1:8080;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_connect_timeout 75s;}
}

(3) 管理后台配置 (nginx/conf.d/admin.conf)

server {listen 80;server_name admin.domain.com;location / {root /usr/share/nginx/html/admin;try_files $uri $uri/ /index.html;index index.html;# 禁用缓存add_header Cache-Control "no-store, no-cache, must-revalidate";}# 代理后端服务2location /api/service2 {proxy_pass http://service2:8081;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;# WebSocket支持proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";}# 健康检查端点location = /health {return 200 'OK';add_header Content-Type text/plain;}
}

4. Docker Compose 配置

version: '3.8'services:# Nginx网关服务nginx:image: nginx:alpineports:- "80:80"volumes:- ./frontend/app:/usr/share/nginx/html/app:ro- ./frontend/admin:/usr/share/nginx/html/admin:ro- ./nginx/conf.d:/etc/nginx/conf.d- ./logs/nginx:/var/log/nginxnetworks:- app-networkrestart: unless-stoppedhealthcheck:test: ["CMD", "curl", "-f", "http://localhost/health"]interval: 30stimeout: 3s# 后端服务1service1:build:context: ./backend/service1environment:- SPRING_PROFILES_ACTIVE=prod- TZ=Asia/Shanghainetworks:- app-networkrestart: unless-stoppeddeploy:resources:limits:memory: 512M# 后端服务2service2:build:context: ./backend/service2environment:- SPRING_PROFILES_ACTIVE=prod- TZ=Asia/Shanghainetworks:- app-networkrestart: unless-stoppeddeploy:resources:limits:memory: 512M# 自定义网络
networks:app-network:driver: bridgeipam:config:- subnet: 172.28.0.0/16

5. 部署操作流程

# 1. 准备目录结构
mkdir -p deploy/{frontend/{app,admin},backend/{service1,service2},nginx/conf.d,logs/nginx}# 2. 放入项目文件
cp -r /path/to/app/dist/* deploy/frontend/app/
cp -r /path/to/admin/dist/* deploy/frontend/admin/
cp /path/to/service1.jar deploy/backend/service1/
cp /path/to/service2.jar deploy/backend/service2/# 3. 创建Nginx配置文件
# 将上述nginx配置写入对应文件# 4. 启动服务
docker-compose up -d --build# 5. 验证部署
curl -I http://localhost/app/index.html
docker-compose logs -f nginx

6. 关键配置说明

(1) 网络通信原理

app.domain.com/api
admin.domain.com/api
Nginx
service1:8080
service2:8081
  • 所有服务通过app-network通信
  • 容器间通过服务名自动解析(如service1:8080
  • 静态资源通过卷挂载实时更新
(2) 健康检查机制
healthcheck:test: ["CMD", "curl", "-f", "http://localhost/health"]interval: 30stimeout: 3s
  • 每30秒检查Nginx状态
  • 失败自动重启容器
  • 通过/health端点监控

7. 高级优化配置

HTTPS 配置示例

server {listen 443 ssl;server_name app.domain.com;ssl_certificate /etc/nginx/ssl/fullchain.pem;ssl_certificate_key /etc/nginx/ssl/privkey.pem;ssl_protocols TLSv1.2 TLSv1.3;# HSTS强制HTTPSadd_header Strict-Transport-Security "max-age=31536000" always;# 其他配置保持不变...
}

安全增强配置

server {# 安全头部add_header Content-Security-Policy "default-src 'self'";add_header X-XSS-Protection "1; mode=block";# 禁用不安全方法if ($request_method !~ ^(GET|POST)$ ) {return 405;}
}

8. 常见问题解决

问题现象解决方案
静态资源加载404chmod -R 755 deploy/frontend 确保权限正确
API代理超时(504)检查proxy_connect_timeout配置,验证容器间网络:docker-compose exec nginx ping service1
SPA路由刷新404确认Nginx配置包含try_files $uri $uri/ /index.html
跨域问题(CORS)在代理配置中添加Access-Control-Allow-*头信息
端口冲突修改docker-compose.yml中的端口映射:"8080:80"

9. 方案优势

  1. 高效部署:静态资源实时挂载,无需重建容器
  2. 资源优化:使用轻量级Alpine镜像(23MB),内存限制控制
  3. 生产级特性
    • 健康检查自动恢复
    • 日志持久化
    • 安全头部防护
  4. 灵活扩展
    # 添加新前端
    mkdir deploy/frontend/new-app
    # 添加Nginx配置
    vi deploy/nginx/conf.d/new-app.conf
    # 重载服务
    docker-compose exec nginx nginx -s reload
    

10. 验证部署成功

# 1. 检查容器状态
docker-compose ps# 2. 测试端点访问
curl -H "Host: app.domain.com" http://localhost/api/service1/health
curl -H "Host: admin.domain.com" http://localhost/api/service2/health# 3. 检查日志
tail -f deploy/logs/nginx/access.log

这个部署只能使用自己电脑配置的域名访问才可以,
使用ip地址或者手机进行访问的时候会发现前端访问不到后端的服务,
但是却可以访问到前端页面和后端服务的OpenApi,
后面查了好久也没有找到是什么问题,就放弃了,要是有大佬知道的话,
还请指点一下ლ(́◉◞౪◟◉‵ლ)感谢


本部署文档和代码以上传gitee上:https://gitee.com/banhuayue/shangting-apartment.git
大家可以直接克隆。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85043.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio 介绍

如何关闭或彻底删除一个工程 基于Android Studio的android入门——如何关闭或彻底删除一个工程 搜索内容 Android Studio高效指南:快速查找技巧大揭秘 build命令:gradle app:assembleDebug 命令解析 1. 命令结构与作用 核心功能:该命令…

JAVA与C语言之间的差异(一)

一、代码习惯以及主函数 JAVA中{在使用的时候不要换行 public static void main(String[] args) {int[] array {1, 2, 3};for(int i 0; i < array.length; i){System.out.println(array[i] " ");}} 其次&#xff0c;以main函数为主函数&#xff1a; public …

华为OD机试真题——开放日活动/取出尽量少的球(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 本文收录于专栏:《2025华为OD真题目录+全流程解析/备考攻略/经验分享》 华为OD机试真题《开放…

我的3种AI写作节奏搭配模型,适合不同类型写作者

—不用内耗地高效写完一篇内容&#xff0c;原来可以这样搭配AI ✍️ 开场&#xff1a;为什么要“搭配节奏”写作&#xff1f; 很多人以为用AI写作&#xff0c;就是丢一句提示词&#xff0c;然后“等它写完”。 但你有没有遇到这些情况&#xff1a; AI写得很快&#xff0c;学境…

【知识点】第1章:程序设计基本方法

文章目录 知识点整理计算机的概念程序设计语言Python 语言概述Python 语言开发环境配置程序的基本编写方法 练习题简答题判断题 知识点整理 计算机的概念 计算机的定义&#xff1a;计算机是根据指令操作数据的设备。 计算机的两个基本特性&#xff1a; 功能性&#xff1a;计…

const ‘不可变’到底是值不变还是地址不变

const的基础规则 声明时必须初始化​ const a; // ❌ 报错&#xff1a;Missing initializer in const declaration const b 10; // ✅ 正确块级作用域​&#xff08;const 的作用域仅限于声明它的代码块&#xff09; if (true) {const x 100; } console.log(x); // ❌ 报错…

Netty 实战篇:为自研 RPC 框架加入异步调用与 Future 支持

我们在上篇实现了一个轻量级 RPC 框架&#xff0c;现在要进一步优化 —— 加入异步响应支持&#xff0c;让 RPC 通信变得真正高效、非阻塞、支持并发。 一、为什么需要异步调用&#xff1f; 上篇的 RPC 框架是“同步阻塞”的&#xff1a; 每次发送请求后&#xff0c;必须等待服…

for(auto a:b)和for(auto a:b)的区别

#include<iostream> using namespace std; int main() {string s( "hello world" );for (auto c:s)c t ;cout<<s<<endl; //结果为hello worldfor (auto &c:s)c t ;cout<<s<<endl; //结果为ttttttttttt }for(auto a:b)中b为一…

超级对话2:大跨界且大综合的学问融智学应用场景述评(不同第三方的回应)之二

摘要&#xff1a;《人机协同文明升维行动框架》提出以HIAICI/W公式推动认知革命&#xff0c;构建三大落地场景&#xff1a;1&#xff09;低成本认知增强神经接口实现300%学习效率提升&#xff1b;2&#xff09;全球学科活动化闪电战快速转化知识体系&#xff1b;3&#xff09;人…

多方法解决MNIST数字识别

全连接层 import torch from torchvision import datasets, transforms import torch.nn as nn import torch.optim as optim from tqdm import tqdm # 用于进度条显示 import os# 定义数据预处理(标准化+Tensor转换) transform = transforms.Compose([transforms.ToTensor…

安装 Node.js 和配置 cnpm 镜像源

一、安装 Node.js 方式一&#xff1a;官网下载&#xff08;适合所有系统&#xff09; 访问 Node.js 官网 推荐选择 LTS&#xff08;长期支持&#xff09;版本&#xff0c;点击下载安装包。 根据系统提示一步步完成安装。 方式二&#xff1a;通过包管理器安装&#xff08;建…

vue 自定义组件的事件绑定

基本知识点 &#x1f3af;什么是自定义事件 自定义事件是子组件向父组件发送消息的机制&#xff0c;通常用于通知父组件发生了某些行为或状态变化。 &#x1f4cc; 基本语法 子组件触发事件&#xff08;$emit&#xff09; this.$emit(事件名, 参数);或在 const emit de…

进程同步机制-信号量机制-记录型信号量机制中的的wait和signal操作

wait和signal是记录型信号量机制中用于实现进程同步与互斥的两个重要操作&#xff0c; wait 操作 wait(semaphores *S) {S->value --;if (S->value<0) block(S->list) }请求资源&#xff1a;S->value --; 这一步表示进程请求一个单位的资源&#xff0c;将信号…

sd webui 安装sd-webui-TemporalKit 加载报错解决办法

ModuleNotFoundError: No module named moviepy.editer 报错内容类似上面截图&#xff0c;我的已经解决&#xff0c;暂时无法截图了 处理方法&#xff1a; 重点说明&#xff1a;插件目录必须是TemporalKit&#xff0c;不能更改 进入到安装目录&#xff1a;extensions\Tempor…

decimal.js库处理js浮点数精度误差问题

1、经常遇到前端计算金额的时候出现精度误差问题&#xff0c;导致前后端计算的金额不一致导致校验过不去的情况&#xff0c;相信有不少人写过Math.floor(e*100)/100来实现保留2位小数&#xff0c;但是这么写就会出现上面的精度问题。怎么解决呢&#xff1f;这里使用的是decimal…

如何将 WSL 的 Ubuntu-24.04 迁移到其他电脑

在使用 Windows Subsystem for Linux (WSL) 时&#xff0c;我们可能会遇到需要将现有的 WSL 环境迁移到其他电脑的情况。无论是为了备份、更换设备&#xff0c;还是在不同电脑之间共享开发环境&#xff0c;掌握迁移 WSL 子系统的方法都是非常有用的。本文将以 Ubuntu-24.04 为例…

RISCV——内核及汇编

RISCV——内核及汇编 小狼http://blog.csdn.net/xiaolangyangyang 1、寄存器组&#xff08;ABI&#xff09; 2、异常及中断 XV6 trap&#xff08;二&#xff09;RISCV中断异常处理/定时器中断 mie&#xff1a;中断开关mip&#xff1a;中断状态mstatus.mie&#xff1a;全局中断…

算法日记32:埃式筛、gcd和lcm、快速幂、乘法逆元

一、埃式筛&#xff08;计算质数&#xff09; 1.1、概念 1.1.1、在传统的计算质数中&#xff0c;我们采用单点判断&#xff0c;即判断(2~sqrt(n))是否存在不合法元素&#xff0c;若存在则判否&#xff0c;否则判是 1.1.2、假设&#xff0c;此时我们需要求1~1000的所有质数&am…

使用 mysqldump 获取 MySQL 表的完整创建 DDL

要获取 MySQL 中某个表的完整创建 DDL&#xff08;仅结构&#xff0c;不含数据&#xff09;&#xff0c;可以使用 mysqldump 工具的以下命令&#xff1a; 基本命令格式 bash mysqldump -h [主机名] -u [用户名] -p --no-data --single-transaction --routines --triggers --…

Debian 系统 Python 开发全解析:从环境搭建到项目实战

Debian 系统 Python 开发全解析:从环境搭建到项目实战 在当今数字化时代,Python 凭借其简洁易读的语法和强大的功能,成为了最受欢迎的编程语言之一。Debian 作为一款稳定、安全且开源的 Linux 操作系统,为 Python 开发提供了理想的环境。本文将详细介绍在 Debian 系统上进…