基于Alpine构建MySQL 10.11.11镜像的完整教程
在容器化技术日益流行的今天,使用Docker构建高效、轻量级的MySQL镜像成为许多开发者的需求。本教程将详细介绍如何基于Alpine Linux构建MySQL 10.11.11镜像,Alpine Linux以其小巧的体积和快速的启动速度而闻名,非常适合用于构建容器镜像。
文件目录结构
MySQL/
├── docker-entrypoint.sh
├── Dockerfile
└── my.cnf
0 directories, 3 files
核心文件内容
Dockerfile
FROM alpine:3.18
# 切换至旧版本仓库并安装依赖
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& echo "http://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories \
&& apk update \
&& apk add --no-cache \
mysql=10.11.11-r0 \
mysql-client=10.11.11-r0 \
mariadb-connector-c-dev=3.3.5-r0 \
&& mkdir -p /var/run/mysqld /var/lib/mysql \
&& chown -R mysql:mysql /var/run/mysqld /var/lib/mysql
COPY my.cnf /etc/mysql/my.cnf
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
VOLUME /var/lib/mysql
EXPOSE 3306
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["mysqld", "--user=mysql"]
my.cnf 配置文件
[mysqld]
user=mysql
datadir=/var/lib/mysql
port=3306
character-set-server=utf8
collation-server=utf8_general_ci
default-authentication-plugin=mysql_native_password
[client]
default-character-set=utf8
docker-entrypoint.sh
#!/bin/sh
set -eo pipefail
# 初始化数据库逻辑
if [ -z "$(ls -A /var/lib/mysql)" ]; then
if ! mysql_install_db --user=mysql --datadir=/var/lib/mysql > /dev/null; then
echo "Failed to initialize MySQL database"
exit 1
fi
mysqld --user=mysql --datadir=/var/lib/mysql --skip-networking &
MYSQL_PID=$!
# 等待MySQL启动
until mysqladmin ping --silent; do
sleep 1
done
# 设置root密码
if ! mysql -uroot <<-EOSQL
ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';
FLUSH PRIVILEGES;
EOSQL
then
echo "Failed to set root password"
exit 1
fi
kill $MYSQL_PID
wait $MYSQL_PID
fi
# 启动MySQL服务
exec "$@"
构建及运行命令
构建镜像
在构建镜像时,可以使用--cache-from
参数来利用之前构建的缓存,加快构建速度。
docker build --cache-from mysql:10.11-alpine -t mysql:10.11-alpine .
- 使用
docker build
命令构建镜像,-t
参数指定镜像的标签为mysql:10.11-alpine
,.
表示当前目录为构建上下文。
运行容器(需设置root密码)
docker run -d \
--name mysql \
-e MYSQL_ROOT_PASSWORD='Tech@12345' \
-v mysql_data:/var/lib/mysql \
-p 3306:3306 \
mysql:10.11-alpine
- 使用
docker run
命令运行容器,-d
参数表示容器在后台运行。 --name mysql
指定容器的名称为mysql8
。-e MYSQL_ROOT_PASSWORD=
设置环境变量MYSQL_ROOT_PASSWORD
,用于指定MySQL的root
用户密码。-v mysql_data:/var/lib/mysql
将容器内的/var/lib/mysql
目录挂载到名为mysql_data
的数据卷上,实现数据持久化。-p 3306:3306
将容器的3306端口映射到宿主机的3306端口,方便外部访问。
下面是Dockerfile内容解说
基础镜像选择
FROM alpine:3.18
- 我们选择
alpine:3.18
作为基础镜像,因为Alpine Linux的镜像非常小巧,这意味着构建出来的MySQL镜像也会相对较小,从而减少磁盘空间的占用,同时也能加快镜像的拉取和容器的启动速度。
仓库切换与依赖安装
# 切换至旧版本仓库并安装依赖
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& echo "http://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories \
&& apk update \
&& apk add --no-cache \
mysql=10.11.11-r0 \
mysql-client=10.11.11-r0 \
mariadb-connector-c-dev=3.3.5-r0 \
&& mkdir -p /var/run/mysqld /var/lib/mysql \
&& chown -R mysql:mysql /var/run/mysqld /var/lib/mysql
- 使用
sed
命令将Alpine Linux的软件源替换为阿里云的镜像源,这样可以加快软件包的下载速度。 - 添加
http://mirrors.aliyun.com/alpine/v3.18/community
仓库,确保可以获取到所需的软件包。 - 使用
apk update
更新软件包列表,然后使用apk add --no-cache
安装MySQL服务、MySQL客户端以及mariadb-connector-c-dev
。--no-cache
参数可以避免在镜像中缓存安装包,进一步减小镜像体积。 - 创建MySQL运行和数据目录
/var/run/mysqld
和/var/lib/mysql
,并将其所有者设置为mysql
用户,确保MySQL服务有正确的权限。
配置文件和入口脚本复制
COPY my.cnf /etc/mysql/my.cnf
COPY docker-entrypoint.sh /usr/local/bin/
- 将本地的
my.cnf
配置文件复制到容器内的/etc/mysql/my.cnf
路径,用于配置MySQL服务。 - 将
docker-entrypoint.sh
脚本复制到容器内的/usr/local/bin/
路径,该脚本将作为容器的入口点,用于初始化数据库和启动MySQL服务。
数据卷和端口暴露
VOLUME /var/lib/mysql
EXPOSE 3306
- 使用
VOLUME
指令声明/var/lib/mysql
为数据卷,这样可以将MySQL的数据存储在宿主机上,避免容器删除时数据丢失。 - 使用
EXPOSE
指令暴露MySQL服务的默认端口3306,方便容器与外部进行通信。
入口点和默认命令
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["mysqld", "--user=mysql"]
- 使用
ENTRYPOINT
指令指定容器启动时执行的脚本为docker-entrypoint.sh
。 - 使用
CMD
指令指定容器启动后默认执行的命令为mysqld --user=mysql
,即启动MySQL服务。
my.cnf配置文件详解
mysqld配置段
[mysqld]
user=mysql
datadir=/var/lib/mysql
port=3306
character-set-server=utf8
collation-server=utf8_general_ci
default-authentication-plugin=mysql_native_password
[client]
default-character-set=utf8
user=mysql
:指定MySQL服务运行的用户为mysql
。datadir=/var/lib/mysql
:指定MySQL数据存储的目录为/var/lib/mysql
。port=3306
:指定MySQL服务监听的端口为3306。character-set-server=utf8
:设置MySQL服务器的字符集为utf8
。collation-server=utf8_general_ci
:设置MySQL服务器的字符排序规则为utf8_general_ci
,支持更广泛的字符范围。default-authentication-plugin=mysql_native_password
:强制使用mysql_native_password
认证方式,避免部分客户端因兼容性问题无法连接。
client配置段
default-character-set=utf8
:设置MySQL客户端的默认字符集为utf8
。
docker-entrypoint.sh脚本详解
#!/bin/sh
set -eo pipefail
脚本开头设置
#!/bin/sh
:指定脚本使用sh
解释器执行。set -eo pipefail
:设置脚本在遇到错误时立即退出,并且在管道命令中只要有一个子命令失败,整个管道命令就失败。
# 初始化数据库逻辑
if [ -z "$(ls -A /var/lib/mysql)" ]; then
mysql_install_db --user=mysql --datadir=/var/lib/mysql > /dev/null
mysqld --user=mysql --datadir=/var/lib/mysql --skip-networking &
MYSQL_PID=$!
# 等待MySQL启动
until mysqladmin ping --silent; do
sleep 1
done
# 设置root密码
mysql -uroot <<-EOSQL
ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';
FLUSH PRIVILEGES;
EOSQL
kill $MYSQL_PID
wait $MYSQL_PID
fi
数据库初始化流程
- 使用
if [ -z "$(ls -A /var/lib/mysql)" ]
判断/var/lib/mysql
目录是否为空,如果为空则表示数据库尚未初始化。 - 使用
mysql_install_db
初始化MySQL数据库。 - 启动MySQL服务,并设置
--skip-networking
参数,避免在初始化过程中接受外部连接。 - 使用
until mysqladmin ping --silent; do sleep 1; done
循环等待MySQL服务启动。 - 使用
mysql -uroot
执行SQL语句,修改root
用户的密码为环境变量MYSQL_ROOT_PASSWORD
的值,并刷新权限。 - 最后杀死临时启动的MySQL进程,并等待其退出。
启动MySQL服务
# 启动MySQL服务
exec "$@"
- 使用
exec "$@"
执行传递给脚本的所有参数,即启动MySQL服务。
关键实现说明
依赖安装
通过mariadb-connector-c-dev
提供caching_sha2_password
插件支持,同时显式指定MySQL 10.11.11的Alpine软件包版本以确保兼容性。
配置优化
my.cnf
中强制使用mysql_native_password
认证方式,避免部分客户端因兼容性问题无法连接。
数据持久化
使用VOLUME
声明数据目录,并通过docker run
的-v
参数实现宿主机挂载,保证数据安全。
初始化流程
入口脚本docker-entrypoint.sh
实现了数据库初始化、密码设置和服务启动的完整流程,兼容官方镜像的行为逻辑。
总结
通过本教程,你学会了如何基于Alpine Linux构建MySQL 10.11.11镜像,包括Dockerfile的编写、配置文件的设置、入口脚本的实现以及镜像的构建和运行。同时,你还了解了如何安装额外的模块,希望这些知识能帮助你更好地使用Docker构建自己的镜像。