mysql/mysql-server
当必须指定时,
下面的大多数示例命令都有
Docker 镜像存储库(例如docker pull和docker run命令);如果您的图像来自另一个存储库,请更改它——例如,将其替换
container-registry.oracle.com/mysql/enterprise-server
为从 Oracle Container Registry (OCR) 下载的 MySQL Enterprise Edition 图像,或mysql/enterprise-server
从
My Oracle Support下载的 MySQL Enterprise Edition 图像。
为 Docker 优化的 MySQL 安装
MySQL 的 Docker 镜像针对代码大小进行了优化,这意味着它们仅包含预期与在 Docker 容器中运行 MySQL 实例的大多数用户相关的关键组件。MySQL Docker 安装在以下方面不同于常见的非 Docker 安装:
包含的二进制文件仅限于:
/usr/bin/my_print_defaults
/usr/bin/mysql
/usr/bin/mysql_config
/usr/bin/mysql_install_db
/usr/bin/mysql_tzinfo_to_sql
/usr/bin/mysql_upgrade
/usr/bin/mysqladmin
/usr/bin/mysqlcheck
/usr/bin/mysqldump
/usr/bin/mysqlpump
/usr/sbin/mysqld
所有二进制文件都被剥离;它们不包含调试信息。
配置 MySQL 服务器
启动 MySQL Docker 容器时,可以通过docker run命令将配置选项传递给服务器。例如:
docker run --name mysql1 -d mysql/mysql-server:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_col
utf8mb4
该命令以默认字符集和
utf8mb4_col
数据库的默认排序规则
启动 MySQL 服务器
。
配置MySQL Server的另一种方法是准备一个配置文件并将其挂载到容器内服务器配置文件的位置。有关详细信息,请参阅 持久化数据和配置更改。
持久化数据和配置更改
Docker 容器原则上是短暂的,如果容器被删除或损坏,任何数据或配置都将丢失(参见
此处的讨论)。
然而, Docker volumes提供了一种机制来保存在 Docker 容器内创建的数据。在初始化时,MySQL 服务器容器为服务器数据目录创建一个 Docker 卷。在容器上运行docker inspect命令
的 JSON 输出有一个Mount
键,其值提供有关数据目录卷的信息:
$> docker inspect mysql1
...
"Mounts": [
{
"Type": "volume",
"Name": "4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652",
"Source": "/var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...
输出显示,
/var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data
数据在主机上持久化的源文件夹已安装在
/var/lib/mysql
容器内的服务器数据目录中。
另一种保存数据的方法是
在创建容器时使用选项绑定挂载
主机目录。--mount
可以使用相同的技术来持久化服务器的配置。以下命令创建一个 MySQL 服务器容器并绑定挂载数据目录和服务器配置文件:
docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=/path-on-host-machine/datadir,dst=/var/lib/mysql \
-d mysql/mysql-server:tag
该命令挂载
在path-on-host-machine/my.cnf
(容器内的服务器配置文件)和
/etc/my.cnf
(path-on-host-machine/datadir
容器内的数据目录)。绑定挂载必须满足以下条件才能工作:
/var/lib/mysql
配置文件
必须已经存在,并且必须包含使用用户启动服务器的规范path-on-host-machine/my.cnf
mysql
:[mysqld] user=mysql
您还可以在该文件中包含其他服务器配置选项。
数据目录
必须已经存在。要进行服务器初始化,该目录必须为空。您还可以挂载一个预先填充了数据的目录并用它启动服务器;但是,您必须确保使用与创建数据的服务器相同的配置启动 Docker 容器,并且在启动容器时安装所需的任何主机文件或目录。path-on-host-machine/datadir
运行额外的初始化脚本
如果你想在数据库创建后立即运行
任何.sh
或
脚本,你可以将它们放入主机目录,然后将目录挂载到容器内。例如:
.sql
/docker-entrypoint-initdb.d/
docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/scripts/,dst=/docker-entrypoint-initdb.d/ \
-d mysql/mysql-server:tag
从另一个 Docker 容器中的应用程序连接到 MySQL
通过搭建Docker网络,可以让多个Docker容器相互通信,使得另一个Docker容器中的客户端应用程序可以访问服务器容器中的MySQL Server。首先,创建一个 Docker 网络:
docker network create my-custom-net
然后,当您创建和启动服务器和客户端容器时,使用--network
选项将它们放在您创建的网络上。例如:
docker run --name=mysql1 --network=my-custom-net -d mysql/mysql-server
docker run --name=myapp1 --network=my-custom-net -d myapp
然后myapp1
容器可以使用主机名连接到
mysql1
容器,
mysql1
反之亦然,因为 Docker 会自动为给定的容器名称设置 DNS。在以下示例中,我们
从容器内部运行mysq
lmyapp1
客户端以连接到
mysql1
其自己容器中的主机:
docker exec -it myapp1 mysql --host=mysql1 --user=myuser --password
有关容器的其他网络技术,请参阅 Docker 文档中的 Docker 容器网络部分。
服务器错误日志
当 MySQL 服务器首次使用您的服务器容器启动时, 如果满足以下任一条件,则不会生成 服务器错误日志:
来自主机的服务器配置文件已挂载,但该文件不包含系统变量
log_error
(请参阅 有关绑定挂载服务器配置文件的 持久数据和配置更改)。主机中的服务器配置文件尚未挂载,但 Docker 环境变量已挂载
MYSQL_LOG_CONSOLE
(true
MySQL 5.7 服务器容器的变量默认状态为false
)。然后将 MySQL Server 的错误日志重定向到stderr
,以便错误日志进入 Docker 容器的日志,并可以使用docker logsmysqld-container
命令查看。
要使 MySQL 服务器在两个条件之一为真时生成错误日志,请使用该
--log-error
选项
将服务器配置为在容器内的特定位置生成错误日志。要保留错误日志,请在容器内错误日志的位置挂载一个主机文件,如保留
数据和配置更改中所述。但是,您必须确保其容器内的 MySQL 服务器对挂载的主机文件具有写入权限。
已知的问题
在使用server系统变量
audit_log_file
配置审计日志文件名时,使用loose
option修饰符,否则Docker将无法启动服务器。
Docker 环境变量
当您创建 MySQL 服务器容器时,您可以通过使用--env
选项(-e
简称)并指定以下一个或多个环境变量来配置 MySQL 实例。
如果您挂载的数据目录不为空,则以下变量均无效,因为届时将不会尝试进行服务器初始化(有关更多详细信息,请参阅 持久数据和配置更改 )。文件夹中任何预先存在的内容,包括任何旧的服务器设置,在容器启动期间都不会被修改。
布尔变量包括
MYSQL_RANDOM_ROOT_PASSWORD
、MYSQL_ONETIME_PASSWORD
、MYSQL_ALLOW_EMPTY_PASSWORD
和MYSQL_LOG_CONSOLE
通过使用非零长度的任何字符串设置它们来实现。因此,将它们设置为例如 “ 0 ”、“ false ”或 “ no ”不会使它们为假,而是实际上使它们为真。这是 MySQL 服务器容器的一个已知问题。
MYSQL_RANDOM_ROOT_PASSWORD
:当这个变量为真时(这是它的默认状态,除非MYSQL_ROOT_PASSWORD
被设置或被MYSQL_ALLOW_EMPTY_PASSWORD
设置为真),在启动Docker容器时为服务器的root用户生成一个随机密码。密码打印到stdout
容器中,可以通过查看容器的日志找到(请参阅启动 MySQL 服务器实例)。MYSQL_ONETIME_PASSWORD
:当该变量为true时(这是它的默认状态,除非MYSQL_ROOT_PASSWORD
被设置或MYSQL_ALLOW_EMPTY_PASSWORD
设置为true),root用户的密码被设置为过期,必须更改才能正常使用MySQL。MYSQL_DATABASE
:此变量允许您指定要在图像启动时创建的数据库的名称。如果使用 和 提供用户名和密码MYSQL_USER
,MYSQL_PASSWORD
则创建用户并授予超级用户访问该数据库的权限(对应于GRANT ALL
)。指定的数据库由 CREATE DATABASE IF NOT EXIST语句创建,因此如果数据库已经存在,则该变量无效。MYSQL_USER
,MYSQL_PASSWORD
: 这些变量结合使用来创建用户并设置该用户的密码,并且该用户被授予该MYSQL_DATABASE
变量指定的数据库的超级用户权限。MYSQL_USER
和 都是MYSQL_PASSWORD
创建用户所必需的——如果两个变量中的任何一个未设置,另一个将被忽略。如果两个变量都已设置但未设置MYSQL_DATABASE
,则创建的用户没有任何权限。笔记不需要使用此机制来创建 root 超级用户,默认情况下,它是使用由 和 的描述中讨论的任一机制设置的密码创建的
MYSQL_ROOT_PASSWORD
,MYSQL_RANDOM_ROOT_PASSWORD
除非MYSQL_ALLOW_EMPTY_PASSWORD
是 true。MYSQL_ROOT_HOST
:默认情况下,MySQL 创建该'root'@'localhost'
帐户。此帐户只能从容器内部连接,如从容器内部 连接到 MySQL 服务器中所述。要允许来自其他主机的根连接,请设置此环境变量。例如,值172.17.0.1
是默认的 Docker 网关 IP,它允许来自运行容器的主机的连接。该选项只接受一个条目,但允许使用通配符(例如,MYSQL_ROOT_HOST=172.*.*.*
或MYSQL_ROOT_HOST=%
)。MYSQL_LOG_CONSOLE
:当变量为真时(MySQL 5.7 服务器容器变量的默认状态为false
),MySQL 服务器的错误日志被重定向到stderr
,这样错误日志就会进入 Docker 容器的日志,并可以使用docker logsmysqld-container
命令查看。笔记如果已安装来自主机的服务器配置文件,则该变量无效(请参阅 有关绑定安装配置文件的 持久数据和配置更改)。
MYSQL_ROOT_PASSWORD
:此变量指定为 MySQL root 帐户设置的密码。警告在命令行上设置 MySQL root 用户密码是不安全的。作为显式指定密码的替代方法,您可以使用密码文件的容器文件路径设置变量,然后从主机挂载一个包含容器文件路径中密码的文件。这仍然不是很安全,因为密码文件的位置仍然暴露。最好使用默认设置
MYSQL_RANDOM_ROOT_PASSWORD
并且MYSQL_ONETIME_PASSWORD
两者都为真。MYSQL_ALLOW_EMPTY_PASSWORD
. 将其设置为 true 以允许容器以 root 用户的空白密码启动。警告将此变量设置为 true 是不安全的,因为它将使您的 MySQL 实例完全不受保护,从而允许任何人获得完全的超级用户访问权限。最好使用默认设置
MYSQL_RANDOM_ROOT_PASSWORD
并且MYSQL_ONETIME_PASSWORD
两者都为真。