Docker入门学习教程
Docker入门学习
文章目录
- Docker入门学习
- 1.简介
- 2 基本概念
- 2.1 镜像(Image)
- 2.2 容器(Container)
- 2.3 仓库(Repository)
- 3.Windows Docker安装
- 3.1 更改默认安装位置
- 3.2 安装步骤
- 4.使用镜像
- 4.1 获取镜像
- 4.2 列出镜像
- 4.3 删除本地镜像
- 5.容器
- 5.1 启动容器
- 5.1.1 新建并启动
- 5.1.2 启动已终止容器
- 5.2 后台运行
- 5.3 终止容器
- 5.4 进入容器
- 5.4.1 attach命令
- 5.4.2 exec 命令
- 5.5 删除容器
- 6.定制镜像
- 7.目录挂载
- 7.1 数据卷(Volumes)
- 7.2 挂载主机目录
- 8.Docker Compose
- 问题1:Flask容器不能访问MySQL容器,多次更改主机号都连接不上。
- 问题2:RuntimeError: ‘cryptography’ package is required for sha256_password or caching_sha2_password auth methods
- 9.发布和部署
- 实践1.Docker安装MySQL
- 问题:sqlyog:2058连接错误
1.简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
简单来说,Docker可以简化开发环境配置;方便不同系统(Windows/Mac/Linux),不同环境(生产环境,预发环境和开发环境)的程序部署迁移。
Docker 和传统虚拟化方式的区别:
- 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
- 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
2 基本概念
2.1 镜像(Image)
Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
可以理解为软件安装包,可以方便的进行传播和安装。
2.2 容器(Container)
镜像(Image
)和容器(Container
)的关系,就像是面向对象程序设计中的 类
和 实例
一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
可以理解为软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。
2.3 仓库(Repository)
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。
一个Docker Registry中可以包含多个仓库Repository
);每个仓库可以包含多个标签(Tag
);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest
作为默认标签。
仓库名经常以两段式路径形式出现,比如 kint216/flask
,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。
3.Windows Docker安装
3.1 更改默认安装位置
因为Docker的默认安装位置在C盘,而我的C盘容量越来越小,故采取了以下的方式更改Docker的安装位置。
# Docker的安装位置:
# C:\Program Files\Docker
# C:\ProgramData\Docker
# C:\ProgramData\DockerDesktop
# C:\Users\你的用户名\AppData\Local\Docker
# C:\Users\你的用户名\AppData\Roaming\Docker
在有管理员权限的cmd
中执行以下命令:
mklink /j "C:\Program Files\Docker" "自定义的位置"
"自定义的位置“必须在执行命令前手动建立。
执行完上面的命令后直接安装docker就行了。该命令会在“默认的位置”那创建一个指向“自定义位置”的快捷方式(和自己添加的快捷方式不同)。如果想撤回这个命令的话,在”默认的位置“那把快捷方式删了就行。
3.2 安装步骤
下载地址:https://hub.docker.com/editions/community/docker-ce-desktop-windows
- 双击下载好的exe文件,配置勾选下面两个选择,自动安装相应的配置。
配置下载完成后需要重启电脑。
启动Docker时报错,需要手动更新WSL 2内核。
- 根据提示的连接中的步骤4下载 Linux 内核更新包,下载后手动更新。
此时可以正常打开Docker,显示页面如下。
设置镜像源,加快下载速度。
镜像加速器 | 镜像加速器地址 |
---|---|
Docker 中国官方镜像 | https://registry.docker-cn.com |
DaoCloud 镜像站 | http://f1361db2.m.daocloud.io |
Azure 中国镜像 | https://dockerhub.azk8s.cn |
科大镜像站 | https://docker.mirrors.ustc.edu.cn |
阿里云 | https://<your_code>.mirror.aliyuncs.com |
七牛云 | https://reg-mirror.qiniu.com |
网易云 | https://hub-mirror.c.163.com |
腾讯云 | https://mirror.ccs.tencentyun.com |
# 加入的代码如下"registry-mirrors": ["https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://mirror.ccs.tencentyun.com"],
4.使用镜像
4.1 获取镜像
Docker Hub 上有大量的高质量的镜像可以用,从 Docker镜像仓库获取镜像的命令是docker pull
。其命令格式为:
$ docker pull [选项] [Docker Registry地址[:端口号]/]仓库名[:标签]
具体的选项可以通过 docker pull --help
命令看到,这里我们说一下镜像名称的格式。
- Docker 镜像仓库地址:地址的格式一般是
<域名/IP>[:端口号]
。默认地址是 Docker Hub(docker.io
)。 - 仓库名:这里的仓库名是两段式名称,即
<用户名>/<软件名>
。对于 Docker Hub,如果不给出用户名,则默认为library
,也就是官方镜像。
$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
284055322776: Pull complete
Digest: sha256:0fedbd5bd9fb72089c7bbca476949e10593cebed9b1fb9edf5b79dbbacddd7d6
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub (docker.io
)获取镜像。而镜像名称是 ubuntu:18.04
,因此将会获取官方镜像 library/ubuntu
仓库中标签为 18.04
的镜像。docker pull
命令的输出结果最后一行给出了镜像的完整名称,即: docker.io/library/ubuntu:18.04
。
4.2 列出镜像
列出已经下载的镜像,可以使用 docker image ls
命令。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker/getting-started latest 26d80cd96d69 2 months ago 28.5MB
ubuntu 18.04 5a214d77f5d7 4 months ago 63.1MB
ubuntu bionic 5a214d77f5d7 4 months ago 63.1MB
ccr.ccs.tencentyun.com/dockerpracticesig/docker_practice latest a54473bbb25a 7 months ago 47.3MB
列表包含了 仓库名
、标签
、镜像 ID
、创建时间
以及 所占用的空间
。
镜像 ID则是镜像的唯一标识,一个镜像可以对应多个标签。因此,在上面的例子中,我们可以看到 ubuntu:18.04
和 ubuntu:bionic
拥有相同的 ID,因为它们对应的是同一个镜像。
不加任何参数的情况下,docker image ls
会列出所有顶层镜像,但是有时候我们只希望列出部分镜像。docker image ls
有好几个参数可以帮助做到这个事情。
- 根据仓库名列出镜像
$ docker image ls ubuntu
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 5a214d77f5d7 4 months ago 63.1MB
ubuntu bionic 5a214d77f5d7 4 months ago 63.1MB
- 列出特定的某个镜像,也就是说指定仓库名和标签
$ docker image ls ubuntu:18.04
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 5a214d77f5d7 4 months ago 63.1MB$ docker image ls ubuntu:bionic
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu bionic 5a214d77f5d7 4 months ago 63.1MB
4.3 删除本地镜像
删除本地的镜像,可以使用 docker image rm
命令,其格式为:
$ docker image rm [选项] <镜像1> [<镜像2> ...]
其中,<镜像>
可以是 镜像短 ID
、镜像长 ID
、镜像名
。
比如我们有这么一些镜像:
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker/getting-started latest 26d80cd96d69 2 months ago 28.5MB
ubuntu 18.04 5a214d77f5d7 4 months ago 63.1MB
ubuntu bionic 5a214d77f5d7 4 months ago 63.1MB
ccr.ccs.tencentyun.com/dockerpracticesig/docker_practice latest a54473bbb25a 7 months ago 47.3MB
我们可以用镜像的完整 ID,也称为 长 ID
,来删除镜像,但更多的时候是用 短 ID
来删除镜像。docker image ls
默认列出的就已经是短 ID 了,一般取前3个字符以上,只要足够区分于别的镜像就可以了。
比如这里,如果我们要删除 docker/getting-started
镜像,可以执行:
$ docker image rm 26d
Untagged: docker/getting-started:latest
Untagged: docker/getting-started@sha256:86093b75a06bf74e3d2125edb77689c8eecf8ed0cb3946573a24a6f71e88cf80
Deleted: sha256:26d80cd96d6905cdc4f95c8e4cac9e1dce43cc9d81054fff28371728435891a8
Deleted: sha256:417302e3ee3f952e11b2c25c5295ac437e9eceb97b5d50683ab9717688c2c47a
Deleted: sha256:8dfa110a9ba2693c02cc4311773b7a7ebdd02a8be91d089cd4cfc4a7ca51a75c
Deleted: sha256:57dba6dab88290f4e9b3125f9e6b3b088626af1fe3a93d47056c030ac7d51c1c
Deleted: sha256:67c225b96afdfdb9c2b8f6f7284d771fe20ff5ebabc65a088afeca1fbafadbee
Deleted: sha256:d8242f1082c90da0b3819a2737bc23215237e2440857a0c5ec0904abc81e81b0
Deleted: sha256:329df243003cb0259caf109da224f24391d0a4e3fe419fde5a6f092ee27424fe
Deleted: sha256:bdb2ce57de00bca016d44a1def44f2a281dfe027bbc4975d65c8ff4cf04d63fb
Deleted: sha256:1a058d5342cc722ad5439cacae4b2b4eedde51d8fe8800fcf28444302355c16d
我们也可以用镜像名
,也就是 <仓库名>:<标签>
,来删除镜像。
$ docker image rm ubuntu:18.04
Untagged: ubuntu:18.04
如果观察上面这几个命令的运行输出信息的话,你会注意到删除行为分为两类,一类是 Untagged
,另一类是 Deleted
。我们之前介绍过,镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。
因此当我们使用上面命令删除镜像的时候,实际上是在要求删除某个标签的镜像,这就是 Untagged
的信息。因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 Delete
行为就不会发生。所以在执行docker image rm ubuntu:18.04
指令时,只是仅取消了标签名18.04
,因为该ubuntu镜像还有其他的标签名bionic
当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为。镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变得非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。
除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。
5.容器
容器是独立运行的一个或一组应用,以及它们的运行态环境。
5.1 启动容器
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(exited
)的容器重新启动。
5.1.1 新建并启动
有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。使用的命令主要为 docker run
。
例如,下面的命令则启动一个 bash 终端,允许用户进行交互。
$ docker run -it --rm ubuntu:18.04 bashroot@10781f4737ca:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.6 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
root@10781f4737ca:/# exit
exit
-it
:这是两个参数,一个是-i
交互式操作,一个是-t
终端,即交互式终端。--rm
:这个参数是说容器退出后随之将其删除。ubuntu:18.04
:这是指用ubuntu:18.04
镜像为基础来启动容器。bash
:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是bash
。
进入容器后,我们可以在 Shell 下操作,执行任何所需的命令。这里,我们执行了 cat /etc/os-release
,这是 Linux 常用的查看当前系统版本的命令,从返回的结果可以看到容器内是 Ubuntu 18.04.1 LTS
系统。最后我们通过 exit
退出了这个容器。
当利用 docker run
来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从
registry
下载 - 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去(-p参数)
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
5.1.2 启动已终止容器
可以利用 docker container start
命令,直接将一个已经终止(exited
)的容器启动运行。
5.2 后台运行
更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出。此时,可以通过添加 -d
参数来实现。
如果不使用 -d
参数运行容器。
$ docker run ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
hello world
从上面的例子中可以看到,容器会把输出的结果打印出来。
如果使用了 -d
参数运行容器。
$ docker run -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
9822df018d4e99c8057af442a90f5b18dd4e73ea40627602bba4312f38364300
此时容器会在后台运行并不会把输出的结果打印(输出结果可以用 docker logs
查看)。
使用 -d
参数启动后会返回一个唯一的 id,也可以通过 docker container ls
命令来查看容器信息。
要获取容器的输出信息,可以通过 docker container logs
命令。
$ docker container logs [container ID or NAMES]
hello world
hello world
hello world
. . .
在docker desktop中也可以查看容器的logs。
5.3 终止容器
可以使用 docker container stop
来终止一个运行中的容器。此外,当 Docker 容器中指定的应用终结时,容器也自动终止。
$ docker container stop [container ID]
处于终止状态的容器,可以通过 docker container start
命令来重新启动。
此外,docker container restart
命令会将一个运行态的容器终止,然后再重新启动它。
5.4 进入容器
在使用 -d
参数时,容器启动后会进入后台。某些时候需要进入容器进行操作,可以使用 docker attach
命令或 docker exec
命令。
5.4.1 attach命令
# 启动容器
$ docker run -dit ubuntu
862613a2556eb1dcd3aefcd954ee0eda25ee71d21baba0f6ed4fb364b05cd680# 查看容器状态
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
862613a2556e ubuntu "bash" 3 seconds ago Up 2 seconds infallible_cori# 根据container ID进入某一容器
$ docker attach 862
# 退出
root@862613a2556e:/# exit
exit# 查看结束attach指令后的容器状态
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
如果exit,会导致容器的停止。
5.4.2 exec 命令
# 启动容器
$ docker run -dit ubuntu
6f242cd3ca38dbc32e85d55821ed23336a2b935fa19a8aa97d42df054723477d# 查看容器状态
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6f242cd3ca38 ubuntu "bash" 4 seconds ago Up 3 seconds naughty_williamson# 根据container ID进入某一容器
$ docker exec -it 6f24 bash
# 查看当前目录
root@6f242cd3ca38:/# ls
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# 退出
root@6f242cd3ca38:/# exit
exit# 查看结束exec指令后的容器状态
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6f242cd3ca38 ubuntu "bash" 5 minutes ago Up 5 minutes naughty_williamson
如果exit,不会导致容器的停止。
推荐使用 docker exec
指令。
5.5 删除容器
可以使用docker container rm
来删除一个处于终止状态
的容器。
$ docker container rm [container ID]
如果要删除一个运行中的容器,可以添加 -f
参数。Docker 会发送 SIGKILL
信号给容器。
用 docker container ls -a
命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。
$ docker container prune
6.定制镜像
镜像是容器的基础,每次执行 docker run
的时候都会指定哪个镜像作为容器运行的基础。在之前的例子中,我们所使用的都是来自于 Docker Hub 的镜像。直接使用这些镜像是可以满足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜像。
下面通过基于Flask框架的一个demo做演示。
文件目录结构
demo/app.pyrequirements.txtDockerfile
后端代码如下,打开网页显示Hello, World!
:
from flask import Flaskapp = Flask(__name__)@app.route("/")
def hello_world():return "Hello, World!"if __name__ == '__main__':app.run(host='0.0.0.0')
requirements.txt内容如下:
flask
Dockerfile
内容如下:
# FROM 指定基础镜像
FROM python:3.8-slim-buster
# 指定Docker命令的工作路径,如果路径不存在,Docker会自动创建
WORKDIR /app
# 将所有程序拷贝到Docker镜像中
# COPY <本地路径> <目标路径>
# 第一个'.'代表程序根目录下的所有文件;第二个'.'代表Docker镜像中的路径,即当前的工作路径'/app/'
COPY . .
# 创建镜像,安装环境,RUN指令是在创建镜像时使用
RUN pip install -r requirements.txt
# CMD指令用来指定当Docker容器运行起来执行的命令
CMD ["python","app.py"]
在Dockerfile
文件目录下输入指令,-t
参数是指定镜像名称,.
告诉docker在该目录下寻找Dockerfile
文件
$ docker build -t demo .
docker按照我们编写的指令逐步执行,如下图。
然后我们通过docker run
指令来启动一个容器。-p
是将容器上的某一个端口映射到本地主机上,这样我们才能从主机上访问容器中的Web服务,前面的8080是本地主机上的端口,后面的5000是容器上的端口;-d
让容器在后台运行,这样输出不会直接显示在控制台;--name
参数指定容器的名称,如果未设置Docker会随机生成一个容器名称。
$ docker run -p 8080:5000 -d --name web demo
此时在浏览器打开localhost:8080
,就可以在网页中看到Hello World!
注意:Flask后端的代码主机号要写成0.0.0.0
,否则容器启动后在本机上打开报错。
7.目录挂载
7.1 数据卷(Volumes)
数据卷是一个可供一个或多个容器使用的特殊目录,有以下特性:
- 可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 更新数据卷不会影响镜像
- 数据卷默认会一直存在,即使容器被删除
# 创建一个数据卷
$ docker volume create 数据卷名字# 查看所有的数据卷
$ docker volume ls# 在主机里使用以下命令可以查看指定数据卷的信息
$ docker volume inspect 数据卷名字# 删除数据卷
$ docker volume rm my-vol# 删除不使用的数据卷
$ docker volume prune
下面演示启动一个挂载数据卷的容器:
# 创建数据卷
$ docker volume create test
test# 查看数据卷
$ docker volume ls
DRIVER VOLUME NAME
local test# 用ubuntu镜像创建一个名为test的容器,且将新创建的数据卷挂载到/volume目录下,如果没有该目录Docker会自动创建
$ docker run -dit --name test -v test:/volume ubuntu
57cc84da548f5f60da942e77cd5bf3ec9be5baff31adb3dfa21178bf1a5587cc# 进入容器,创建测试文件
$ docker exec -it 57cc bash
root@57cc84da548f:/# cd volume
root@57cc84da548f:/volume# touch test.txt
此时可以看到数据卷中也出现了测试文件。
7.2 挂载主机目录
在本地创建一个挂载目录,这里我用的目录是D:\Volume
。
挂载一个本地主机目录作为数据卷,命令如下:
# 用ubuntu镜像创建一个名为test的容器,且将本地目录挂载到/volume目录下,如果没有该目录Docker会自动创建
$ docker run -dit --name test01 -v /d/Volume:/volume ubuntu
为了能够在容器中修改文件,我在容器里安装vim
,用到指令如下:
# 更新apt源
apt-get update
# 安装vim
apt-get install -y vim
在容器中创建文件:
$ docker exec -it test01 bash
root@7c6623ff53d2:/# cd volume
# 创建测试文件,内容为“Container test”
root@7c6623ff53d2:/volume# vim test.txt
本地文件夹中也会同步更新。
8.Docker Compose
在很多情况下,我们需要多个容器相互配合来完成某项任务。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。Compose
恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml
模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
这里我使用一个简单的个人博客系统作为演示,包括Flask后端和MySQL数据库两部分。
仓库地址:https://github.com/LenkyAndrews/notebook-docker
文件目录如下:
notebook/docker-compose.ymlflask/...dockerfilemysql/notebook.sqldockerfile
后端flask文件夹中的dockerfile如下:
FROM python:3.8-slim-buster
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
CMD ["python","app.py"]
数据库mysql文件夹中的dockerfile如下:
FROM mysql
COPY ./notebook.sql /docker-entrypoint-initdb.d
notebook.sql
是数据库初始化文件,它会把flask应用需要用到的库和表创建出来。在mysql官方镜像中提供了容器启动时自动执行/docker-entrypoint-initdb.d
文件夹下的脚本的功能(包括shell脚本和sql脚本) 。因此我们只要把初始化文件在镜像启动时复制到/docker-entrypoint-initdb.d
文件夹就可以了。
要把项目依赖的多个服务集合到一起,我们需要编写一个docker-compose.yml
文件,描述依赖哪些服务。
# 版本号
version: '3'services:# 定义数据库容器mysql:# 执行数据库文件夹下的dockerfilebuild: ./mysql# 设置主机和容器的端口映射ports:- "3307:3306"environment:# 设置root用户密码- MYSQL_ROOT_PASSWORD=123456# 定义后端容器flask:# 执行后端文件夹下的dockerfilebuild: ./flask# 设置主机和容器的端口映射ports:- "5000:5000"
完成以上步骤后,在docker-compose.yml
文件所在目录,执行命令:
$ docker-compose up -d
问题1:Flask容器不能访问MySQL容器,多次更改主机号都连接不上。
# 后端报错提示
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on '0.0.0.0' ([Errno 111] Connection refused)")
网页报错提示如下:
解决方案:
在github
和stack overflow
上查询类似的问题后,发现是我的host和port写错了。host应该写成数据库服务的名称,即docker-compose.yml
中的mysql
;因为我将容器的端口3306
映射到本地主机的端口3307
,之前我一直写的是3307
端口没成功,这两个容器是处在同一个网络中的,所以改成3306
端口后就可以相互通信了。
# 数据库连接代码
class MysqlUtil():def __init__(self):host = 'mysql' # 主机名port = 3306 # 端口号user = 'root' # 数据库用户名password = '123456' # 数据库密码database = 'notebook' # 数据库名称self.db = pymysql.connect(host=host, port=port, user=user, password=password, db=database) # 建立连接self.cursor = self.db.cursor(cursor=pymysql.cursors.DictCursor) # 设置游标,并将游标设置为字典类型
问题2:RuntimeError: ‘cryptography’ package is required for sha256_password or caching_sha2_password auth methods
解决方法:
安装cryptography
包,或者设置加密方式(在docker-compose.yml
或手动修改)。
9.发布和部署
在Docker Hub上注册账号
创建一个镜像库
- 命令行登录账号:
$ docker login -u username
- 新建一个tag,名字跟注册账号一样
$ docker tag notebook_flask:latest username/notebook:v1
- 推到远端仓库
$ docker push username/notebook:v1
- 此时可以从远端仓库拉取部署使用
$ docker run -dp 8080:5000 --name hub_notebook username/notebook:v1
实践1.Docker安装MySQL
# 拉取镜像
$ docker pull mysql# 运行一个MySQL容器
# -p 3306:3306 :映射容器服务的3306端口到宿主机的3307端口,外部主机可以直接通过宿主机ip:3307访问到MySQL的服务。
# MYSQL_ROOT_PASSWORD=123456:设置MySQL服务root用户的密码。
$ docker run -itd --name mysql-test -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
问题:sqlyog:2058连接错误
在本地主机连接mysql
出现sqlyog:2058的错误。意思是客户端不支持caching_sha2_password的加密方式。
解决步骤:
- 进入容器
$ docker exec -it mysql-test bash
- 登录
mysql -uroot -p
- 查看一下当前root用户的加密方式,发现此时root用户的加密方式是caching_sha2_password
select user,host,plugin from mysql.user where user = 'root';
- 更改加密规则,需要重新设置root密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root密码';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root密码';
- 刷新权限配置
flush privileges;
Docker入门学习教程相关推荐
- ES(Elasticsearch)入门学习教程
Elasticsearch 入门学习教程 1.1 为什么要学Elasticsearch? 1.2 如何下载安装使用ES? 1.2.1 ES 安装使用条件 1.2.2 ES 下载须知 1.2.3 ES ...
- MAYA 2022基础入门学习教程
流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:3.41 GB |时长:4.5小时 包含 ...
- 3dmax Vray建筑可视化入门学习教程
面向初学者的3Ds Max Vray最佳Archviz可视化课程 从安装到最终图像的一切都将从头开始教授,不需要任何经验 大小解压后:3.25G 时长4h 6m 1280X720 MP4 语言:英语+ ...
- Blender 3.0基础入门学习教程 Introduction to Blender 3.0
成为Blender通才,通过这个基于项目的循序渐进课程学习所有主题的基础知识. 你会学到什么 教程获取:Blender 3.0基础入门学习教程 Introduction to Blender 3.0- ...
- Maya游戏角色绑定入门学习教程 Game Character Rigging for Beginners in Maya
准备好开始为游戏制作自己的角色动画了吗? 你会学到什么 了解Maya的界面 优化并准备好你的模型,为游戏做准备 了解关节以及如何使用它们来构建健壮的角色骨骼,以便在任何游戏引擎中制作动画 了解IK和F ...
- 三维地形制作软件 World Machine 基础入门学习教程
<World Machine课程>涵盖了你需要的一切,让你有一个坚实的基础来构建自己的高质量的电影或视频游戏地形. 你会学到什么 为渲染或游戏开发创建高分辨率.高细节的地形. 基于Worl ...
- Blender3.0动画制作入门学习教程 Learn Animation with Blender (2021)
要求 下载并安装Blender.免费下载和免费用于任何目的. 描述 加入我的动画课程. 在本课程中,我将从头开始讲述在Blender中创建动画场景的过程. 从第一步到最终渲染.在这个课程中,我们将使用 ...
- UE5真实环境设计入门学习教程
大小解压后:4.69G 时长4h 30m 1280X720 MP4 语言:英语+中英文字幕(根据原英文字幕机译更准确) 虚幻引擎5–面向初学者的真实环境设计 Unreal Engine 5 – Rea ...
- ZBrush全面入门学习教程 Schoolism – Introduction to ZBrush
ZBrush全面入门学习教程 Schoolism – Introduction to ZBrush ZBrush全面入门学习教程 Schoolism – Introduction to ZBrush ...
最新文章
- html(超链接定义锚点与特殊符号转义)
- android错误整理——模拟器无法连接网络
- 《敏捷开发绩效管理》扩展阅读(敏捷开发绩效管理,敏捷团队绩效管理)
- CodeForces - 850C Arpa and a game with Mojtaba(博弈+sg函数)
- C#操作Access数据库 增删改查
- 关于iPhone的UIView刷新(转)
- 在oracle中游标的操作,Oracle中的游标和函数详解
- linux 提取日志字段,记一次Linux下提取MySQL日志关键字段
- python---内置模块
- 编程之美 3.1 字符串移位包含问 复杂度(O(N*K)
- opencv基础:相机参数标定(camera calibration)及标定结果如何使用
- 使用Java实现简单串口通信
- 【SAS系列】SAS入门书籍推荐
- 基于STM32-ESP8266-阿里云-微信小程序的智慧舒适家庭控制系统项目
- 不删除磁盘内容,如何给C盘扩容
- leetcode算法 森林中的兔子
- ffmpeg v4l2集成分析
- android webview 横竖屏_Android 切换横竖屏
- 【Android】Studio 依赖 ButterKnife 黄油刀 时出现 空指针异常
- 编程修养 - 来自网络整理
热门文章
- C++笔记 char
- matplotlib:使用子图实现简易象形图
- X3D制作简易三维动画
- HCIP(四)---BMA,NBMA网络类型
- 从“薛定谔的猫”联想到“好奇害死猫”
- 慧居科技在港交所上市状态“失效”,双良科技为控股股东
- 阅兵式直播刺杀总统,无人机敢死队有多可怕
- 图形界面 II: 设置库的事件处理函数 (第三章)
- 思科配置系统日志服务器配置,思科交换机路由器配置日志服务器脚本
- Unity用户手册2019.3(中文版)1.3.1 常见资源类型