docker 部署 java 项目详解

        在平常的开发工作中,我们经常需要部署项目,开发测试完成后,最关键的一步就是部署。今天我们以若依项目为例,总结下部署项目的整体流程。简单来说,第一步:安装项目所需的中间件;第二步:将项目打包成 jar 包;第三步:编写 Dockerfile 文件,构建镜像;第四步:编写 docker-compose.yml 文件;第五步:编写 nginx.conf 文件;第六步:启动项目,进行测试。

      1:安装项目所需中间件

         项目部署依赖的中间件,如数据库 mysql 、缓存 redis、负载均衡 nginx 等,这些中间件的安装就不在这儿一 一赘述了。如果有不清楚的小伙伴,可以看我之前写的几篇博客,如下:

        安装 mysql:docker 安装 mysql 详解-CSDN博客

        安装 redis:docker 安装 redis 详解-CSDN博客

        安装 nginx:docker 安装 nginx 详解-CSDN博客

     2:将项目打成 jar 包

        部署不同的环境,需要选择不同的配置文件,部署测试环境一般选择 application-test.yml 文件打包,部署生产环境一般选择 application-prod.yml 文件。打 jar 包时一定注意本地修改不需要提交的配置,先回滚,然后拉取最新的代码,点击 maven  clean,然后点击 package 打包,打包完后在 target 目录。将 jar 包上传到服务器指定的目录。

        注意:比如在服务器上新建一个 /docker/ruoyi/ 的目录,那么 jar 包放在这个目录下,在这个目录下再新建 Dockerfile 文件 和 docker-compose.yml 文件,如下所示:

                               

     3:编写 Dockerfile 文件,构建镜像

        Dockerfile文件示例:

# 使用OpenJDK 17基础镜像
FROM openjdk:17
# 创建一个名为/ruoyi/logs的目录
RUN mkdir -p /ruoyi/logs
# 切换工作目录
WORKDIR /ruoyi
# 配置环境变量
ENV SERVER_PORT=8008 \LANG=C.UTF-8 \LC_ALL=C.UTF-8# 暴露应用端口
EXPOSE 8008# 添加应用Jar包到容器中
ADD ruoyi-admin.jar ./app.jar# 设置启动命令
ENTRYPOINT ["java", \"-Dserver.port=${SERVER_PORT}", \"-Xlog:gc*:time,tags,level", \"-XX:+UseZGC", \"-jar", "app.jar"]

       Dockerfile文件内容释义
       1):FROM openjdk:17: 使用OpenJDK 17基础镜像
       2):RUN mkdir -p /ruoyi/logs:创建一个名为/ruoyi/logs的目录,即日志目录
       3):WORKDIR /ruoyi:切换工作目录
       4):ENV SERVER_PORT=8008 \
              LANG=C.UTF-8 \
              LC_ALL=C.UTF-8
        配置环境变量,Docker 镜像构建时设置了三个环境变量,分别是服务端口和字符编码相关的环境变量,LANG=C.UTF-8 和 LC_ALL=C.UTF-8:这两个环境变量用于设置字符编码和语言环境,\ 末尾的反斜杠 \ 是行延续符,表示下一行是当前命令的延续
       5):EXPOSE 8008:暴露8008端口
       6):ADD ruoyi-admin.jar ./app.jar:
       添加应用Jar包到容器中,ADD:这是 Dockerfile 里用于复制文件和目录的指令,ruoyi-admin.jar:这是位于宿主机上的源文件路径,./app.jar:这是目标路径,指定将源文件复制到 Docker 镜像中的位置和文件名。./ 表示镜像中的当前 # 工作目录,将源文件 ruoyi-admin.jar 复制到镜像的当前工作目录下,并命名为 app.jar
       7):ENTRYPOINT ["java", \
              "-Dserver.port=${SERVER_PORT}", \
              "-Xlog:gc*:time,tags,level", \
              "-XX:+UseZGC", \
              "-jar", "app.jar"]
        a:ENTRYPOINT 关键字:这是 Dockerfile 里用来定义容器启动命令的指令。
        b:"java":表明要执行的是 Java 虚拟机。
        c:"-Dserver.port=${SERVER_PORT}":设置 Java 虚拟机的系统属性。server.port 通常用于指定 Spring Boot 应用程序监听的端口,#${SERVER_PORT} 是一个环境变量引用,其值在之前的 ENV 指令中设置为 8008,这意味着应用程序会监听 8008 端口。
        d:"-Xlog:gc*:time,tags,level":开启 Java 垃圾回收(GC)日志记录功能。gc* 表示记录所有与垃圾回# 收相关的事件,time,tags,level 表示日志中要包含时间、事件标签和日志级别等信息。
        e:"-XX:+UseZGC":启用 Z Garbage Collector(ZGC),这是 Java 11 及以上版本引入的一种可扩展的低# 延迟垃圾回收器,能显著减少垃圾回收停顿时间。
        f:"-jar":告诉 Java 虚拟机要执行一个 JAR 包,"app.jar":指定要执行的 JAR 包名称,这个 JAR 包是之前使用 ADD 或 COPY 指令复制到镜像中的。

        编写完 Dockerfile 文件后,这个时候就可以构建镜像了,命令:docker build -t  镜像名称:镜像版本 . ,如 docker build  -t  ruoyi:v1.0 注意版本后面有个 空格 点。使用点 :表示使用当前目录下的 Dockerfile,如果不加这个点,Docker 不会知道从哪里获取 Dockerfile。镜像构建完成后,可以使用 docker images 查看生成的镜像:

        

     4:编写 docker-compose.yml 文件

        docker-compose.yml 文件示例:

services:ruoyi-admin:image: ruoyi-admin:v1.0container_name : ruoyi-adminenvironment:- SERVER_PORT=8008# 可选,Java 启动参数- JAVA_OPTS="-Xmx2g -Xms2g" - TZ=Asia/Shanghairestart: alwaysnetwork_mode: "host"

        docker-compose.yml 文件内容释义
        1):image: ruoyi-admin:v1.0:服务会使用ruoyi-admin:v1.0镜像来创建容器
        2):container_name:容器名称
        3):SERVER_PORT=8008:定义环境变量
        4):- JAVA_OPTS="-Xmx2g -Xms2g":可选参数,-Xmx用来设定 JVM 堆内存的最大使用量;-Xms用于设置 JVM 堆内存的初始使用量。JAVA_OPTS="-Xmx2g -Xms2g" 把 JVM 堆内存的初始大小和最大大小都设置为 2GB。这么做可以避免在应用程序运行过程中频繁进行堆内存的扩容和缩容操作,从而提升性能。不过,设置时要依据应用程序的实际内存需求和服务器的可用内存来合理调整,防止出现内存不足或者浪费的情况。
        5):- TZ=Asia/Shanghai:把容器内的时区指定为 Asia/Shanghai(即上海所在的时区,也就是中国标准时间,UTC+8)。这样容器内运行的应用程序所显示和处理的时间会UTC+8时区处理。
        6):restart: always:为容器指定了一种重启策略,确保容器在各种情况下都能尽可能保持运行状态。当容器由于各种原因(如正常退出、异常崩溃、宿主机重启等)停止运行时,Docker 会依据此策略自动尝试重启容器。
       除了always,还有其他几种重启策略:
       no:默认策略,容器停止后不会自动重启。
       on-failure:只有当容器以非零退出码退出时,Docker 才会尝试重启它。可以通过 on-failure: N 的形式指定最多重启 N 次。
       unless-stopped:容器停止后,除非手动停止(如使用 docker stop 命令),否则 Docker 会在 Docker 守护进程重启或宿主机重启后自动重启容器。
      7):network_mode: "host":指定容器使用宿主机的网络,即容器直接使用宿主机的网络接口,而非创建独立的 Docker 网络。

     5:配置 nginx.conf

        nginx.conf 文件示例:

user  nginx;
worker_processes  auto;pid        /var/run/nginx.pid;events {worker_connections  1024;
}http {include       /etc/nginx/mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  60;server {listen 80;server_name localhost;charset utf-8;location / {proxy_pass  http://localhost:8008;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
}

      6:启动项目,测试

        1):进入 /doker/ruoyi/ 目录下,即 docker-compose.yml 文件目录,使用 docker compose up -d 命令启动容器,启动完成后可以使用 docker ps 命令查看启动的容器,信息如下:

        使用 docker logs -f  容器id 查看启动日志,启动成功:

        2):访问系统,nginx 配置监听 80 端口,所以访问地址为:http:ip地址:80,访问成功,页面如下:

        可能会遇到的问题:项目启动成功,访问失败,可以查看项目端口是否因没开防火墙导致无法访问。如果是,解决步骤如下:

        1):查看防火墙开的端口:firewall-cmd --zone=public --list-ports

        2):若端口未开,则添加,比如开放 8008 端口:firewall-cmd --zone=public --add-port=8008/tcp --permanent

        3):修改完成后,重启防火墙:firewall-cmd --reload

        以上为 docker 部署项目的基本步骤。主要是Dockerfile文件的编写,第一次构建镜像比较慢,因为要下载依赖的基础镜像,只需耐心等待即可。Dockerfile文件有问题,会导致构建镜像失败。构建完成后,可以使用 docker images 查看构建的镜像。启动容器可以直接使用 docker run 命令后面跟启动参数启动,这样做不好的地方每次启动项目,都要输入一 长串命令,不便于使用,在docker-compose.yml文件里面编写启动命令,可以更好的管理启动命令,所以推荐使用docker-compose.yml文件方式。在项目目录使用 docker compose up -d 命令启动就可以,docker compose up -d,带上 -d 是非阻塞的,不阻塞当前的命令窗口。使用 docker logs -f 容器id 或者 容器名称 可以查看启动日志。

        

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

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

相关文章

Crawl4AI 人工智能自动采集数据

文章目录 1 使用 Crawl 的步骤2 AI 智能体应用实例3 结语 Crawl是一款免费的开源工具,利用AI技术简化网络爬取和数据提取,提高信息收集与分析的效率。它智能识别网页内容,并将数据转换为易于处理的格式,功能全面且操作简便。 定位…

使用vitepress搭建自己的博客项目

一、介绍can-vitepress-blog 什么是CAN BLOG CAN BLOG是基于vitepress二开的个人博客系统,他能够方便使用者快速构建自己的博客文章,无需繁琐的配置和复杂的代码编写。 CAN BLOG以antdv为UI设计基础,简洁大方,界面友好&#xf…

On to OpenGL and 3D computer graphics

2. On to OpenGL and 3D computer graphics 声明:该代码来自:Computer Graphics Through OpenGL From Theory to Experiments,仅用作学习参考 2.1 First Program Square.cpp完整代码 /// // square.cpp // // OpenGL program to draw a squ…

Excel分区间统计分析(等步长、不等步长、多维度)

在数据分析过程中,可能会需要统计不同数据区间的人数、某个数据区间的平均值或者进行分组区间统计,本文从excel函数到数据透视表的方法,从简单需求到复杂需求,采用不同的方法进行讲解,尤其是通过数据透视表的强大功能大…

低代码系统-产品架构案例介绍、得帆云(八)

产品名称 得帆云DeCode低代码平台-私有化 得帆云DeMDM主数据管理平台 得帆云DeCode低代码平台-公有云 得帆云DePortal企业门户 得帆云DeFusion融合集成平台 得帆云DeHoop数据中台 名词 概念 云原生 指自己搭建的运维平台,区别于阿里云、腾讯云 Dehoop 指…

mybatis(78/134)

前天学了很多&#xff0c;关于java的反射机制&#xff0c;其实跳过了new对象&#xff0c;然后底层生成了字节码&#xff0c;创建了对应的编码。手搓了一遍源码&#xff0c;还是比较复杂的。 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE …

1.23 补题 寒假训练营

E 一起走很长的路&#xff01; 输入描述 第一行输入两个整数 n,q&#xff08;1≤n,q≤210^5&#xff09;&#xff0c;代表多米诺骨牌的个数和询问次数。 第二行输入 n 个整数 a1,a2,…,an​&#xff08;1≤ai≤10^9&#xff09;&#xff0c;表示多米诺骨牌的重量。 此后输入…

从入门到精通:RabbitMQ的深度探索与实战应用

目录 一、RabbitMQ 初相识 二、基础概念速览 &#xff08;一&#xff09;消息队列是什么 &#xff08;二&#xff09;RabbitMQ 核心组件 三、RabbitMQ 基本使用 &#xff08;一&#xff09;安装与环境搭建 &#xff08;二&#xff09;简单示例 &#xff08;三&#xff09;…

基于vscode的cppcmake调试环境配置

1. 创建项目文件 创建cpp文件及CMakeLists.txt文件 helloOpenCV.cpp #include <opencv2/opencv.hpp> int main() {// 创建图像&#xff0c;初始化为黑色cv::Mat image cv::Mat::zeros(200, 300, CV_8UC3);// 设置为纯绿色 (BGR格式&#xff1a;0, 255, 0)image.setTo…

后端面试题分享第一弹(状态码、进程线程、TCPUDP)

后端面试题分享第一弹 1. 如何查看状态码&#xff0c;状态码含义 在Web开发和调试过程中&#xff0c;HTTP状态码是了解请求处理情况的重要工具。 查看状态码的步骤 打开开发者工具&#xff1a; 在大多数浏览器中&#xff0c;您可以通过按下 F12 键或右键单击页面并选择“检查…

(1)STM32 USB设备开发-基础知识

开篇感谢&#xff1a; 【经验分享】STM32 USB相关知识扫盲 - STM32团队 ST意法半导体中文论坛 单片机学习记录_桃成蹊2.0的博客-CSDN博客 USB_不吃鱼的猫丿的博客-CSDN博客 1、USB鼠标_哔哩哔哩_bilibili usb_冰糖葫的博客-CSDN博客 USB_lqonlylove的博客-CSDN博客 USB …

win32汇编环境,对话框程序中使用进度条控件

;运行效果 ;win32汇编环境,对话框程序中使用进度条控件 ;进度条控件主要涉及的是长度单位,每步步长,推进的时间。 ;比如你的长度是1000,步长是100,每秒走1次,则10秒走完全程 ;比如你的长度是1000,步长是10,每秒走1次,则100秒走完全程,但每格格子的长度与上面一样 ;以下…

CrypTen——基于pytorch的隐私保护机器学习框架

目录 一、CrypTen概述 二、应用场景 三、CrypTen优势 四、CrypTen技术解析 1.基于pytorch的构建基础 2.核心密码学原语 3.加密模型训练流程 五、传统隐私保护技术与CrypTen的对比 1.传统隐私保护技术介绍 2.CrypTen与传统隐私保护技术的区别 六、CrypTen的环境配置…

电梯系统的UML文档11

场景 7.3 紧急制动 3 –当电梯停止在某一楼层时&#xff0c;如果命令门打开&#xff0c;但是门不开&#xff0c;则紧急制动将触发。 图 16: 场景 7.3- 紧急制动 - 门将不开启当电梯停止在目的层 场景 7.4 紧急制动 4 –如果电梯移动时门打开&#xff0c;紧急制动将触发。 图 1…

【Elasticsearch 基础入门】Centos7下Elasticsearch 7.x安装与配置(单机)

Elasticsearch系列文章目录 【Elasticsearch 基础入门】一文带你了解Elasticsearch&#xff01;&#xff01;&#xff01;【Elasticsearch 基础入门】Centos7下Elasticsearch 7.x安装与配置&#xff08;单机&#xff09; 目录 Elasticsearch系列文章目录前言单机模式1. 安装 J…

正点原子Linux 移植USB Wifi模块MT7601U驱动(上)

目录 下载驱动MT7601驱动文件中重要的几个文件1.README_STA_usb2.sta_ate_iwpriv_usage.txt3.config.mk4.Makefile 移植过程编译驱动成ko文件复制到根文件系统里驱动加载失败常见原因A. DMA缓存大小不够B. RT2870STA.dat文件没配置好 模块加载测试开启无线网卡并设置IP地址 参考…

Linux相关概念和易错知识点(26)(命名管道、共享内存)

目录 1.命名管道 &#xff08;1&#xff09;匿名管道 -> 命名管道 ①匿名管道 ②命名管道 &#xff08;2&#xff09;命名管道的使用 ①创建和删除命名管道文件 ②命名管道文件的特性 ③命名管道和匿名管道的区别 &#xff08;3&#xff09;用命名管道实现进程间通信…

【时时三省】(C语言基础)对比一组函数

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 对比一组函数 比如对比一下scanf fscanf sscanf和printf fprintf sprintf scanf 针对标准输入的格式化的输入语句 其实它针对的是stdin fscanf 针对所有输入流的格式化的输入语句 它是针对s…

Leecode刷题C语言之组合总和②

执行结果:通过 执行用时和内存消耗如下&#xff1a; int** ans; int* ansColumnSizes; int ansSize;int* sequence; int sequenceSize;int** freq; int freqSize;void dfs(int pos, int rest) {if (rest 0) {int* tmp malloc(sizeof(int) * sequenceSize);memcpy(tmp, seque…

汽车网络信息安全-ISO/SAE 21434解析(下)

目录 第十二~十四章 - 后开发阶段 1. 十二章节 - 生产 2. 十三章节 - 运营与维护 网络安全事件响应 更新 3. 十四章节 - 结束网络安全支持和停用 结束网络安全支持 报废 第十五章 - TARA分析方法 1. 概述 2. 资产识别 3. 威胁场景识别 4. 影响评级 5. 攻击路径分…