实战:Docker Compose 下 Nginx、Java、Mysql 和 Redis 服务协同部署(包含解决浏览器访问Linux部署服务器本地资源问题)

news2024/11/18 19:37:20

1. 背景

在该实战中,我们将探讨如何使用Docker Compose协同部署Nginx、Java、Mysql和Redis服务,实现一个视频上传与展示的应用。具体需求如下:

  • Java应用负责上传视频和图片资源到Nginx目录下,作为资源服务器。
  • Nginx服务作为静态资源服务器,通过URL访问已上传的视频和图片资源。
  • Java服务通过读取数据卷挂载的/data/init.properties文件获取服务器的IP地址,用于拼接资源的访问URL。

2. 实现步骤

2.1 配置Java应用读取服务器IP

我们使用Spring的@Profile注解和InitConfig类,读取部署时挂载的/data/init.properties文件,获取服务器IP。

拓展:优化,可以在项目所部署的服务器上,写一个获取服务器IP的脚本(Centos系统Docker获取宿主机IP地址,MAC地址,磁盘序列号和CPU序列号的shell脚本),然后java通过运行该脚本获取服务器IP,如果买了域名,那更好了,直接省掉拼接服务器IP的步骤。

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Profile({"pro", "docker"})
@Component
@Data
public class InitConfig {

    private String serverIp;

    @Bean
    public Map<String, String> loadLinuxConfig() {
        Properties prop = new Properties();
        try (InputStream in = new BufferedInputStream(Files.newInputStream(Paths.get("/data/init.properties")))) {
            prop.load(new InputStreamReader(in, StandardCharsets.UTF_8));
        } catch (IOException e) {
            log.error("Failed to load local configuration file InitConfig.properties", e);
        }

        Set<String> keySet = prop.stringPropertyNames();
        Map<String, String> configMap = new HashMap<>();
        for (String key : keySet) {
            String value = prop.getProperty(key);
            log.info("Configuration loaded: key={}, value={}", key, value);
            configMap.put(key, value);
        }

        serverIp = configMap.get("data.serverIp");

        return configMap;
    }
}

2.2编写init.properties文件

data.serverIp该key根据自己需求随意取名。

data.serverIp=192.168.xx.xx

2.3调整Java资源列表展示接口

返回列表给前端的时候,将获取到的服务器IP拼接到资源的Url中。

    @Autowired
    private VideoInfoMapper videoInfoMapper;
    @Autowired
    private InitConfig initConfig;
    /**
     * 获取资源视频列表
     *
     * @return {@link ResponseResult }
     * @param type    视频类型
     * @param search  搜索关键词
     * @author yangz
     */
    @Override
    public ResponseResult<List<VideoInfo>> getVideoList(String type, String search) {
        List<VideoInfo> videoList = videoInfoMapper.selectByTypeAndSearch(type, search);
        for (VideoInfo videoInfo : videoList) {
            // 构建相对路径
            String relativePath = videoInfo.getFileName();
            // 构建完整的 URL,拼接 Nginx 的部署路径
            videoInfo.setUrl( "http://"+initConfig.getServerIp()+":yourPort/static/" + relativePath);
            // 同样处理 imageUrl
            String relativeImagePath = videoInfo.getImageName();
            videoInfo.setImageUrl("http://"+initConfig.getServerIp()+":yourPort/static/" + relativeImagePath);
        }
        return new ResponseResult<>(videoList);
    }

2.4 编写Docker Compose 文件

这里volumes_from属性将Nginx容器的数据卷挂载到Java容器中,实现了两个容器之间数据卷的共享。

这是因为Nginx容器中的/usr/share/nginx/static目录包含了Java上传的静态资源,而volumes_from确保了Java容器可以访问这个目录。这样,Nginx就能够正确地服务Java上传的资源了。

version: '3'
services:
  # Nginx
  nginx:
    image: nginx:1.22.0
    container_name: nginx_education
    restart: always
    ports:
      - "yourPort:8868"
      - "83:80"
    volumes:
      - ./nginx/html:/usr/share/nginx/html
      - ./nginx/static:/usr/share/nginx/static
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    privileged: true

  # MySQL
  mysql:
    image: mysql:5.7
    ports:
      - "yourPort:3306"
    container_name: mysql_education
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: yourPassword
    volumes:
      - ./mysql:/var/lib/mysql
      - ./init/:/docker-entrypoint-initdb.d/

  # Redis
  redis:
    image: redis:5.0.3
    container_name: redis_education
    command: "/usr/local/bin/redis-server /usr/local/etc/redis/redis.conf --appendonly yes"
    restart: always
    ports:
      - "yourPort:6379"
    volumes:
      - ./redis:/data
      - ./redis.conf:/usr/local/etc/redis/redis.conf
      - ./logs/redis:/logs

  # Java
  java:
    image: java:8
    container_name: education
    ports:
      - "yourPort:jarPort"
    environment:
      - TZ=Asia/Shanghai
      - LANG=en_US.UTF-8
    volumes:
      # 映射Java应用程序jar文件
      - ./xxx-education-xxx-0.0.1-SNAPSHOT.jar:/data/xxx-education-xxx-0.0.1-SNAPSHOT.jar
      # 映射Java应用程序的初始化配置文件
      - ./init/init.properties:/data/init.properties
      # 映射Java应用程序的日志目录
      - ./logs:/logs
    # 使用volumes_from属性,挂载Nginx容器的数据卷到Java容器
    volumes_from:
      - nginx
    # Java应用程序的入口命令
    entrypoint: nohup java -jar /data/xxx-education-xxx-0.0.1-SNAPSHOT.jar --spring.profiles.active=docker > nohup.out &
    depends_on:
      - redis
      - mysql
    restart: on-failure
networks:
  default:
    external:
      name: my-education

2.5 Nginx配置

在Nginx的配置中,我们配置了/static/路径的访问规则,通过rewrite ^/(.+)/$ /$1 permanent;将URI结尾的斜杠去掉,并使用alias指定静态资源的路径。

注意172.17.0.1是Docker在部署docker-compose时创建的默认网关地址。在容器网络中,这个地址充当了容器之间直接通信的网关。通过配置Nginx时使用这个地址,使得即使服务器IP变化,也不需要修改Nginx的代理配置。这样一来,容器之间的通信可以通过网关地址和端口进行,实现了更加灵活和方便的部署方式。

server {
    listen yourPort;

    location / {
        root   /usr/share/nginx/html/dist;
        index  index.html index.htm;
        try_files  $uri $uri/ /index.html;
    }

    # 配置静态资源访问的路径
    location /static/ {
        rewrite ^/(.+)/$ /$1 permanent;
        alias /usr/share/nginx/static/;
    }

    location /prod-api/ {
        client_max_body_size 1000m;
        proxy_pass http://172.17.0.1:jarPort/;
        proxy_set_header  Host   $host;
        proxy_set_header  X-Real-IP   $remote_addr;
        proxy_set_header  X-Forwarded-For $remote_addr;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

3. 部署与访问

  1. 使用docker-compose up -d命令启动所有服务。

  2. 访问Java容器中的日志文件,查看Java应用启动时是否正确加载了服务器IP。

  3. 通过浏览器访问http://serverIP:Port/static/,验证Nginx是否正确访问了Java上传的资源。
    在这里插入图片描述

4. 结语

通过这个实战,我们成功搭建了一个多服务协同部署的环境,其中Nginx作为静态资源服务器,Java负责业务逻辑。利用Docker Compose,我们实现了服务的快速部署和环境一致性,为开发和测试提供了便利。

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

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

相关文章

C++相关闲碎记录(5)

1、容器提供的类型 2、Array Array大小固定&#xff0c;只允许替换元素的值&#xff0c;不能增加或者移除元素改变大小。Array是一种有序集合&#xff0c;支持随机访问。 std::array<int, 4> x; //elements of x have undefined value std::array<int, 5> x {…

cpu 300% 爆满 内存占用不高 排查

top查询 cpu最高的PID ps -ef | grep PID 查看具体哪一个jar服务 jstack -l PID > ./jstack.log 下载/打印进程的线程栈信息 可以加信息简单分析 或进一步 查看堆内存使用情况 jmap -heap Java进程id jstack.log 信息示例 Full thread dump Java HotSpot(TM) 64-Bit Se…

陪诊软件开发|北京陪诊系统功能详解

在这个快节奏的生活中&#xff0c;寻求医疗服务往往让人感到繁琐和时间浪费。然而&#xff0c;现如今&#xff0c;随着科技的不断进步&#xff0c;一项创新的上门服务系统正在改变传统的医疗体验&#xff0c;带来了前所未有的便利和舒适。 陪诊系统功能&#xff1a; 1、诊前约…

海上液化天然气 LNG 终端 | 图扑数字孪生

关于 LNG 液化天然气 (Liquefied Natural Gas&#xff0c;简称 LNG) 在能源转型过程中被广泛认可为相对较清洁的能源选择。 相对于传统的煤炭和石油燃料&#xff0c;LNG 的燃烧过程产生的二氧化碳 (CO2) 排放较低。LNG 的燃烧释放的二氧化碳排放较少&#xff0c;因此对应对气…

Theamleaf导出pdf模版编写(原始th/td编写表格)

需求&#xff1a;简单的theamleaf编写表格就是简单的th/td&#xff0c;新需求是导出的模版是学员table表&#xff0c;每个项目的学员数量是不定的&#xff0c;所以用到 <tr th:each"item,start:${studentList}"> 所有代码&#xff1a; <!DOCTYPE html>…

12月7日作业

使用QT模仿一个登陆界面&#xff08;模仿育碧Ubisoft登录界面&#xff09; #include "myqq.h"MyQQ::MyQQ(QWidget *parent): QMainWindow(parent) {this->resize(880,550); //设置窗口大小this->setFixedSize(880,550); //固定窗口大小this->setStyleShee…

【Docker二】docker网络模式、网络通信、数据管理、资源控制

目录 一、docker网络模式&#xff1a; 1、概述 2、docker网络实现原理&#xff1a; 3、docker的网络模式&#xff1a; 3.1、bridge模式&#xff1a; 3.2、host模式&#xff1a; 3.3、container模式&#xff1a; 3.4、none模式&#xff1a; 3.5、自定义网络模式&#xf…

嵌入式总线技术学习(二):Modbus 总线技术详解

参考资料 工业控制网络 1. Modbus 概述 Modbus 是全球第一个真正用于工业现场的总线协议。为更好地普及和推动 Modbus 在基于以太网上的分布式应用&#xff0c;目前施耐德公司已将 Modbus 协议的所有权移交给 IDA (Interfacefor DistributedAutomation&#xff0c;分布式自动化…

docker:部署java Springboot项目

文章目录 1、打 jar 包1、创建Dockerfile3、创建镜像4、启动容器其他注意事项docker中jdk的版本命名举例&#xff1a;openjdk:11-ea-17-jre-slim举例&#xff1a;8u312-jre-nanoserver-1809 通过find找文件 1、打 jar 包 将项目打一个 jar 包&#xff0c;可以使用 IDEA 1、…

智能优化算法应用:基于跳蛛算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于跳蛛算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于跳蛛算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.跳蛛算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

前端依赖下载速度过慢解决方法,nrm 镜像管理工具

npm 默认镜像 &#xff1a;https://registry.npmjs.org/ 问题 使用 npm install 安装依赖的时候&#xff0c;受网络的限制&#xff0c;速度会很慢。 解决 使用国内镜像代理。 nrm nrm 是镜像源管理工具&#xff1b; 1. 安装 nrm npm install nrm --global# 查看镜像源列…

Java线程安全问题及其三大线程同步“锁”方案

文章目录 一、 线程安全问题概述二、线程安全问题的demo演示三、线程同步方案四、线程同步代码块五、同步方法六、Lock锁七、附录—多线程常用方法 在实际开发过程中&#xff0c;使用线程时最重要的一个问题非线程安全问题莫属。这篇博客会带你由浅入深的初步了解该问题&#x…

FolkMQ 内存型消息中间件,v1.0.18 发布

简介 采用 “内存运行” “快照持久化” “Broker 集群模式”&#xff08;可选&#xff09;基于 Socket.D 网络应用协议 开发&#xff0c;使用“多路复用”技术。全新设计&#xff0c;自主架构&#xff01; 角色功能生产端发布消息&#xff08;Qos0、Qos1&#xff09;、发布…

SOLIDWORKS参数化工具如何设置部分提取

编制参数表是参数化设置必不可少的一环&#xff0c;提取零部件参数又是生成参数表所必须的步骤&#xff0c;然而很多时候&#xff0c;模型的量级很大&#xff0c;需要变化的零部件只有三分之一&#xff0c;那如果全部提取出来&#xff0c;将耗费大量的时间&#xff0c;因此部分…

Swagger页面报错Resolver error at definitions

问题描述 打开swagger页面报错Resolver error at definitions 原因分析&#xff1a; 从错误提示可以看出&#xff0c;是由map引起的原因&#xff0c;具体是因为swagger配置没有默认添加map的复杂结构引起的&#xff0c;需要手动添加。 解决方案&#xff1a; 找到swagger配置类…

黄金代理商怎么做才会受客户青睐?

黄金代理商是市场中推广现货黄金投资的角色&#xff0c;黄金代理商做的越好&#xff0c;推广的效果越明显&#xff0c;投资者就越多&#xff0c;这样他们就可以获得多一点黄金代理平台的佣金。所以&#xff0c;黄金代理商们会使劲浑身解数&#xff0c;让自己获得更多客户的青睐…

【ARM Trace32(劳特巴赫) 使用介绍 13 -- Trace32 Var 变量篇】

文章目录 Trace32 查看变量值Var.view 查看变量值Var.view 查看数据类型的大小Var.view 根据变量地址查看变量值 地址类型判断 Trace32 查看变量值 步骤1 步骤2 步骤3&#xff1a; 步骤4&#xff1a; 查看结构体变量 str_t32 的值 struct t32_str {uint32_t t32_val…

【JavaEE进阶】 Spring使用注解存储对象

文章目录 &#x1f334;序言&#x1f340;前置⼯作&#xff1a;配置扫描路径&#x1f384;添加注解存储 Bean 对象&#x1f333;类注解&#x1f6a9;为什么要这么多类注解&#x1f6a9;注解之间的联系 &#x1f38b;⽅法注解 Bean&#x1f6a9;⽅法注解需要配合类注解使⽤ ⭕总…

合合信息旗下启信宝与鹏城实验室达成数据托管合作,“AI靶场”让数据管理更精准

数字经济时代&#xff0c;数据已成为新型生产要素。通过“数据托管”等形式对数据进行集中管理&#xff0c;有助于保护数据主体权益&#xff0c;促进数据共享和运用效率&#xff0c;对数字经济的发展具有重要意义。近期&#xff0c;在深圳数据交易所&#xff08;简称“深数所”…

如何使用eXtplorer+cpolar内网穿透搭建个人云存储实现公网访问

文章目录 1. 前言2. eXtplorer网站搭建2.1 eXtplorer下载和安装2.2 eXtplorer网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1. 前言 通过互联网传输文件&#xff0c;是互联网最重要的应用之一&#xff0c;无论是…