当前位置: 首页 > news >正文

Docker精通:微服务

文章目录

  • Docker进阶
    • 八、 Docker网络
      • 1、 理解网络
        • 1.1 问题引出
        • 1.2 原理
      • 2、 容器之间通信
        • 2.1 --link
        • 2.2 自定义网络
        • 2.3 网络连通
      • 3、 实战
        • 3.1 部署redis集群
        • 3.2 SpringBoot微服务部署
    • 九、 DockerCompose
      • 1、 简介
        • 1.1 微服务
        • 1.2 安装
        • 1.3 删除
      • 2、 使用
      • 3、 配置文件
    • 十、 部署案例
      • 1.1 环境准备
      • 1.2 Dockerfile
      • 1.3 自定义网络
      • 1.4 docker-compose.yaml

Docker进阶

学完Docker安装到入门这篇文章后,相信大家对Docker有了较多的理解。下面是一些高级的使用,适用于分布式搭建等

八、 Docker网络

1、 理解网络

1.1 问题引出

首先我们需要清空所有环境:

docker rm -f $(docker ps -aq)
docker rmi -f $(docker images -aq)

查看本机的网络:

我们看到了三个不同的网卡

https://fastly.jsdelivr.net/gh/liuzhongkun1/imgStore@master/202210/ohukedmph11664946042921.png

问题:docker是如何处理容器间的访问的?

  • 首先我们进行一个测试,查看本机能否ping通容器内部:

    docker run -d -P --name tomcat01 tomcat  # 我们先启动一个容器
    docker  exec -it tomcat01 /bin/bash
    # 安装网络连接工具
    apt update && apt install -y iproute2
    apt-get install inetutils-ping  # 安装ping工具
    ip addr  # 查看容器的ip地址
    

  • 我们查看能不能互相ping通

    ping 172.17.0.2  # 主机ping容器内部
    ping 10.0.2.15  # 容器内部ping主机
    

    我们发现容器和主机之间可以相互ping通

1.2 原理

  • 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只需要安装了docker,就会有一个网卡 docker0 桥接模式,使用的技术是 evth-pair 技术!

再次测试ip addr

在启动一个容器测试,发现又多了一对网卡,主机一个,容器中一个!

我们发现这个容器到来的网卡,是一对一对的:

  • evth-pair:一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连

  • 正因为有这个特性,evth-pair充当各种虚拟网络设备

    • docker容器之间的连接

所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。

Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0

https://fastly.jsdelivr.net/gh/liuzhongkun1/imgStore@master/202210/bi8p1hau341664948594736.png

Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)

只要容器删除,对应的网桥一对就没了!

2、 容器之间通信

2.1 --link

思考一个场景,我们编写一个微服务,database_url = ip,项目不重启,数据库ip换掉了,我们能不能使用名字来访问容器?

docker run --link可以用来链接2个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量。

测试:

  • 开启三个容器:

    docker run -it -d --name centos01 centos  /bin/bash
    docker run -it -d --name centos02 centos  /bin/bash
    docker run -it --name centos03 --link centos02 centos /bin/bash
    
  • 测试能否通信

    docker exec -it centos03 ping centos02  # 可以ping通
    docker exec -it centos02 ping centos03  # 不可以ping通
    docker exec -it centos01 ping centos02  # 不可以ping通
    

docker网络探究:

docker netword ls 

# NETWORK ID     NAME      DRIVER    SCOPE
# 297f07c51979   bridge    bridge    local # bridge:桥接 docker0
# 87a8f8309bfa   host      host      local
# 51b67872ea20   none      null      local

全部命令:

[root@192 ~]# docker network --help

Usage:  docker network COMMAND

Manage networks  # 管理网络

Commands:
  connect     # 将容器连接到网络
  create      # 创建网络
  disconnect  # 断开一个容器与网络的连接
  inspect     # 显示一个或多个网络的详细信息
  ls          # 网络列表
  prune       # 删除所有未使用的网络
  rm          # 删除一个或多个网络

我们来查看一下容器与网络相关的信息:

docker network inspect 297f07c51979 

我们首先来查看Tomcat02的信息

docker inspect 78904cf54659

啥也没发现

然后我们再来查看Tomcat03的信息

docker inspect 4e6aae2d99dd
# ...
"HostConfig": {
	# ...
	"Links": [
                "/tomcat02:/tomcat03/tomcat02"  # 发现了tomcat02读得相关信息
            ],
	# ...
}
# ...

说明Tomcat03与Tomcat02之间有ip映射的关系

本质就是:容器tomcat03配置了网络映射,将主机名(tomcat02)与ip地址host映射(不推荐使用)。

cat /etc/hosts

我们现在已经不建议使用--link

docker0的问题:他不支持容器名直接访问

2.2 自定义网络

查看所有的docker网络:

https://fastly.jsdelivr.net/gh/liuzhongkun1/imgStore@master/202210/2g246n5r6c1664949710397.png

网络模式:

  • bridge:桥接 docker(自己创建也是用桥接模式)
  • none:不配置网络,默认
  • host:和宿主机共享网络

运行docker

docker run -d -P --name tomcat01 --net bridge tomcat
# 我们直接启动命令 --net bridge,这个就是默认启动命令,也是docker0

# docker0特点:默认,域名不能访问,--link可以打通连接
# 我们可以自定义网络

我们创建网络的命令

[root@myCentOS ~]# docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           # 启用手动容器附件
      --aux-address map      # map网络驱动使用的辅助IPv4或IPv6地址(默认map[])
      --config-from string   # 要复制配置的网络
      --config-only          # 创建仅配置网络
  -d, --driver string        # 管理网络的驱动程序(默认为“bridge”)
      --gateway strings      # IPv4或IPv6主子网网关
      --ingress              # 创建群路由-mesh网络
      --internal             # 限制外部用户访问网络
      --ip-range strings     # 从子范围分配容器ip
      --ipam-driver string   # IP地址管理驱动程序(默认为“default”)
      --ipam-opt map         # map设置IPAM驱动的特定选项(default map[])
      --ipv6                 # 启用ipv6组网功能
      --label list           # list设置网络元数据
  -o, --opt map              # 设置驱动程序的特定选项(默认map[])
      --scope string         # 控制网络范围
      --subnet strings       # CIDR格式的子网,表示一个网段

实例:

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 

比如,我们创建一个网络,设置子网为:192.168.0.0/16,设置网关为:192.168.0.1,驱动为桥接模式。家里面的路由器默认就是这个配置

然后我们就发现我们创建的网络了。

查看我们创建的网络:

使用我们创建的网络:

docker run -d --name n1 --net mynet tomcatnet 
docker run -d --name n2 --net mynet tomcatnet 

我们再来查看我们创建的自定义网络:发现增加了我们创建的两个容器

docker network inspect mynet

我们来看一下两个容器能否互相ping通

docker exec -it n1 ping n2 
docker exec -it n2 ping n1

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐平时这样使用网络

好处:

  • redis:不同的集群使用不同的网络,保证集群是安全的

2.3 网络连通

解决问题,网段不同如何ping通

需求,我们需要从docker01连接到mynet

# 我们发现 docker01到mynet无法连通的
(base) [root@MyCentOS test]# docker run --name no1 -d -P tomcatnet
9792d84e8abf48359b6d05304ecea472ffd25d32731452412856fc07167237b4
(base) [root@MyCentOS test]# docker exec -it no1 ping n1
ping: unknown host

解决方法:我们使用docker network connect 命令

[root@192 ~]# docker network connect --help

# NETWORK:工作网络(mynet)
Usage:  docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network # 将容器连接到网络中

Options:
      --alias strings           # 为容器添加网络范围的别名
      --driver-opt strings      # 网络驱动选项
      --ip string               # IPv4地址(例如172.30.100.104)
      --ip6 string              # IPv6地址(例如,2001:db8:: 33)
      --link list               # 添加链接到另一个容器
      --link-local-ip strings   # 为容器添加链路本地地址

例如:

docker network connect mynet no1  # 把no1直接与mynet连通
# 相当于一个服务器,有两个ip,内网和公网

注意,只是一个容器与mynet连通了,不是docker01这个网段与mynet连通了

结论:假设要换网络连通别人,就需要使用docker network connect 连通

3、 实战

3.1 部署redis集群

首先,我们创建网卡:

docker network create redisnet --subnet 172.38.0.0/16

我们使用shell脚本创建六个redis配置文件:

for port in $(seq 1 6);\
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >> /mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

通过脚本创建6个redis容器:

for port in $(seq 1 6);\
do \
docker run -p 637${port}:6379 -p 1667${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisnet --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done

redis-server /etc/redis/redis.conf: 以配置文件启动redis

我们查看我们创建的集群;

docker ps 
docker inspect redisnet   # 查看网络信息

创建集群:

docker exec -it redis-1 /bin/sh  # 进入redis中
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379  --cluster-replicas 1  # 然后输入yes就配置完毕

测试部署好的集群:

redis-cli -c  # 进入集群模式
# 查看集群信息
127.0.0.1:6379> cluster nodes
35fcc7906fda3c977cf6fe09ebfd4632c8288449 172.38.0.15:6379@16379 slave 7866a044a62217acc264e0780724baebfcbdf9ec 0 1643970509988 5 connected
a2d9d996b447f724860502d4230434d8fbef45bb 172.38.0.13:6379@16379 master - 0 1643970508952 3 connected 10923-16383
59c81a95ed20b8964246dee3bfc333e25960275a 172.38.0.16:6379@16379 slave e2210b65a712c43fce9cb11a40605d4ae6afc61c 0 1643970509257 6 connected
e2210b65a712c43fce9cb11a40605d4ae6afc61c 172.38.0.12:6379@16379 master - 0 1643970508000 2 connected 5461-10922
eaa1f8ba8de966a6fffaed6b43e0226d95caffb9 172.38.0.14:6379@16379 slave a2d9d996b447f724860502d4230434d8fbef45bb 0 1643970509000 4 connected
7866a044a62217acc264e0780724baebfcbdf9ec 172.38.0.11:6379@16379 myself,master - 0 1643970507000 1 connected 0-5460

集群搭建完成

3.2 SpringBoot微服务部署

步骤:

  1. 构建SpringBoot微服务项目
  2. 打包应用
  3. 编写dockerfile
  4. 构建镜像
  5. 发布运行

构建SpringBoot项目

package com.example.demo.colltroller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloColltroer {

    @RequestMapping("/hello")
    public String hello(){
        return "hello world";
    }
}

双击Maven Package进行打包

最后打包成功,测试是否可以运行

java -jar demo1-0.0.1-SNAPSHOT.jar

上传jar包:

在idea项目根目录创建并编写Dockerfile文件

FROM java:11
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]

将jar包和Dockerfile上传到服务器中:

[root@192 idea]# ls
demo1-0.0.1-SNAPSHOT.jar  Dockerfile

构建镜像:

 docker build -t springboot .

运行docker容器:

docker run -dit -p 8080:8080 --name hello springboot 

测试能否访问成功:

curl 127.0.0.1:8080/hello

发布镜像:

docker login -u 【你的用户名】 -p 【你的密码】
# docker tag 镜像id 你的账户名/镜像仓库名:tag名
docker tag f107ab2a9246 dockerywl/springboot
# docker push 作者/镜像:TAG(版本)
docker push dockerywl/springboot

以后我们使用了Docker之后,给别人交付就是一个镜像即可!

九、 DockerCompose

1、 简介

1.1 微服务

微服务的基本特点:

  1. 对外暴露单一:对外只有一个HTTP接口
  2. 对内服务特别多:接口、数据、redis、消息队列、日志收集

Compose中有两个概念:

  • 服务(service):一个应用的容器,实际上可以包括着若干运行相同镜像的容器实例
  • 项目(project):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yaml文件中定义

使用 Docker 的时候,定义 Dockerfile 文件,然后使用 docker builddocker run 等命令操作容器。

然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,这样效率很低,也不方便管理。

使用 Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具 。

yaml 官方示例:https://docs.docker.com/compose/compose-file/compose-file-v3/#compose-file-structure-and-examples

1.2 安装

curl -L "https://github.com/docker/compose/releases/download/2.2.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose  # 国外的源,可以换成国内的
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.2.3/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose  # 修改权限

docker-compose version  # 测试是否安装成功

1.3 删除

rm /usr/local/bin/docker-compose

由于 Linux 一切皆文件,删除此文件夹即可完成 Docker Compose 的卸载。

2、 使用

(base) [root@MyCentOS ~]# docker-compose --help

Usage:  docker compose [OPTIONS] COMMAND

Docker Compose

Options:
      --ansi string                Control when to print ANSI control characters
                                   ("never"|"always"|"auto") (default "auto")
      --compatibility              Run compose in backward compatibility mode
      --env-file string            Specify an alternate environment file.
  -f, --file stringArray           Compose configuration files
      --profile stringArray        Specify a profile to enable
      --project-directory string   Specify an alternate working directory
                                   (default: the path of the Compose file)
  -p, --project-name string        Project name

Commands:
  build       构建或者重构一个微服务
  convert     Converts the compose file to platform's canonical format
  cp          Copy files/folders between a service container and the local filesystem
  create      Creates containers for a service.
  down        停止并删除相关容器以及网络信息
  events      Receive real time events from containers.
  exec        Execute a command in a running container.
  images      列出用来创建容器的镜像
  kill        强行停止一个微服务里面的容器
  logs        View output from containers
  ls          展示所有正在运行的项目
  pause       暂停微服务
  port        Print the public port for a port binding.
  ps          列出所有正在运行的容器
  pull        将微服务镜像推送到远程仓库
  push        将微服务镜像拉取到本地
  restart     重启容器
  rm          移除并且停止微服务里面的所有容器
  run         Run a one-off command on a service.
  start       启动微服务
  stop        停止微服务
  top         展示微服务运行的一些进程信息
  unpause     Unpause services
  up          创建并且启动一个容器
  version     显示docker-compose的版本信息

Run 'docker compose COMMAND --help' for more information on a command.

3、 配置文件

其为一个yaml文件,用到了yaml文件的语法。

同时官方默认的文件名称是docker-compose.yaml文件,如果是其他名字,则要通过-f参数指定配置文件。

version: "3.7"  # 指定docker-compose版本开头
services:  # 配置微服务
    postgres:  # postgres数据库,服务名唯一
        image: library/postgres:11.5-alpine  # 指定镜像类型  
        container_name: postgress115  # 容器名称,不是必填,可以用于容器间的通信 --name
        restart: always  # 启动方式 
        networks:  # 指定的网络  --net
            - postgresql  
        ports:  # 端口转发  -p
            - 5432:5432  
        environment:  # 环境变量,重点,向容器内部传递一些参数 --env
            TZ: Asia/Shanghai
            POSTGRES_USER: postgres
            POSTGRES_PASSWORD: postgres_pass
        volumes:  # 挂载数据卷,进行数据共享 -v
        	- ./data:/var/lib/postgresql/data
        env_file:  # 传入存储环境变量的文件
            - ./common.env
            - ./apps/web.env
            - /opt/secrets.env
        volumes_from:  # 从另一个服务或容器挂载它的所有卷。 
 			- service_name
 			- container_name
        	
	pgadmin:
		image: dpage/pgadmin4  # 指定镜像名称
		container_name: pgadmin  # 容器名字
		restart: unless-stopped  # 不用重启
		ports:  # 端口映射
			- 5431:80
		environment:  # 配置环境变量
			PGADMIN_DEFAULT_EMAIL: kun@qq.com
			PGADMIN_DEFAULT_PASSWORD: pwd
		depends_on:  # 启动依赖,重点
			- postgres
		networks:  # 指定网络
			- postgresql
			
	redis:
		build: /path/to/build/dir  # 指定 Dockerfile 所在文件夹的路径。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像
		command: "redis-server --appendonly yes"  # 覆盖容器启动后默认执行的命令
		expose:  # 暴露端口,但不映射到宿主机,只被连接的服务访问
			- "3306"  

volumes:  # 声明上面服务所使用的自动创建的卷名
	data:  # 声明指令的卷名 compose自动创建该卷名,会在项目启动前加入
		extranal:  # 使用自定义卷名,true确定使用的卷名,注意:需要在启动容器之前,手动创建容器,如果需要其自动创建卷,需要使用false
			true  
	
networks:  # 定义服务用到的桥 
	postgresql:  # 定义上面的服务用到的网桥名称,默认创建的就是bridge
		extranal:
			true  # 使用外部指定的网桥,注意,网桥必须要存在
			name: postgresql

最核心的是services

  • 其实是服务之间的关系

这是一些常用的docker-compose 部署语法,更多的可以到官方文档查看

十、 部署案例

flask + mysql + redis

flask:主程序

mysql: 数据存储

redis:存储session

1.1 环境准备

首先,我们写一个简易的登录验证系统

# _*_ encoding: utf-8 _*_

from flask import (Flask, request, redirect, session)
from pymysql import connect
from os import urandom
from flask_session import RedisSessionInterface
from redis import Redis

app = Flask(__name__)
app.secret_key = urandom(32)

app.config["SESSION_USE_SIGNER"] = True
app.session_interface = RedisSessionInterface(
    redis=Redis("flaskRedis"),
    key_prefix="flask_login",
)

db_config = {
    "host": "flaskMysql",  # 这个主机改为我们共享网段的路径
    "port": 3306,
    "user": "root",
    "pa***rd": "qwe123",
    "db": "custom",
    "charset": "utf8"
}
conn = connect(
    **db_config
)


@app.route('/login/<password>/<name>')
def hello_world(password, name):
    cor = conn.cursor()
    cor.execute(r"SELECT * FROM `info` WHERE name=%s and pwd=%s", (name, password))
    # cor.execute(r"SELECT * FROM `info`")
    if cor.fetchall():
        session["user_info"] = name
        return "登录成功"
    return "账号或密码错误,登录失败"


@app.route("/index")
def index():
    user_info = session.get("user_info")
    if not user_info:  # 如果没有用户信息,则返回登录页面
        return redirect("/login")
    return {
        "msg": 200,
        "data": "返回的数据,后面完善"
    }


@app.route("/loginout")
def loginout():
    del session["user_info"]  # 删除cookies信息,进行注销操作
    return redirect("/login")  # 重定向到登录页面


@app.route("/")
def red():  # 如果直接访问的话,默认跳转到登录界面
    return "首页面"  # 进行url的跳转


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8888)

同时,也要事先写好我们的SQL文件,我们将其放入/init/custom.sql,以便对数据库的快速初始化:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `info`;
CREATE TABLE `info`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `pwd` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
INSERT INTO `info` VALUES (1, 'Make', '123456');
INSERT INTO `info` VALUES (2, 'lis', 'qwe123');

SET FOREIGN_KEY_CHECKS = 1;

包依赖:requirements.txt

Flask-Session==0.4.0
Flask==2.1.3
PyMySQL
redis==4.3.4

然后,我们将这些文件一同提交到服务器中

1.2 Dockerfile

FROM python:3.9
MAINTAINER kun<350051500050@qq.com>

ENV MYPATH /usr/src/app/

WORKDIR $MYPATH

COPY . $MYPATH

RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.douban.com/simple

CMD python init.py && python app.py  # 

1.3 自定义网络

使得不同容器之间可以实现网络通信

docker network create --subnet 192.169.0.0/16 --gateway 192.169.0.1 flasknet 

1.4 docker-compose.yaml

version: "3.7"

services:
  mysql1:  # 配置一个数据库
    image: mysql:5.7  # 拉取的镜像版本
    container_name: flaskMysql  # 定义数据库的名字
    restart: always  # 是否重启
    networks:  # 网络连接
      - flasknet
    environment:  # 环境配置
      MYSQL_ROOT_PASSWORD: qwe123  # 数据库登录密码
      MYSQL_DATABASE: custom  # 会创建这个数据库
    volumes:  # 挂载的卷
      - mysqlconf:/etc/mysql/confi.d
      - mysqldata:/var/lib/mysql
      - ./init/:/docker-entrypoint-initdb.d/  # docker-entrypoint-initdb.d,mysql启动时会扫描这个目录,运行脚本

  redis1:  # 配置redis
    image: redis  # 拉取redis镜像
    container_name: flaskRedis  # 这个数据的名称,类似于域名
    restart: always  # 是否进行重启
    networks:  # 网络配置,使得容器之间网络可以连通
      - flasknet
    volumes:  # 挂载数据卷
      - redisconf:/etc/redis/redis.conf
      - redisdata:/data
  app:
    build:  # 通过Dockerfile创建镜像
      .
    container_name: flaskService  # 对容器命名
    restart: always  # 是否进行重启
    networks:  # 网络配置
      - flasknet
    volumes:  # 挂载的数据卷
      - /root/flask-test/:/usr/src/app/
    depends_on:  # 配置依赖环境
      - mysql1
      - redis1
    ports:  # 端口映射
      - 8888:8888
      
networks:  # 声明我们的网络,同时,这个网络是我们自己创建的
  flasknet:
    external: true

volumes:  # 声明数据卷,具名数据卷自动创建,不需要我们手动创建
  mysqlconf:
  mysqldata:
  redisdata:
  redisconf:

新知识点:

  • MYSQL_DATABASE:设置mysql在启动时需要创建的数据库
  • ./init/:/docker-entrypoint-initdb.d/ : 数据库初始化脚本,当Mysql容器首次启动时,会在 /docker-entrypoint-initdb.d目录下扫描 .sh,.sql,.sql.gz类型的文件。如果这些类型的文件存在,将执行它们来初始化一个数据库

注意:

  • 如果使用了匿名数据卷,要保证映射的匿名数据卷的数据目录是空的,不然数据库无法运行新的脚本
  • 所以,执行docker-compose up 命令之前,要清空映射mysql数据库文件的目录哦,有时候还会存在隐藏文件,也要删掉(rm -rf 执行时要注意执行的目录是否正确)!

相关文章:

  • 解决dtypes.py:513: FutureWarning:...系列问题【TensorFlow】
  • Linux:详解TCP协议段格式
  • 为啥从我激情满满的要做前端开发,到现在不断的怀疑自己能不能学会?
  • 【明道云】如何让用户可以新增但不能修改记录
  • 增强现实(AR)的开发工具
  • [LeetCode]516. 最长回文子序列[记忆化搜索解法详解]
  • 代码库管理工具Git介绍
  • Go语言学习-实现一个workshop
  • Spring中的事务和事务的传播机制
  • VScode打开keil5软件的内容
  • [rust] 10 project, crate, mod, pub, use: 项目目录层级组织, 概念和实战
  • 苹果分拣检测YOLOV8NANO
  • HCIA-LTE学习总结03~04
  • Python Apex Legends 武器自动识别与压枪 全过程记录
  • 『Android』Toolbar+DrawerLayout+NavigationView实现类似QQ侧边栏效果
  • 10.13面试整理
  • 下一代 IDE 工具 JetBrains Fleet 正式公测
  • Node.js3---nodejs的内置模块之url模块
  • 什么样的小程序才能留住客户?
  • EXCEL表格-系统时间及进度自动记录工具制作
  • 走进元宇宙--手势交互技术详解
  • Zookeeper集群安装部署
  • 机器学习笔记 - 在Vehicles数据集上训练 YOLOv5 目标检测器
  • flutter系列之:把box布局用出花来
  • 计算机毕业设计JAVA旧物置换网站mybatis+源码+调试部署+系统+数据库+lw
  • GridView使用详情
  • springboot(四)
  • 基于腾讯云Docker部署PXC搭建MySQL集群
  • Node.js:模块化
  • java面试-GC垃圾回收机制
  • 没有谷歌翻译,我该怎么办?
  • Java Web Spring核心之AOP的解析及实战(AOP的实现、切入点、Aspect Spring的持久化 Hibernate)