Docker-02-镜像&项目部署

发布时间:2024年01月18日

Docker-02-镜像&项目部署


一、镜像

前面我们一直在使用别人准备好的镜像,那如果我要部署一个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

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

在这里插入图片描述

文章来源:https://blog.csdn.net/cygqtt/article/details/135611596
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。