一、基于源码构建 MySQL 5.7.44 Arm64 镜像

创建一个shell

#!/bin/bash
set -e  # 添加错误处理

imageTag=mysql-openeuler:5.7.44

# 2. 设置环境变量
export DOCKER_BUILDKIT=1
export DOCKER_CLI_EXPERIMENTAL=enabled

# 3. 清理和设置构建器
echo "设置 Docker Buildx 构建器..."
rm -rf /tmp/buildkitd.toml
cat > /tmp/buildkitd.toml << 'EOF'
debug = true
root = "/var/lib/buildkit"

[registry."docker.io"]
  mirrors = [
  		"https://e2zfh98i.mirror.aliyuncs.com",
  		"https://mirror.baidubce.com",
  		"https://docker.mirrors.ustc.edu.cn",
  		"https://docker-cf.registry.cyou",
  		"https://dockercf.jsdelivr.fyi",
  		"https://docker.jsdelivr.fyi",
  		"https://dockertest.jsdelivr.fyi",
  		"https://dockerproxy.com",
  		"https://docker.m.daocloud.io",
  		"https://docker.nju.edu.cn",
  		"https://docker.mirrors.sjtug.sjtu.edu.cn",
  		"https://mirror.iscas.ac.cn",
  		"https://docker.rainbond.cc",
  		"https://do.nark.eu.org",
  		"https://dc.j8.work",
  		"https://dockerproxy.com",
  		"https://gst6rzl9.mirror.aliyuncs.com",
  		"https://registry.docker-cn.com",
  		"http://hub-mirror.c.163.com",
  		"http://mirrors.ustc.edu.cn/",
  		"https://mirrors.tuna.tsinghua.edu.cn/",
  		"http://mirrors.sohu.com/"
	]
EOF

# 清理现有构建器
docker buildx rm mybuilder 2>/dev/null || true

# 创建构建器
if ! docker buildx create \
  --name mybuilder \
  --driver docker-container \
  --driver-opt "image=moby/buildkit:master" \
  --platform linux/arm64 \
  --config /tmp/buildkitd.toml \
  --use; then
    echo "错误:创建构建器失败"
    exit 1
fi

# 启动构建器
docker buildx inspect --bootstrap

# 4. 创建正确的 Dockerfile
echo "创建 Dockerfile..."
cat > Dockerfile << 'EOF'
# 使用华为云镜像源
FROM openeuler/openeuler:20.03-lts-sp4 AS builder

# 设置参数
ARG MYSQL_VERSION=5.7.44
ARG TARGETARCH=arm64
ARG MYSQL_HOME=/usr/local/mysql
ARG MYSQL_DATA_DIR=/var/lib/mysql

# 安装编译和构建依赖
RUN dnf install -y \
    tar \
    xz \
    gzip \
    bzip2 \
    wget \
    curl \
    cmake \
    gcc \
    gcc-c++ \
    gcc-gfortran \
    make \
    openssl openssl-devel \
    ncurses-devel \
    libaio-devel \
    openssl-devel \
    numactl-devel \
    zlib-devel \
    bison \
    flex \
    libedit-devel \
    readline-devel \
    pkg-config \
    libtirpc \
    libtirpc-devel \
    perl \
    perl-Data-Dumper \
    perl-Env \
    perl-ExtUtils-MakeMaker \
    perl-ExtUtils-Embed \
    && dnf clean all

# 为 RPC 创建必要的符号链接
RUN ln -sf /usr/include/tirpc /usr/include/rpc 2>/dev/null || true \
    && ln -sf /usr/include/tirpc/rpc /usr/include/rpc 2>/dev/null || true

# 下载 MySQL 5.7.44 源码
RUN wget https://downloads.mysql.com/archives/get/p/23/file/mysql-boost-${MYSQL_VERSION}.tar.gz \
    && tar -xzf mysql-boost-${MYSQL_VERSION}.tar.gz \
    && rm -f mysql-boost-${MYSQL_VERSION}.tar.gz

# 编译 MySQL
WORKDIR /mysql-${MYSQL_VERSION}

RUN sed -i '/INCLUDE(cmake\/abi_check.cmake)/d' CMakeLists.txt

# 可选:添加调试信息查看修改结果
RUN echo "=== 查看 CMakeLists.txt 修改结果(包含 abi_check 的行)===" \
    && grep -n "abi_check" CMakeLists.txt || echo "未找到 abi_check 相关行"

RUN cmake . \
    -DCMAKE_INSTALL_PREFIX=${MYSQL_HOME} \
    -DMYSQL_DATADIR=${MYSQL_DATA_DIR} \
    -DSYSCONFDIR=/etc \
    -DWITH_INNOBASE_STORAGE_ENGINE=1 \
    -DWITH_ARCHIVE_STORAGE_ENGINE=1 \
    -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
    -DWITH_READLINE=1 \
    -DWITH_SSL=system \
    -DWITH_ZLIB=system \
    -DWITH_LIBWRAP=0 \
    -DENABLED_LOCAL_INFILE=1 \
    -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
    -DEXTRA_CHARSETS=all \
    -DDEFAULT_CHARSET=utf8mb4 \
    -DDEFAULT_COLLATION=utf8mb4_general_ci \
    -DWITH_EMBEDDED_SERVER=1 \
    -DENABLE_DOWNLOADS=1 \
    -DDOWNLOAD_BOOST=1 \
    -DWITH_BOOST=/mysql-${MYSQL_VERSION}/boost \
    -DBUILD_CONFIG=mysql_release \
    -DWITH_NUMA=ON \
    -DWITH_DEBUG=OFF \
    -DWITH_RAPID=OFF

RUN make -j$(nproc) && make install

# 第二阶段:最终镜像
FROM openeuler/openeuler:20.03-lts-sp4

# 设置参数
ARG MYSQL_VERSION=5.7.44
ARG MYSQL_HOME=/usr/local/mysql
ARG MYSQL_DATA_DIR=/var/lib/mysql
ARG MYSQL_LOG_DIR=/var/log/mysql
ENV PATH=${MYSQL_HOME}/bin:${PATH}
ENV TZ=Asia/Shanghai
ENV LANG=en_US.utf8

# 设置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 安装运行时依赖
RUN dnf install -y \
    tar \
    xz \
    perl \
    perl-Data-Dumper \
    libaio \
    numactl shadow-utils \
    ncurses-compat-libs \
    procps-ng \
    hostname \
    && dnf clean all

# 创建 MySQL 用户和组
RUN groupadd -r mysql \
    && useradd -r -g mysql -s /bin/false -d ${MYSQL_DATA_DIR} mysql \
    && mkdir -p ${MYSQL_HOME} ${MYSQL_DATA_DIR} ${MYSQL_LOG_DIR} \
    && chown -R mysql:mysql ${MYSQL_HOME} ${MYSQL_DATA_DIR} ${MYSQL_LOG_DIR}

# 从构建阶段复制 MySQL
COPY --from=builder ${MYSQL_HOME} ${MYSQL_HOME}

# 复制配置文件
COPY my.cnf /etc/my.cnf
COPY docker-entrypoint.sh /usr/local/bin/

# 设置权限
RUN chmod +x /usr/local/bin/docker-entrypoint.sh \
    && mkdir -p /var/run/mysql \
    && chown -R mysql:mysql /var/run/mysql \
    && ln -sf ${MYSQL_HOME}/bin/* /usr/local/bin/ 2>/dev/null || true

# 验证架构
RUN echo "Building for architecture: $(uname -m)"

# 暴露端口
EXPOSE 3306
EXPOSE 33060

# 设置数据卷
VOLUME ["${MYSQL_DATA_DIR}", "${MYSQL_LOG_DIR}"]

# 设置工作目录
WORKDIR ${MYSQL_HOME}

# 设置入口点
ENTRYPOINT ["docker-entrypoint.sh"]

# 默认命令
CMD ["mysqld"]
EOF


echo "创建my.cnf..."
cat > my.cnf << 'EOF'
[mysqld]
user=mysql
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysql/error.log
pid-file=/var/run/mysql/mysql.pid

# 字符集设置
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
init-connect='SET NAMES utf8mb4'

# 连接设置
max_connections=1000
max_connect_errors=1000
connect_timeout=60
wait_timeout=28800
interactive_timeout=28800

# 缓冲池设置
innodb_buffer_pool_size=256M
innodb_log_file_size=128M
innodb_log_buffer_size=16M
innodb_flush_log_at_trx_commit=1
innodb_lock_wait_timeout=50

# 查询缓存设置
query_cache_type=1
query_cache_size=32M
query_cache_limit=1M

# 二进制日志
server-id=1
log-bin=mysql-bin
expire_logs_days=7
binlog_format=ROW

# 慢查询日志
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
log_queries_not_using_indexes=1

# 安全设置
skip-name-resolve
local-infile=0
symbolic-links=0

[client]
default-character-set=utf8mb4
socket=/var/lib/mysql/mysql.sock

[mysql]
default-character-set=utf8mb4
EOF

# 5. 创建修复后的启动脚本
echo "创建启动脚本..."
cat > docker-entrypoint.sh << 'EOF'
#!/bin/bash
set -e

# 设置环境变量
MYSQL_HOME=${MYSQL_HOME:-/usr/local/mysql}
MYSQL_DATA_DIR=${MYSQL_DATA_DIR:-/var/lib/mysql}
MYSQL_LOG_DIR=${MYSQL_LOG_DIR:-/var/log/mysql}

# 设置权限
chown -R mysql:mysql ${MYSQL_DATA_DIR} ${MYSQL_LOG_DIR} /var/run/mysql

# 如果数据目录为空,则初始化数据库
if [ ! -d "${MYSQL_DATA_DIR}/mysql" ]; then
    echo "初始化 MySQL 数据库..."
    
    # 初始化数据库
    ${MYSQL_HOME}/bin/mysqld \
        --initialize-insecure \
        --user=mysql \
        --datadir=${MYSQL_DATA_DIR} \
        --basedir=${MYSQL_HOME}
    
    echo "MySQL 初始化完成"
    
    # 启动临时服务来设置 root 密码
    ${MYSQL_HOME}/bin/mysqld \
        --user=mysql \
        --datadir=${MYSQL_DATA_DIR} \
        --skip-networking \
        --socket=/tmp/mysql.sock &
    
    pid="$!"
    
    # 等待 MySQL 启动
    for i in {30..0}; do
        if ${MYSQL_HOME}/bin/mysqladmin ping --socket=/tmp/mysql.sock >/dev/null 2>&1; then
            break
        fi
        echo '等待 MySQL 启动...'
        sleep 1
    done
    
    if [ "$i" = 0 ]; then
        echo >&2 'MySQL 启动失败'
        exit 1
    fi
    
    # 设置 root 密码
    if [ -n "${MYSQL_ROOT_PASSWORD}" ]; then
        mysql --socket=/tmp/mysql.sock -u root -e \
            "ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';"
    else
        mysql --socket=/tmp/mysql.sock -u root -e \
            "ALTER USER 'root'@'localhost' IDENTIFIED BY '';"
    fi
    
    # 创建远程 root 用户
    if [ -n "${MYSQL_ROOT_HOST}" ] && [ "${MYSQL_ROOT_HOST}" != "localhost" ]; then
        mysql --socket=/tmp/mysql.sock -u root -p"${MYSQL_ROOT_PASSWORD}" -e \
            "CREATE USER 'root'@'${MYSQL_ROOT_HOST}' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';" || true
        mysql --socket=/tmp/mysql.sock -u root -p"${MYSQL_ROOT_PASSWORD}" -e \
            "GRANT ALL PRIVILEGES ON *.* TO 'root'@'${MYSQL_ROOT_HOST}' WITH GRANT OPTION;" || true
    fi
    
    # 停止临时服务
    if ! kill -s TERM "$pid" || ! wait "$pid"; then
        echo >&2 'MySQL 初始化进程失败'
        exit 1
    fi
    
    echo "MySQL 已成功初始化"
fi

# 在后台启动 MySQL
echo "启动 MySQL..."
"$@" &

# 获取 MySQL 进程 ID
MYSQL_PID=$!

# 等待 MySQL 启动并开始生成日志
sleep 2

# 在前台运行 tail 查看日志
echo "开始输出 MySQL 日志..."
tail -f /var/log/mysql/error.log &

# 捕获退出信号
trap "echo '收到停止信号,停止 MySQL...'; kill $MYSQL_PID" TERM INT

# 等待 MySQL 进程
wait $MYSQL_PID
EOF

chmod +x docker-entrypoint.sh

# 6. 构建镜像(添加错误处理)
echo "开始构建镜像..."
if ! docker buildx build \
  --platform linux/arm64 \
  -t ${imageTag} \
  --load --progress=plain \
  --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
  .; then
    echo "错误:镜像构建失败"
    exit 1
fi

echo "镜像构建成功: ${imageTag}"

二、基于 glibc2 包构建 MySQL 8.0.44 Arm64 镜像

创建一个shell

#!/bin/bash
set -e  # 添加错误处理

# 1. 下载 MySQL(添加错误检查)
if [ ! -f "mysql-8.0.44-linux-glibc2.28-aarch64.tar.xz" ]; then
    echo "下载 MySQL 安装包..."
    if ! wget -O "mysql-8.0.44-linux-glibc2.28-aarch64.tar.xz" "https://cdn.mysql.com/archives/mysql-8.0/mysql-8.0.44-linux-glibc2.28-aarch64.tar.xz"; then
        echo "错误:MySQL 安装包下载失败"
        exit 1
    fi
fi

imageTag=mysql-openeuler:8.0.44

# 2. 设置环境变量
export DOCKER_BUILDKIT=1
export DOCKER_CLI_EXPERIMENTAL=enabled

# 3. 清理和设置构建器
echo "设置 Docker Buildx 构建器..."
rm -rf /tmp/buildkitd.toml
cat > /tmp/buildkitd.toml << 'EOF'
debug = true
root = "/var/lib/buildkit"

[registry."docker.io"]
  mirrors = [
  		"https://e2zfh98i.mirror.aliyuncs.com",
  		"https://mirror.baidubce.com",
  		"https://docker.mirrors.ustc.edu.cn",
  		"https://docker-cf.registry.cyou",
  		"https://dockercf.jsdelivr.fyi",
  		"https://docker.jsdelivr.fyi",
  		"https://dockertest.jsdelivr.fyi",
  		"https://dockerproxy.com",
  		"https://docker.m.daocloud.io",
  		"https://docker.nju.edu.cn",
  		"https://docker.mirrors.sjtug.sjtu.edu.cn",
  		"https://mirror.iscas.ac.cn",
  		"https://docker.rainbond.cc",
  		"https://do.nark.eu.org",
  		"https://dc.j8.work",
  		"https://dockerproxy.com",
  		"https://gst6rzl9.mirror.aliyuncs.com",
  		"https://registry.docker-cn.com",
  		"http://hub-mirror.c.163.com",
  		"http://mirrors.ustc.edu.cn/",
  		"https://mirrors.tuna.tsinghua.edu.cn/",
  		"http://mirrors.sohu.com/"
	]
EOF

# 清理现有构建器
docker buildx rm mybuilder 2>/dev/null || true

# 创建构建器
if ! docker buildx create \
  --name mybuilder \
  --driver docker-container \
  --driver-opt "image=moby/buildkit:master" \
  --platform linux/arm64 \
  --config /tmp/buildkitd.toml \
  --use; then
    echo "错误:创建构建器失败"
    exit 1
fi

# 启动构建器
docker buildx inspect --bootstrap

# 4. 创建正确的 Dockerfile
echo "创建 Dockerfile..."
cat > Dockerfile << 'EOF'
# 使用 ARM64 基础镜像
FROM openeuler/openeuler:24.03-lts-sp3

# 设置参数
ARG TARGETARCH
ARG TARGETPLATFORM
RUN echo "目标架构: $TARGETARCH, 目标平台: $TARGETPLATFORM"

# 设置环境变量
ENV MYSQL_VERSION=8.0.44
ENV MYSQL_HOME=/usr/local/mysql
ENV MYSQL_DATA_DIR=/var/lib/mysql
ENV MYSQL_LOG_DIR=/var/log/mysql
ENV PATH=$MYSQL_HOME/bin:$PATH
ENV TZ=Asia/Shanghai

# 安装依赖
RUN dnf install -y \
        perl \
        perl-Data-Dumper \
        libaio \
        numactl \
        ncurses-compat-libs \
        shadow-utils \
        procps-ng \
        tar \
        xz \
        gzip \
        wget \
        hostname \
    && dnf clean all

# 确保 bash 是默认 shell
RUN ln -sf /bin/bash /bin/sh
    
# 设置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 复制 MySQL 安装包
COPY mysql-8.0.44-linux-glibc2.28-aarch64.tar.xz /tmp/

# 安装 MySQL
RUN tar -xf /tmp/mysql-*.tar.xz -C /usr/local/ && \
    mv /usr/local/mysql-${MYSQL_VERSION}-linux-glibc2.28-aarch64 ${MYSQL_HOME} && \
    rm -f /tmp/mysql-*.tar.xz && \
    ln -sf ${MYSQL_HOME}/bin/* /usr/local/bin/

# 创建用户和目录
RUN groupadd -r mysql && \
    useradd -r -g mysql -s /bin/false mysql && \
    mkdir -p ${MYSQL_DATA_DIR} ${MYSQL_LOG_DIR} /var/run/mysql && \
    chown -R mysql:mysql ${MYSQL_DATA_DIR} ${MYSQL_LOG_DIR} /var/run/mysql

# 创建配置文件
RUN echo "[mysqld]" > /etc/my.cnf \
    && echo "datadir=${MYSQL_DATA_DIR}" >> /etc/my.cnf \
    && echo "socket=/var/lib/mysql/mysql.sock" >> /etc/my.cnf \
    && echo "log-error=${MYSQL_LOG_DIR}/error.log" >> /etc/my.cnf \
    && echo "pid-file=/var/run/mysql/mysql.pid" >> /etc/my.cnf \
    && echo "user=mysql" >> /etc/my.cnf \
    && echo "default_authentication_plugin=mysql_native_password" >> /etc/my.cnf \
    && echo "[client]" >> /etc/my.cnf \
    && echo "socket=/var/lib/mysql/mysql.sock" >> /etc/my.cnf

# 复制启动脚本
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

# 暴露端口
EXPOSE 3306 33060

# 数据卷
VOLUME ["${MYSQL_DATA_DIR}", "${MYSQL_LOG_DIR}"]

# 设置工作目录
WORKDIR ${MYSQL_HOME}

# 正确的 ENTRYPOINT 和 CMD
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["mysqld"]
EOF

# 5. 创建修复后的启动脚本
echo "创建启动脚本..."
cat > docker-entrypoint.sh << 'EOF'
#!/bin/bash
set -e

# 如果数据目录为空,则初始化数据库
if [ -z "$(ls -A ${MYSQL_DATA_DIR})" ]; then
    echo "初始化 MySQL 数据库..."
    
    # 初始化数据库
    mysqld --initialize-insecure \
        --user=mysql \
        --datadir=${MYSQL_DATA_DIR} \
        --basedir=${MYSQL_HOME}
    
    # 启动临时服务来设置 root 密码
    mysqld --user=mysql --datadir=${MYSQL_DATA_DIR} --skip-networking &
    pid="$!"
    
    # 等待 MySQL 启动
    for i in {30..0}; do
        if mysqladmin ping --silent; then
            break
        fi
        echo '等待 MySQL 启动...'
        sleep 1
    done
    
    if [ "$i" = 0 ]; then
        echo >&2 'MySQL 启动失败'
        exit 1
    fi
    
    # 设置 root 密码
    if [ -n "${MYSQL_ROOT_PASSWORD}" ]; then
        mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';"
    else
        mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '';"
    fi
    
    # 创建远程 root 用户
    if [ -n "${MYSQL_ROOT_HOST}" ]; then
        mysql -u root -p${MYSQL_ROOT_PASSWORD:-''} -e \
            "CREATE USER 'root'@'${MYSQL_ROOT_HOST}' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';"
        mysql -u root -p${MYSQL_ROOT_PASSWORD:-''} -e \
            "GRANT ALL PRIVILEGES ON *.* TO 'root'@'${MYSQL_ROOT_HOST}' WITH GRANT OPTION;"
    fi
    
    # 停止临时服务
    if ! kill -s TERM "$pid" || ! wait "$pid"; then
        echo >&2 'MySQL 初始化进程失败'
        exit 1
    fi
    
    echo "MySQL 已成功初始化,等待启动"
fi

# 设置权限
chown -R mysql:mysql ${MYSQL_DATA_DIR} ${MYSQL_LOG_DIR}

# 在后台启动 MySQL
echo "启动 MySQL..."
"$@" &

# 获取 MySQL 进程 ID
MYSQL_PID=$!

# 等待 MySQL 启动并开始生成日志
sleep 2

# 在前台运行 tail 查看日志
echo "开始输出 MySQL 日志..."
tail -f /var/log/mysql/error.log &

# 捕获退出信号
trap "echo '收到停止信号,停止 MySQL...'; kill $MYSQL_PID" TERM INT

# 等待 MySQL 进程
wait $MYSQL_PID
EOF

chmod +x docker-entrypoint.sh

# 6. 构建镜像(添加错误处理)
echo "开始构建镜像..."
if ! docker buildx build \
  --platform linux/arm64 \
  -t ${imageTag} \
  --load \
  --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
  .; then
    echo "错误:镜像构建失败"
    exit 1
fi

echo "镜像构建成功: ${imageTag}"

三、运行容器

# 基本运行
docker run -d \
  --name mysql-server \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql-openeuler:8.0.44

# 带数据持久化
docker run -d \
  --name mysql-server \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v /path/to/mysql/data:/var/lib/mysql \
  -v /path/to/mysql/logs:/var/log/mysql \
  mysql-openeuler:8.0.44

# 自定义配置
docker run -d \
  --name mysql-server \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_ROOT_HOST=% \
  -v /my/custom/my.cnf:/etc/my.cnf \
  mysql-openeuler:8.0.44

四、环境变量配置

  • MYSQL_ROOT_PASSWORD:root用户密码(必须)
  • MYSQL_ROOT_HOST:root远程访问主机,默认为localhost
  • TZ:时区设置,默认为 Asia/Shanghai
  • LANG:语言设置,需要设置为 zh_CN.UTF-8 容器才支持中文
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐