Docker-02-镜像项目部署

Docker-02-镜像&项目部署

文章目录

  • Docker-02-镜像&项目部署
  • 一、镜像
    • ①:镜像结构
    • ②:Dockerfile
    • ③:构建镜像
      • 01:构建
      • 02:查看镜像列表
      • 03:运行镜像
  • 二、网络
    • ①:容器的网络IP地址
    • ②:网络常见命令
    • ③:自定义网络
  • 三、项目部署
    • ①:准备工作
    • ②:准备MySQL、nginx、redis容器
      • 01:创建网络
      • 02:创建nginx容器
      • 03:创建redis容器
      • 04:创建MySQL容器
      • 05:准备数据
    • ③:部署Java项目
      • 01:准备Dokerfile文件
      • 02:部署后端
      • 03:部署前端


一、镜像

前面我们一直在使用别人准备好的镜像,那如果我要部署一个Java项目,把它打包为一个镜像该怎么做呢?

①:镜像结构

要想自己构建镜像,必须先了解镜像的结构。
之前我们说过,镜像之所以能让我们快速跨操作系统部署应用而忽略其运行环境、配置,就是因为镜像中包含了程序运行需要的系统函数库、环境、配置、依赖。
因此,自定义镜像本质就是依次准备好程序运行的基础环境、依赖、应用本身、运行配置等文件,并且打包而成。

举个例子,我们要从0部署一个Java应用,大概流程是这样:

  • 准备一个linux服务(CentOS或者Ubuntu均可)
  • 安装并配置JDK
  • 上传Jar包
  • 运行jar包

那因此,我们打包镜像也是分成这么几步:

  • 准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)
  • 安装并配置JDK
  • 拷贝jar包
  • 配置启动脚本

上述步骤中的每一次操作其实都是在生产一些文件(系统运行环境、函数库、配置最终都是磁盘文件),所以镜像就是一堆文件的集合

但需要注意的是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer(层)。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。

例如,第一步中需要的Linux运行环境,通用性就很强,所以Docker官方就制作了这样的只包含Linux运行环境的镜像。我们在制作java镜像时,就无需重复制作,直接使用Docker官方提供的CentOS或Ubuntu镜像作为基础镜像。然后再搭建其它层即可,这样逐层搭建,最终整个Java项目的镜像结构如图所示:

在这里插入图片描述

②:Dockerfile

由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。
而这种记录镜像结构的文件就称为Dockerfile,其对应的语法可以参考官方文档:

https://docs.docker.com/engine/reference/builder/

其中的语法比较多,比较常用的有:

指令说明示例
FROM指定基础镜像FROM centos:6
ENV设置环境变量,可在后面指令使用ENV key value
COPY拷贝本地文件到镜像的指定目录COPY ./xx.jar /tmp/app.jar
RUN执行Linux的shell命令,一般是安装过程的命令RUN yum install gcc
EXPOSE指定容器运行时监听的端口,是给镜像使用者看的EXPOSE 8080
ENTRYPOINT镜像中应用的启动命令,容器运行时调用ENTRYPOINT java -jar xx.jar

例如,要基于Ubuntu镜像来构建一个Java应用,其Dockerfile内容如下:

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装JDK
RUN cd $JAVA_DIR \&& tar -xf ./jdk8.tar.gz \&& mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 指定项目监听的端口
EXPOSE 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]

思考一下:以后我们会有很多很多java项目需要打包为镜像,他们都需要Linux系统环境、JDK环境这两层,只有上面的3层不同(因为jar包不同)。如果每次制作java镜像都重复制作前两层镜像,是不是很麻烦。

所以,就有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去JDK的配置了:

# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

是不是简单多了。

③:构建镜像

01:构建

当Dockerfile文件写好以后,就可以利用命令来构建镜像了。
在课前资料中,我们准备好了一个demo项目及对应的Dockerfile:

在这里插入图片描述

1.首先,我们将课前资料提供的docker-demo.jar包以及Dockerfile拷贝到虚拟机的/root/demo目录:

在这里插入图片描述

2.然后,执行命令,构建镜像:

# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 .

命令说明:

  • docker build : 就是构建一个docker镜像
  • -t docker-demo:1.0 :-t参数是指定镜像的名称(repository和tag)
  • . : 最后的点是指构建时Dockerfile所在路径,由于我们进入了demo目录,所以指定的是.代表当前目录,也可以直接指定Dockerfile目录:
# 直接指定Dockerfile目录
docker build -t docker-demo:1.0 /root/demo

结果:
在这里插入图片描述

02:查看镜像列表

1.查看镜像列表:

# 查看镜像列表:
docker images

在这里插入图片描述

03:运行镜像

1.运行该镜像:

# 1.创建并运行容器
docker run -d --name dd -p 8080:8080 docker-demo:1.0
# 2.查看容器
docker ps

在这里插入图片描述

2.访问

# 3.访问
curl localhost:8080/hello/count

在这里插入图片描述

3.查看日志

docker logs -f dd

在这里插入图片描述

二、网络

①:容器的网络IP地址

上面我们创建了一个Java项目的容器,而Java项目往往需要访问其它各种中间件,例如MySQL、Redis等。现在,我们的容器之间能否互相访问呢?我们来测试一下

首先,我们查看下MySQL容器的详细信息,重点关注其中的网络IP地址:

1.用基本命令,寻找Networks.bridge.IPAddress属性

# 1.用基本命令,寻找Networks.bridge.IPAddress属性
docker inspect mysql
# 也可以使用format过滤结果
docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' mysql
# 得到IP地址如下:
172.17.0.2

在这里插入图片描述

2.进入dd容器,在容器内,通过ping命令测试网络

# 2.然后通过命令进入dd容器
docker exec -it dd bash# 3.在容器内,通过ping命令测试网络
ping 172.17.0.2

在这里插入图片描述

发现可以互联,没有问题。

但是,容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。

②:网络常见命令

我们必须借助于docker的网络功能来解决这个问题

官方文档:https://docs.docker.com/engine/reference/commandline/network/

常见命令有:

命令说明文档地址
docker network create创建一个网络docker network create
docker network ls查看所有网络docs.docker.com
docker network rm删除指定网络docs.docker.com
docker network prune清除未使用的网络docs.docker.com
docker network connect使指定容器连接加入某网络docs.docker.com
docker network disconnect使指定容器连接离开某网络docker network disconnect
docker network inspect查看网络详细信息docker network inspect

③:自定义网络

1.首先通过命令创建一个网络

# 1.首先通过命令创建一个网络
docker network create coke

在这里插入图片描述

2…然后查看网络

# 2.然后查看网络 ( 其中,除了coke以外,其它都是默认的网络)
docker network ls

在这里插入图片描述

3.让dd和mysql都加入该网络,注意,在加入网络时可以通过–alias给容器起别名

# 3.让dd和mysql都加入该网络,注意,在加入网络时可以通过--alias给容器起别名
# 这样该网络内的其它容器可以用别名互相访问!
# 3.1.mysql容器,指定别名为db,另外每一个容器都有一个别名是容器名
docker network connect coke mysql --alias db
# 3.2.db容器,也就是我们的java项目
docker network connect coke dd

在这里插入图片描述

4.进入dd容器,尝试利用别名访问db

# 4.进入dd容器,尝试利用别名访问db
# 4.1.进入容器
docker exec -it dd bash
# 4.2.用db别名访问
ping db

在这里插入图片描述

5.进入dd容器,用容器名访问

# 4.3.用容器名访问
ping mysql

在这里插入图片描述

OK,现在无需记住IP地址也可以实现容器互联了。

总结:

  • 在自定义网络中,可以给容器起多个别名,默认的别名是容器名本身
  • 在同一个自定义网络中的容器,可以通过别名互相访问

三、项目部署

①:准备工作

好了,我们已经熟悉了Docker的基本用法,接下来可以尝试部署项目了。

项目说明:

  • invoice:发票系统管理的后端代码
  • invoice-web:发票系统管理的前端代码

部署的容器及端口说明:

项目容器名端口备注
invoiceinvoice19009发票系统管理的后端API入口
invoice-webnginx8899发票系统管理的前端入口
mysqlmysql3306发票系统管理的前端入口

DockerFile

# 基础镜像
FROM openjdk:8-jre-buster# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone# 拷贝jar包
COPY invoice-0.0.1-SNAPSHOT.jar /app.jar# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

②:准备MySQL、nginx、redis容器

  • 因为项目中分别用到了MySQL、nginx和redis,所以提前准备好这些容器(并准备好数据库中的数据)

  • MySQL、nginx、redis容器 将容器放到同一个网络中,之后直接使用容器名字访问即可

在这里插入图片描述

01:创建网络

# 创建网络(名为invoice)
docker network create invoice# 查看所有网络
docker network ls

在这里插入图片描述

02:创建nginx容器

1.创建容器
创建nginx容器笔记:https://blog.csdn.net/cygqtt/article/details/135665012

docker run \
-p 80:80 \
-p 8899:8899 \
--name nginx \
--restart=always \
-v /usr/local/nginx/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /usr/local/nginx/html:/usr/share/nginx/html \
-v /usr/local/nginx/logs:/var/log/nginx \
-d nginx:1.25.3

2.nginx容器创建之后我们需要将nginx容器加入到invoice网络中

# 查看所有网络
docker network ls
# 将容器加入到网络中
docker network connect invoice nginx

在这里插入图片描述

3.查看网络详细信息

docker network inspect  invoice

在这里插入图片描述

03:创建redis容器

1.创建容器
创建redis容器笔记:https://blog.csdn.net/cygqtt/article/details/135665012

2.redis容器创建之后我们需要将redis容器加入到invoice网络中

# 查看所有网络
docker network ls
# 将容器加入到网络中
docker network connect invoice redis

在这里插入图片描述

3.查看网络详细信息

docker network inspect  invoice

在这里插入图片描述

04:创建MySQL容器

1.创建容器
创建MySQL容器笔记:https://blog.csdn.net/cygqtt/article/details/135665012

2.MySQL容器创建之后我们需要将MySQL容器加入到invoice网络中

# 查看所有网络
docker network ls
# 将容器加入到网络中
docker network connect invoice mysql

在这里插入图片描述

3.查看网络详细信息

docker network inspect  invoice

在这里插入图片描述

05:准备数据

1.运行sql文件

在这里插入图片描述
在这里插入图片描述

③:部署Java项目

01:准备Dokerfile文件

1.可以使用以下两种方式来命名 Dockerfile 文件:

  • Dockerfile:这是最常见和推荐的方式,使用没有后缀的文件名。
  • Dockerfile.dockerfile:这种方式在某些情况下可能更具描述性,特别是当你有多个类型的 Dockerfile 文件时。

2.Dokerfile内容

# 基础镜像
FROM openjdk:8-jre-buster# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone# 拷贝jar包
COPY invoice-0.1.2-SNAPSHOT.jar /app.jar# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

02:部署后端

1.将Dockerfile和jar包一起上传到虚拟机

在这里插入图片描述

2.构建镜像

# 1.构建项目镜像,不指定tag,则默认为latest
docker build -t invoice .

在这里插入图片描述

2,查看镜像

# 2.查看镜像
docker images

在这里插入图片描述

3.创建并运行容器

# 创建并运行一个tomcat容器
docker run -d --name tomcat --network invoice -p 8080:8080 tomcat# 创建并运行容器,并通过--network将其加入hmall网络,这样才能通过容器名访问mysql
docker run -d --name invoice --network invoice -p 19009:19009 invoice

在这里插入图片描述

4.查看启动日志

docker logs invoice

在这里插入图片描述

5.请求api测试 http://192.168.200.128:19009/web/workFile/getAll

  • 后端部署成功!
    在这里插入图片描述

03:部署前端

1.创建目录用于存放前端代码

mkdir -p /usr/local/nginx/html/invoice-web

2.将打包好的前端代表拷贝到目录/usr/local/nginx/html/invoice-web

在这里插入图片描述

3.配置nginx

vim /usr/local/nginx/nginx/nginx.conf
  • 添加以下信息
worker_processes  1;events {worker_connections  1024;
}http {include       mime.types;default_type  application/json;sendfile        on;keepalive_timeout  65;client_max_body_size 1000M; #(设置客户端请求体最大值) client_body_buffer_size 1000M; #(配置请求体缓存区大小) fastcgi_intercept_errors on;server {    listen 8899;server_name _;location /api/ {# 这里配置代理到后端服务的地址proxy_pass http://invoice:19009/;}location / {# 这里配置前端资源的路径(容器内部路径)root /usr/share/nginx/html/invoice-web;index index.html index.htm;try_files $uri $uri/ /index.html;}}
}

4.重启nginx容器

# 重启nginx容器(使配置文件生效)
docker restart nginx

在这里插入图片描述

5.访问测试 http://192.168.200.128:8899/web

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

SQL性能分析

SQL性能分析 1、SQL执行频率 ​ MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信 息。通过如下指令,可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次: -- session 是查看当前会话 ; …

oracle11g的闪回技术-闪回表-时间戳

--数据库闪回表 --1创建表(登录模式system) CREATE table dept2 as select * from dept;--此语句如果加上where条件可用于工作中数据的临时备份 select * from dept2;--查询新建表信息 --进入sql>set time on 通过时间点闪回 记录弹出的时间点&#…

flutter 五点一:MaterialApp Theme

ThemeData factory ThemeData({bool? applyElevationOverlayColor, //material2的darkTheme下 增加一个半透明遮罩 来凸显阴影效果 material3下无效 貌似没啥用NoDefaultCupertinoThemeData? cupertinoOverrideTheme, //ios组件样式 Iterable<ThemeExtension<dyn…

zabbix客户端配置及自定义监控

部署zabbix客户机 1.服务端和客户端都配置时间同步 yum install -y ntpdate ntpdate -u ntp.aliyun.com 2.服务端和客户端都设置 hosts 解析 cat > /etc/hosts << EOF 172.16.23.16 localhost 172.16.23.17 zbx-server EOF 3.被监控端 //设置 zabbix 的下载源&…

MySQL深度分页优化问题

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

广告投放场景中ABtest分析的评价、优化和决策建议

目录 写在开头1. AB测试基础知识1.1 AB测试概述1.2 原理和流程1.3 广告领域中的AB测试应用 2. 评价广告投放中的AB测试2.1 关键指标选择与解释2.2 统计学方法应用 3. AB测试分析中的常见问题与解决方案3.1 样本偏差3.2 季节性影响3.3 测试时长选择3.4 结果误解与分析失误 4. 优…

老师布置作业的技巧有哪些

布置作业可不只是简单地给学生分配任务&#xff0c;而是需要运用一些技巧&#xff0c;以达到更好的教学效果。那么&#xff0c;老师应该如何布置作业呢&#xff1f; 一、作业要有针对性 布置作业时&#xff0c;老师应该根据学生的实际情况和课程要求&#xff0c;有针对性地设…

tinyxml2

使用tinyxml2&#xff0c;得知道一些xml基础 xml tutorial--菜鸟 tinyxml2类对象 链接 结构 XMLNode 什么是节点 节点&#xff1a;元素、声明、文本、注释等。 XMLDocument xml文档(文件)对象。 作用&#xff1a; 加载xml文件&#xff0c; tinyxml2作用 先定义两个宏 …

阿里云服务器地域如何选择?哪个地域价格优惠一些?

阿里云服务器地域和可用区怎么选择&#xff1f;地域是指云服务器所在物理数据中心的位置&#xff0c;地域选择就近选择&#xff0c;访客距离地域所在城市越近网络延迟越低&#xff0c;速度就越快&#xff1b;可用区是指同一个地域下&#xff0c;网络和电力相互独立的区域&#…

【数据结构】堆的实现和排序

目录 1、堆的概念和结构 1.1、堆的概念 1.2、堆的性质 1.3、堆的逻辑结构和存储结构 2、堆的实现 2.1、堆的初始化和初始化 2.2、堆的插入和向上调整算法 2.3、堆的删除和向下调整算法 2.4、取堆顶的数据和数据个数 2.5、堆的判空和打印 2.6、测试 3、堆的应用 3.1…

CentOS查看修改时间

经常玩docker的朋友应该都知道&#xff0c;有很多的镜像运行起来后&#xff0c;发现容器里的系统时间不对&#xff0c;一般是晚被北京时间8个小时&#xff08;不一定&#xff09;。 这里合理怀疑是镜像给的初始时区是世界标准时间&#xff08;也叫协调世界时间&#xff09;。 有…

CPU密集型计算、IO密集型计算、多进程、多线程

参考链接&#xff1a; 使用多进程multiprocessing模块加速程序的运行_哔哩哔哩_bilibili 什么是CPU密集型计算、IO密集型计算&#xff1a; CPU密集型&#xff1a; CPU密集型也叫计算密集型&#xff0c;是指I/O在很短的时间就可以完成&#xff0c;CPU需要大量的计算和处理&a…