Docker实战教程-03Docker实践篇

2,309 阅读8分钟

本篇文章详细介绍了docker在实际项目中的使用,通过一个单体项目和一个有多个微服务组成的微服务项目来演示

6、使用docker容器化部署项目实战

6-1 在开发工具中使用docker

这个网上有很多教程,不在赘述,看教程吧

(202条消息) IDEA 中配置及使用Docker_傲傲娇的博客-CSDN博客_idea配置docker

(202条消息) Idea:连接Docker服务器_琦彦的博客-CSDN博客_idea连接docker服务器

6-2 部署单体项目

基于若依开发的系统

docker 配置spring boot项目带配置文件_RunMonster的博客-CSDN博客

1、项目介绍

项目除了springboot本身,还需要mysql和redis两个数据库,其他的就没有了

项目结构:

image-20221108193350199

最终的启动jar包在ruoyi-admin模块中

2、构建网络,启动数据库

新建网络

这一个项目所需要的容器都放在一个网络下面,以便他们之间可以通过容器名称连接,而不是通过ip

image-20221108194129512

mysql

docker run -d -p 8136:3306 --network sgdt_network --privileged=true -v /app/mysql/log:/var/log/mysql -v /app/mysql/data:/var/lib/mysql -v /app/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7

命令分析:

docker run 
-d  #后台启动
-p 8136:3306 #端口映射 
--network sgdt_network #指定网络
--privileged=true  #挂载数据卷
-v /app/mysql/log:/var/log/mysql  #挂载数据卷
-v /app/mysql/data:/var/lib/mysql  #挂载数据卷
-v /app/mysql/conf:/etc/mysql/conf.d  #挂载数据卷
-e MYSQL_ROOT_PASSWORD=123456   #设置root用户密码
--name mysql  #容器名称
mysql:5.7 #镜像名称

这个项目的数据库使用了这个容器卷挂载数据,当有别的项目的需要新的数据库时记得要挂载别的路径,不要两个项目挂载了同一个路径

执行即可上述命令:

image-20221108194619309

太长了,只截取了部分

由于和宿主机的8136端口映射,所以我们通过宿主机ip和端口连接上这个服务器,新建数据库和所需要表即可

image-20221108194733501

到此,mysql安装完成(是不是非常快速)

redis

执行命令:

docker run -d -p 6380:6379 --network sgdt_network --name redis --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data redis:6.0.8 redis-server /etc/redis/redis.conf

命令分析:

docker run  
-d #后台运行容器
-p 6380:6379 #端口映射
--network sgdt_network #选择网络
--name redis #容器名称
--privileged=true #挂载数据卷
-v /app/redis/redis.conf:/etc/redis/redis.conf  #挂载数据卷
-v /app/redis/data:/data  #挂载数据卷
redis:6.0.8  #镜像名称
redis-server /etc/redis/redis.conf #指定操作命令为redis-serve并指定读取宿主机同步过去的配置文件

注意,这里挂载数据卷中指定了redis的配置文件,所以在宿主机的相应路径下应该有一个redis的配置文件,在配置文件中设置我们常用的配置即可

如果使用redis的默认模板,记得更改这些:

image-20221108195838673

运行即可:

image-20221108200048212

可以在外界通过映射的端口连接

3、项目配置和打包

配置文件

在生产环境的配置文件中,可以直接通过容器名称连接容器(在同一个docker网络下)

image-20221108200332266

打包

还是使用不将配置文件(yml)打包进jar,当然也可以当文件打包进jar,看个人习惯就可以,具体springboot选择配置文件的知识看其他笔记即可

<build>
    <!--排除yml文件,部署打包的时候使用,平时注释掉(或者放到master分支)-->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>*.yml</exclude>
            </excludes>
        </resource>
    </resources>
</build>

之后maven打包即可,注意要选择ruoyi-admin下的

4、Dockfile

详细的Dockerfile,之后可以参考这个模板

这里的文件后面我又改了一下,所以可能和下面构建镜像时的截图不太一样,不过无伤大雅

#基础镜像使用java8
FROM java:8
# 作者
MAINTAINER zylai<zylai0712@163.com>
#端口
EXPOSE 8201
# 环境变量
ENV WORK_PATH /sgdt
ENV WORK_CONFIG_PATH /sgdt/config

#工作目录
WORKDIR $WORK_PATH

# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
#创建文件夹
RUN mkdir -p $WORK_CONFIG_PATH
# 将jar包添加到容器中并更名为app.jar
ADD /ruoyi-admin/target/ruoyi-admin.jar $WORK_PATH/app.jar
# 拷贝jar包的配置文件到config文件夹下面
ADD /ruoyi-admin/src/main/resources/*.yml $WORK_CONFIG_PATH/

# 进入工作目录,以便直接执行运行jar包的命令(否则还需要手动指定jar的全路径)
RUN cd $WORK_PARH

#修改这个文件的访问时间和修改时间为当前时间,而不会修改文件的内容。
RUN bash -c 'touch app.jar'
# 运行jar包
ENTRYPOINT ["java","-jar","app.jar"]

5、idea一键生成镜像运行容器

需要注意的点就是构建之后运行容器的端口映射和网络

image-20221108200830802

最终会执行的命令:

image-20221108200929781

然后,run!!!

image-20221110150829040

image-20221110150908008

image-20221110151027241

查看容器打印的日志:

image-20221110151103874

通过宿主机映射的端口访问:

image-20221108201409310

一套下来,非常滴爽哈!

6-2 编排容器

就是说上面需要先运行mysql和redis才可以运行我们最终的项目容器sgdt,我们这里就可以通过docker-compose编排来实现上述三个容器的一键运行

docker-compose的诸多优点(直接网上cv的)

  • 在单个主机上建立多个隔离环境,Compose 使用项目名称将环境彼此隔离。您可以在多个不同的上下文中使用此项目名称。默认项目名称是项目目录的基本名称。您可以使用-p 命令行选项或 COMPOSE_PROJECT_NAME 环境变量设置自定义项目名称 。默认项目目录是 Compose 文件的基本目录。可以使用--project-directory 命令行选项自定义项目目录。
  • 创建容器时保留卷数据
  • 仅重新创建已更改的容器,当您重新启动未更改的服务时,Compose 会使用现有容器。
  • 变量在环境之间组合重复使用

docker-compose.yml文件的编写

不再赘述,看别人的博客即可

docker compose 配置文件 .yml 全面指南 - 知乎 (zhihu.com)

version: "3"

services:
  # sgdt-service为服务名称,在同一个网络中可以通过服务名称来访问容器,而不通过ip
  sgdt-service:
    image: sgdt:1.2 #镜像名称
    container_name: sgdt01 #容器名称
    #    如果上述镜像不存在,就可以根据这里指定的Dockerfile去创建镜像
    build:
      context: ./
      dockerfile: Dockerfile
    ports: #指定端口映射
      - "8201:8201"
    volumes: #挂载容器卷
      - /app/sgdt:/data
    networks: #指定使用的网络
      - sgdt_network
    depends_on: #依赖哪些服务,这些服务先启动之后才会启动当前服务
      - redis
      - mysql

  redis:
    image: redis:6.0.8
    container_name: redis
    ports:
      - "6380:6379"
    volumes:
      - /app/redis/redis.conf:/etc/redis/redis.conf
      - /app/redis/data:/data
    networks:
      - sgdt_network
    command: redis-server /etc/redis/redis.conf

  mysql:
    image: mysql:5.7
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: '123456'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
    ports:
      - "8136:3306"
    volumes:
      - /app/mysql/log:/var/log/mysql
      - /app/mysql/data:/var/lib/mysql
      - /app/mysql/conf:/etc/mysql/conf.d
    networks:
      - sgdt_network
    command: --default-authentication-plugin=mysql_native_password #解决外部无法访问

networks:
  sgdt_network:
    name: sgdt_network        #指定网络名称

关于网络的问题:如果你不指定网络的名称,那么他会默认使用当前路径名+网络名

配置问题

如果直接在idea里面run这个文件,肯定会报错的,就像下面这样

Failed to deploy ‘Compose: docker-compose.yml’: com.intellij.execution.process.ProcessNotCreatedException: Cannot run program “docker-compose” (in directory “XXXXXX”): CreateProcess error=2, 系统找不到指定的文件

这是因为本地没有去配置docker compose,那么就无法连接远程的服务器用远程的docker compose,这个和docker不一样,docker不需要本地的任何配置,只需要直接连接即可

所以这里去配置一下,先下载docker-compose的exe执行程序到本地

下载地址:Releases · mirrors / docker / compose · GitCode

然后在idea的配置里指定刚才的exe文件位置:

image-20221109191621959

一键编排走起

一键走起

image-20221109193107217

image-20221109193034466

image-20221109193200977

6-3 编排多个微服务项目

怎么说呢,微服务和6-2节差别不大,就是docker-compose.yml文件中多加了几个服务

nacos

这里就先使用最简单的启动方式,没有把元数据持久化之类的。

TODO:先挖个坑,以后再填坑

docker run -d --name nacos -p 8848:8848 -e PREFER_HOST_MODE=hostname -e MODE=standalone nacos/nacos-server

docker-compose

version: "3"

services:
  # service_device为服务名称,在同一个网络中可以通过服务名称或者容器名称来访问容器,而不通过ip
#  build表示如果镜像不存在就根据build去构建
  service_device:
    image: quest/service_device:1.1 #镜像名称
    build:
      context: /service/service_device
      dockerfile: Dockerfile
    container_name: service_device #容器名称
    ports:
      - "8211:8211"
#    volumes: #挂载容器卷
#      - /app/quest//sgdt:/data
    networks: #指定使用的网络
      - quest_network
    depends_on: #依赖哪些服务,这些服务先启动之后才会启动当前服务
      - nacos
      - mysql

  service_ucenter:
    image: quest/service_ucenter:1.1 #镜像名称
    build:
      context: /service/service_ucenter
      dockerfile: Dockerfile
    container_name: service_ucenter
    ports:
      - "8212:8212"
    networks:
      - quest_network
    depends_on:
      - mysql
      - nacos

  service_qvs:
    image: quest/service_qvs:1.1 #镜像名称
    build:
      context: /service/service_qvs
      dockerfile: Dockerfile
    container_name: service_qvs
    ports:
      - "8213:8213"
    networks:
      - quest_network
    depends_on:
      - mysql
      - nacos


  redis:
    image: redis:6.0.8
    container_name: redis
    ports:
      - "6380:6379"
    volumes:
      - /app/redis/redis.conf:/etc/redis/redis.conf
      - /app/redis/data:/data
    networks:
      - quest_network
    command: redis-server /etc/redis/redis.conf

  mysql:
    image: mysql:5.7
    container_name: quest_mysql
    environment:
      MYSQL_ROOT_PASSWORD: '123456'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
    ports:
      - "8236:3306"
    volumes:
      - /app/quest/mysql/log:/var/log/mysql
      - /app/quest/mysql/data:/var/lib/mysql
      - /app/quest/mysql/conf:/etc/mysql/conf.d
    networks:
      - quest_network
    command: --default-authentication-plugin=mysql_native_password #解决外部无法访问

  nacos:
    image: nacos/nacos-server:latest
    container_name: nacos
    environment:
      PREFER_HOST_MODE: hostname
      MODE: standalone
    ports:
      - "8848:8848"
    networks:
      - quest_network

networks:
  quest_network:
    name: quest_network        #指定网络名称

image-20221110170855498

也可以在监控工具中查看运行状况

image.png

小总结

其实队伍微服务的编排是个很复杂的事情,尤其是依赖过多时。又是也不一定就是部署的时候就新建一个数据库新建一个mq,新建微服务的镜像等,根据实际灵活运用。

不过compose是真的很好用,很好的管理了各个服务