一、前言

Docker是一种容器化技术,需要在虚拟机上运行这个软件,之前做苍穹外卖的时候就发现,每次启动项目的时候都需要重新启动redis和nginx,这样非常麻烦,而且不便于管理,有时候会忘记启动某个服务,导致后端报错,Docker就可以解决这个问题,他允许一次性启动多个容器,容器中可以存入类似于redis和mysql或者是nginx的服务器,这样,我们在虚拟机上可以一次性启动所有服务,并且可以在主机上面操作这些服务(例如使用mysql数据库创建表之类的操作)。

而Docker起到了管理这些服务器的作用。

二、原理

这里我画了两张图,上面展现得很直观了:

1.对于镜像和仓库的理解

这里我们选择阿里云作为远程的镜像仓库(当然也可以是其他的),镜像相当于是个安装包,远程镜像仓库更像是一个软件商场,下载到本地后,可以在手机(容器)上安装,这个安装包可以给很多人(容器)使用,但是我们不管有多少人使用,安装包下载一次就够了。

亲测这几个镜像源可以正常使用(2025/12/3)

{
  "registry-mirrors": [
    "https://jqk3qd27.mirror.aliyuncs.com",
    "http://hub-mirror.c.163.com",
    "https://mirrors.tuna.tsinghua.edu.cn",
    "http://mirrors.sohu.com",
    "https://ustc-edu-cn.mirror.aliyuncs.com",
    "https://ccr.ccs.tencentyun.com",
    "https://docker.m.daocloud.io",
    "https://docker.awsl9527.cn"
        
  ]
} 

2.对于宿主机和容器的理解

这是一个比较复杂的过程,要想在windows主机上面控制容器,我们必须找到Docker的守护线程,经过配置,我们将守护线程端口号设置为了2375,这是个约定俗成的端口号,表示未加密的守护线程端口,这个端口连接的是Docker的大脑,通过守护线程,我们可以控制所有容器的增删改查,所以一般是需要加密的(加密的端口是2376),同时我们需要屏蔽防火墙,把这几个端口对外露出来,这样在主机才能找到宿主机的端口。

下图就是屏蔽了3306、3307、2375三个端口的防火墙,后面使用nginx还需要屏蔽80端口。

所以为了使用方便,在学习阶段我们可以暂时将防火墙取消掉。

3.IDEA中的Docker

由于我们拿到了端口,所以在IDEA中也可以访问Docker了:

这也算是一种图形化界面了,可以很清楚的看到Docker的容器和镜像列表。

三、部署MySQL

我们需要使用命令来创建容器:

这表示的是:在宿主机3306端口,映射mysql的3306端口创建名为mysql的容器,设置数据源密码为123,选择上海时区。

映射的概念请在图2查看。

docker run -d \
   --name mysql \
   -p 3306:3306 \
   -e TZ=Asia/Shanghai \
   -e MYSQL_ROOT_PASSWORD=123 \
   mysql

所以在idea中,我们创建数据源时,就可以直接通过Linux的容器进行创建了

四、挂载

在讲挂载之前,先讲一下MobaXterm终端工具怎么和虚拟机创建连接,按照如下选项创建,注意,一定要指定用户名为root!!!

这个终端工具在某些方面比FinalShell做得好,比如图形化文件。

1.数据卷

为什么我们需要数据卷?

一个容器的组成如下:

1.分层文件系统:容器由只读的镜像层和可写的容器层组成。

2.数据与容器生命周期绑定:任何在容器运行时创建、修改的文件(比如 MySQL 的数据库文件、你的日志文件)都存放在这个可写层里。

那么当容器被删除,这个可写层也会被删除,里面的所有数据都会丢失。

为了解决这个问题,我们将使用数据卷。

数据卷相当于一个U盘,电脑重装系统过后,插上U盘可以将原来的数据全部导入到新的系统中去。

数据卷可以命名,并且需要指定一个路径,这是宿主机的真实路径,这个容器允许产生的数据将保留在宿主机的这个路径上。

比如:

# 语法:-v <卷名>:<容器内路径>
docker run -d --name my-mysql \
  -v mysql_data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=password \
  mysql:latest

这个容器产生的数据就会存放在/var/lib/mysql中。

所以自然的,如果需要挂载数据到这个数据库中,必须手动创建这个文件,并且将对应配置和数据卷放进去,这样才能在容器中识别这个数据库中的数据。

至于每个服务器挂载的路径,这都是有严格规定的,通常都是由服务器的公司规定的,可以在DockerHub上面查询到官方给出的路径。

还需要注意一点,这个路径的功能不只是可以用于存放数据,还可以存放配置文件,这样服务器就可以读取这个配置,当然,这些一定需要按照官方路径来存放。

五、容器网络

容器网络可以看作一个允许不同容器之间相互访问的一个局域网,比如黑马商城的项目容器,一定需要访问到mysql的容器,所以要把他们放到一个容器网络当中,这里没什么好说的,容器网络创建后命名即可。

如图所示:

六、Dockerfile

Dockerfile是用于构建自定义镜像的,每个dockerfile都是由入口、层、基础镜像构成,相当于为镜像提供了一个统一的骨架。这样我们通过一个统一的步骤,就可以自定义镜像了。

比如下面代码就是一个Dockerfile:

# 基础镜像
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 hm-service.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

比如,我们想要部署一个Java项目到Docker,那就需要我们先将这个项目搞成一个镜像,怎么搞?先将项目打包成jar包,然后肯定需要编译这个jar包,所以我们的基础镜像必须要有jdk11(所以jdk11其实也是一个镜像,但是这个不是自定义的,所以我们获取这个镜像的方式是拉取镜像)。

七、DockerCompose

这是一个工具,用于将我们对容器允许配置写到一个yml文件中,这样就可以使配置更加直观,便于后续维护,所以我们如果要运行容器时,我们直接运行这个配置文件就可以一键部署了,比如下面就是一个DockerCompose:


services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    networks:
      - hm-net
  hmall:
    build: 
      context: .
      dockerfile: Dockerfile
    container_name: hmall
    ports:
      - "8080:8080"
    networks:
      - hm-net
    depends_on:
      - mysql
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "18080:18080"
      - "18081:18081"
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./nginx/html:/usr/share/nginx/html"
    depends_on:
      - hmall
    networks:
      - hm-net
networks:
  hm-net:
    name: hmall

要运行这个Compose只需要使用命令即可将配置文件中的所有配置好的容器在后台允许:

docker compose up -d

同时注意,Compose是个独立的个服务,是与其他容器隔离的。

更多推荐