【Dockerfile 实战:基于 Ubuntu/CentOS 镜像构建 MySQL 8.4自定义镜像】

提示:本文原创作品,良心制作,干货为主,简洁清晰,一看就会

文章目录


前言

MySQL作为主流开源数据库,在容器化部署场景中,基于不同系统镜像构建定制化MySQL镜像尤为关键。本文分别以Ubuntu和CentOS两大主流Linux发行版为基础,详细拆解MySQL镜像的构建流程,从环境配置、依赖安装到非交互式密码设置、服务启动等核心环节逐一讲解,帮助读者掌握跨系统的MySQL容器镜像构建方法,适配不同的部署环境需求

一、基于ubuntu镜像构建mysql镜像

MySQL官网:https://dev.mysql.com/downloads/mysql/

先在mysql官网下载好对应系统版本的tar包

1.1 前置环境准备

bash 复制代码
# 1. 准备前置环境
root@docker1:~# docker pull ubuntu:22.04   #准备基础镜像
root@docker1:~# mkdir -p /data/docker-images/mysql   #准备dockerfile目录
root@docker1:~# cd /data/docker-images/mysql
root@docker1:/data/docker-images/mysql# ls   #下载tar包到该目录
mysql-server_8.4.8-1ubuntu22.04_amd64.deb-bundle.tar

1.2 编写dockerfile

bash 复制代码
# 2. 编写Dockerfile
root@docker1:~# vim /data/docker-images/mysql/Dockerfile 
FROM ubuntu:22.04

# 设置非交互式环境(关键:避免 apt/debconf 弹出交互窗口)
ENV DEBIAN_FRONTEND=noninteractive
# 预先设置 MySQL root 密码(可自定义,建议容器部署时通过 --env 覆盖)
ENV MYSQL_ROOT_PASSWD=qing@123

# 安装基础依赖和工具
RUN apt update && \
    apt install -y \
    libaio1 \
    libmecab2 \
    libnuma1 \
    lsb-release \
    perl \
    psmisc \
    libsasl2-2 \
    libsasl2-modules \
    libsasl2-modules-db \
    wget \
    && rm -rf /var/lib/apt/lists/*

RUN mkdir /mysql-install
ADD mysql-server_8.4.8-1ubuntu22.04_amd64.deb-bundle.tar /mysql-install

# 设置 MySQL root 密码
RUN debconf-set-selections <<EOF
mysql-community-server mysql-community-server/root-pass password ${MYSQL_ROOT_PASSWD}
mysql-community-server mysql-community-server/re-root-pass password ${MYSQL_ROOT_PASSWD}
EOF

WORKDIR /mysql-install

# 按正确顺序安装所有 MySQL 包
RUN dpkg -i mysql-common_8.4.8-1ubuntu22.04_amd64.deb && \
    dpkg -i mysql-community-client-plugins_8.4.8-1ubuntu22.04_amd64.deb && \
    dpkg -i libmysqlclient24_8.4.8-1ubuntu22.04_amd64.deb && \
    dpkg -i mysql-community-client-core_8.4.8-1ubuntu22.04_amd64.deb && \
    dpkg -i mysql-community-client_8.4.8-1ubuntu22.04_amd64.deb && \
    dpkg -i mysql-client_8.4.8-1ubuntu22.04_amd64.deb && \
    dpkg -i mysql-community-server-core_8.4.8-1ubuntu22.04_amd64.deb && \
    dpkg -i mysql-community-server_8.4.8-1ubuntu22.04_amd64.deb || true

# 修复可能存在的依赖问题
RUN apt-get install -f -y

# 确保 MySQL 正确安装
RUN dpkg -l | grep mysql

EXPOSE 3306

# 创建 MySQL 数据目录
RUN mkdir -p /var/lib/mysql /var/run/mysqld && \
    chown -R mysql:mysql /var/lib/mysql /var/run/mysqld

CMD ["mysqld", "--user=mysql"]

1.3 运行容器

bash 复制代码
# 4. 构建镜像
root@docker1:/data/docker-images/mysql# docker build -t mysql:v1 .

# 5. 运行容器
root@docker1:/data/docker-images/mysql# docker run -itd --name mysql1 -p 3306:3306 mysql:v1 
root@docker1:/data/docker-images/mysql# docker ps
CONTAINER ID   IMAGE      COMMAND                 CREATED         STATUS         PORTS                                       NAMES
65e5ceea89c8   mysql:v1   "mysqld --user=mysql"   6 seconds ago   Up 5 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp   mysql1

# 6. 进入容器,查看mysql版本
root@docker1:/data/docker-images/mysql# docker exec -it mysql1 /bin/bash
root@65e5ceea89c8:/mysql-install# mysql -uroot -p'qing@123'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.4.8 MySQL Community Server - GPL

Copyright (c) 2000, 2026, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.4.8     |
+-----------+

二、基于centos镜像构建mysql镜像

MySQL官网:https://dev.mysql.com/downloads/mysql/

选择对应自己系统版本的tar包

2.1 前置环境准备

bash 复制代码
#前置环境准备
[root@docker ~]# docker pull centos:7   #拉取基础镜像
[root@docker ~]# mkdir -p /data/docker-images/mysql  #准备mysql镜像目录
[root@docker ~]# cd /data/docker-images/mysql  
[root@docker mysql]# ls   #下载tar包到该目录
mysql-8.4.8-linux-glibc2.17-x86_64.tar.xz

2.2 编写dockerfile

bash 复制代码
# 编写dockerfile
[root@docker mysql]# vim Dockerfile 
# 1. 基础镜像
FROM centos:7

# 2. 更换成阿里源
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum clean all && \
    yum makecache

# 安装相关依赖
RUN yum install -y libaio-devel numactl-devel perl xz

# 3. 创建 mysql 系统用户,创建 mysql 的安装目录和数据存放目录
RUN useradd -r -M -s /sbin/nologin mysql && mkdir -p /mysql/install && mkdir /mysql/data

# 4. 复制 mysql tar 包并解压
COPY mysql-8.4.8-linux-glibc2.17-x86_64.tar.xz /tmp/
RUN tar -xf /tmp/mysql-8.4.8-linux-glibc2.17-x86_64.tar.xz -C /mysql/install --strip-components=1

# 5. 创建相关项目并授权
RUN mkdir -p /var/lib/mysql /var/log/mysql /etc/my.cnf.d && \
    chown -R mysql:mysql /mysql && chmod 755 /mysql && \
    chown -R mysql:mysql /var/lib/mysql && chmod 755 /var/lib/mysql && \
    chown -R mysql:mysql /var/log/mysql && chmod 755 /var/log/mysql

# 6. 设置 mysql 配置文件
RUN echo '[mysqld]' > /etc/my.cnf && \
    echo 'user=mysql' >> /etc/my.cnf && \
    echo 'basedir=/mysql/install' >> /etc/my.cnf && \
    echo 'datadir=/mysql/data' >> /etc/my.cnf && \
    echo 'socket=/var/lib/mysql/mysql.sock' >> /etc/my.cnf && \
    echo 'port=3306' >> /etc/my.cnf && \
    echo 'log-error=/var/log/mysql/mysqld.log' >> /etc/my.cnf && \
    echo 'pid-file=/var/run/mysqld/mysqld.pid' >> /etc/my.cnf && \
    echo '' >> /etc/my.cnf && \
    echo '[client]' >> /etc/my.cnf && \
    echo 'socket=/var/lib/mysql/mysql.sock' >> /etc/my.cnf

# 7. 创建 pid 目录并设置权限
RUN mkdir -p /var/run/mysqld && \
    chown -R mysql:mysql /var/run/mysqld && \
    chmod 755 /var/run/mysqld

# 8. 拷贝脚本,暴露端口,做持久化
COPY start-mysql.sh /usr/local/
RUN chmod +x /usr/local/start-mysql.sh
EXPOSE 3306
VOLUME ["/mysql/data"]
WORKDIR /mysql/install
CMD ["/usr/local/start-mysql.sh"]

2.3 编写启动脚本

bash 复制代码
# 编写启动脚本
[root@docker mysql]# cat start-mysql.sh 
#!/bin/bash
set -e

# 设置客户端参数,指定socket路径
export MYSQL_UNIX_PORT=/var/lib/mysql/mysql.sock

# 检查数据目录是否已初始化(避免重复初始化)
if [ ! -f /mysql/data/ibdata1 ]; then
    echo "Initializing MySQL data directory..."
    
    # 初始化MySQL,生成临时密码
    /mysql/install/bin/mysqld --initialize --user=mysql --datadir=/mysql/data --basedir=/mysql/install
    
    echo "Starting MySQL temporarily to set root password..."
    
    # 启动MySQL服务(临时)- 指定socket路径
    /mysql/install/bin/mysqld_safe --user=mysql --socket=/var/lib/mysql/mysql.sock &
    
    # 等待MySQL启动
    echo "Waiting for MySQL to start..."
    sleep 15
    
    # 提取临时密码 - 从配置的日志位置读取
    LOG_FILE="/var/log/mysql/mysqld.log"
    if [ -f "$LOG_FILE" ]; then
        echo "Reading temporary password from $LOG_FILE"
        # 显示日志内容的前几行用于调试
        echo "Log file content (first 20 lines):"
        head -20 "$LOG_FILE"
        
        # 提取临时密码
        TEMP_PASS=$(grep 'temporary password' "$LOG_FILE" | awk '{print $NF}')
        if [ -z "$TEMP_PASS" ]; then
            echo "Error: Could not find temporary password in log file"
            echo "Full log file content:"
            cat "$LOG_FILE"
            exit 1
        fi
        echo "Temporary password found: $TEMP_PASS"
    else
        echo "Error: Cannot find log file at $LOG_FILE"
        # 尝试在其他位置查找
        echo "Searching for log files..."
        find / -name "*.log" -type f 2>/dev/null | head -10
        exit 1
    fi
    
    # 等待MySQL完全启动
    echo "Waiting for MySQL to be ready..."
    sleep 10
    
    # 测试连接
    echo "Testing connection to MySQL..."
    for i in {1..5}; do
        if /mysql/install/bin/mysql -uroot -p"$TEMP_PASS" --connect-expired-password --socket=/var/lib/mysql/mysql.sock -e "SELECT 1" 2>/dev/null; then
            echo "Connection successful!"
            break
        else
            echo "Connection attempt $i failed, waiting..."
            sleep 3
        fi
    done
    
    # 修改root密码
    echo "Setting new root password..."
    /mysql/install/bin/mysql -uroot -p"$TEMP_PASS" --connect-expired-password --socket=/var/lib/mysql/mysql.sock <<EOF
ALTER USER 'root'@'localhost' IDENTIFIED BY 'qing@123';
FLUSH PRIVILEGES;
EOF
    
    # 允许远程访问
    echo "Creating remote root user..."
    /mysql/install/bin/mysql -uroot -p'qing@123' --socket=/var/lib/mysql/mysql.sock <<EOF
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY 'qing@123';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EOF
    
    # 停止临时MySQL进程
    echo "Stopping temporary MySQL instance..."
    /mysql/install/bin/mysqladmin -uroot -p'qing@123' --socket=/var/lib/mysql/mysql.sock shutdown
    sleep 5
fi

echo "Starting MySQL in foreground..."
# 以前台方式启动MySQL
exec /mysql/install/bin/mysqld_safe --user=mysql --socket=/var/lib/mysql/mysql.sock

2.4 运行容器

bash 复制代码
[root@docker mysql]# docker build -t mysql8.4:v1 .  #构建镜像
[root@docker mysql]# docker run -itd --name mysql1 -p 3306:3306 mysql8.4:v1
[root@docker mysql]# docker exec -it mysql1 /bin/bash  #进入容器
[root@bdbc575eb3a1 install]# bin/mysql -uroot -p'qing@123'   #连接mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.4.8 MySQL Community Server - GPL

Copyright (c) 2000, 2026, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.4.8     |
+-----------+

mysql> exit
Bye
[root@bdbc575eb3a1 install]# read escape sequence

# 直接通过宿主机也可以连接容器内的mysql
[root@docker mysql]# /usr/local/mysql/bin/mysql -h 127.0.0.1 -P 3306 -uroot -p'qing@123'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.4.8 MySQL Community Server - GPL

Copyright (c) 2000, 2026, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.4.8     |
+-----------+

注:

文中若有疏漏,欢迎大家指正赐教。

本文为100%原创,转载请务必标注原创作者,尊重劳动成果。

求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~

相关推荐
刘延林.1 小时前
win11系统下通过 WSL2 安装Ubuntu 24.04 使用RTX 5080 GPU
linux·运维·ubuntu
用户34268877621964 小时前
Agent + Ollama 部署踩坑记录
ubuntu
宁波阿成4 小时前
在ubuntu22.04源码级安装sub2api
linux·运维·ubuntu·ai·api·token·中转站
程序猿online5 小时前
本地mysql密码重置
数据库·mysql
为美好的生活献上中指6 小时前
本地虚拟机部署redis集群
前端·redis·ubuntu·bootstrap·html·redis集群
Bert.Cai6 小时前
MySQL CEIL()函数详解
数据库·mysql
一叶龙洲6 小时前
Ubuntu开机无法用向日葵远程控制
linux·运维·ubuntu
Bert.Cai7 小时前
MySQL FLOOR()函数详解
数据库·mysql
小碗羊肉7 小时前
【MySQL | 第七篇】索引
数据库·mysql
hanyi_qwe7 小时前
Mysql 与 Nginx 双机高可用
数据库·mysql·nginx