返回

解决M1芯片Docker运行MySQL报错: no matching manifest

mysql

解决 Apple Silicon (M1) Docker 上 MySQL "no matching manifest..." 错误

最近,在使用 Apple Silicon M1 预览版 Docker 时遇到一个常见问题。尝试通过 docker-compose 拉取 MySQL 镜像时, 可能会遇到以下错误:

ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries

错误信息明确地表明,你试图拉取的 MySQL 镜像,缺乏与你的系统架构(linux/arm64/v8)相匹配的清单条目。说白了, 就是镜像不兼容!

一、 问题原因:为什么不匹配?

原因其实很简单:Docker Hub 上很多官方或者社区提供的镜像, 在构建时主要针对 x86_64 (amd64) 架构。 即使有些镜像提供了 ARM64 版本的支持, 可能标签 (tag) 也没有完全跟上,导致 Docker 无法自动找到合适的版本。

再直白点:官方还没适配好!或者说, 还没完美适配 M1!

二、解决思路: 几个可行的方案

针对这个错误, 有几种解决方法。咱们可以挨个尝试一下。

1. 使用显式指定平台架构的镜像

这是最直接也最推荐的方式。 Docker Hub上有些镜像已经开始支持多平台架构。 你可以通过 --platform 标志手动指定要拉取的镜像平台。

原理: Docker manifest list 中包含不同平台架构的子镜像。 通过--platform 可以明确告诉 Docker 你需要哪个平台的镜像,避免了自动选择可能出现的错误。

操作步骤及代码示例:

  1. 修改你的 docker-compose.yml 文件, 在 image 字段后面增加 platform 选项:
version: '3'

services:
  # Database
  db:
    image: mysql:5.7
    platform: linux/amd64 # 这里指定平台
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: pass
      MYSQL_DATABASE: wp
      MYSQL_USER: wp
      MYSQL_PASSWORD: wp
    networks:
      - wpsite

请注意: mysql:5.7 有时即使你指定 linux/amd64, 它实际上仍然会使用 ARM64 镜像(如果可用),因为它可能具有一个支持多个体系结构的“清单列表”。如果发生这种情况,你需要找到特定于amd64的镜像。一些旧版本或者特殊的tag才可能有amd64.

  1. 使用支持 ARM64 架构的替代镜像。

例如, 如果官方 MySQL 镜像暂时无法使用, 你可以试试 MariaDB。 MariaDB 是 MySQL 的一个分支, 很多情况下可以作为替代品,而且它对 ARM64 的支持通常更好。

version: '3'

services:
  # Database
  db:
    image: mariadb:10.5  # 使用 MariaDB 镜像
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: pass
      MYSQL_DATABASE: wp
      MYSQL_USER: wp
      MYSQL_PASSWORD: wp
    networks:
      - wpsite
  1. 如果是较新版本的mysql,你可以使用如下的platform
version: '3'

services:
  # Database
  db:
    image: mysql:8.0 #较新版本建议使用8.0, 实测可用
    platform: linux/arm64/v8
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: pass
      MYSQL_DATABASE: wp
      MYSQL_USER: wp
      MYSQL_PASSWORD: wp
    networks:
      - wpsite

注意: 某些MySQL新版本,可能8.0之后的,开始对arm64有了较好支持. 可以试试看.

2. 使用特定版本的、已知支持 ARM64 的 MySQL 镜像

很多时候,问题出在 latest 标签上。 可以通过指定特定的、经过验证的、支持 ARM64 的镜像版本来解决。

原理: latest 标签指向的镜像版本可能随时变化,而特定版本的镜像更稳定, 更有可能找到兼容 M1 的。

操作步骤:

  1. 在 Docker Hub 上找到 MySQL 镜像页面, 浏览 "Tags" 选项卡, 查找明确支持 arm64 架构的版本。例如:mysql/mysql-server:8.0.23-1-debian.10-amd64
  2. 更新 docker-compose.yml 文件,使用找到的特定版本标签。
    version: '3'
    
    services:
      # Database
      db:
        image: mysql/mysql-server:8.0.23-1-debian.10-amd64 # 具体版本号
        volumes:
          - db_data:/var/lib/mysql
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: pass
          MYSQL_DATABASE: wp
          MYSQL_USER: wp
          MYSQL_PASSWORD: wp
        networks:
          - wpsite
    

特别提示: 有些时候, 虽然 Tag 没写支持 arm64, 但是通过 docker manifest inspect 镜像名:tag 可以看到实际上它是支持的!可以大胆尝试。

3. 自己动手:构建支持 ARM64 的 MySQL 镜像

如果实在找不到合适的镜像, 或者你想有更大的控制权, 还可以选择自己构建镜像。

原理: 从 Dockerfile 开始, 定义一个基础镜像和所需的 MySQL 安装步骤, 然后在你的 M1 Mac 上构建它。这样可以保证构建出的镜像完全兼容你的硬件环境。

操作步骤:

  1. 创建一个名为 Dockerfile 的文件:
# 使用官方的 Ubuntu 基础镜像,可以换成其他的例如 alpine 等精简镜像
FROM ubuntu:20.04

# 安装必要的软件包
RUN apt-get update && apt-get install -y --no-install-recommends \
    mysql-server

# 设置 MySQL 配置文件(如果需要)
# COPY my.cnf /etc/mysql/my.cnf

# 暴露 MySQL 端口
EXPOSE 3306

# 启动 MySQL 服务
CMD ["mysqld"]
  1. Dockerfile 所在目录下,执行构建命令:
docker build -t my-mysql:arm64 .

my-mysql:arm64是自己起的名字,随意。

  1. 修改你的 docker-compose.yml 文件,使用新构建的镜像:
version: '3'

services:
  # Database
  db:
    image: my-mysql:arm64 # 使用你自定义的镜像
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: pass
      MYSQL_DATABASE: wp
      MYSQL_USER: wp
      MYSQL_PASSWORD: wp
    networks:
      - wpsite

4. Docker Buildx:终极武器(进阶技巧)

docker buildx 是 Docker 官方推出的一个构建工具, 能够方便地构建多平台镜像。 如果你经常需要在不同架构的机器上运行 Docker 镜像, 这是个非常有用的工具。

原理: buildx 使用 QEMU 等模拟器技术, 可以在一台机器上模拟其他平台的运行环境, 从而构建出支持多种架构的镜像。

操作步骤:

  1. 首先,需要启用 buildx:
docker buildx create --use --name mybuilder
  1. 然后,创建一个 Dockerfile (与上一步骤类似), 或者直接使用现有的 Dockerfile.

  2. 使用 buildx 构建镜像, 同时指定多个平台:

docker buildx build --platform linux/amd64,linux/arm64 -t yourusername/your-mysql:latest . --push
  • --platform 指定要构建的平台。
  • -t 给镜像打上标签。
  • --push 将构建好的镜像推送到 Docker Hub(你需要先登录 Docker Hub)。
  1. 更新 docker-compose.yml,直接引用, docker会自行选择匹配的镜像.
version: '3'

services:
  # Database
  db:
    image: yourusername/your-mysql:latest
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: pass
      MYSQL_DATABASE: wp
      MYSQL_USER: wp
      MYSQL_PASSWORD: wp
    networks:
      - wpsite

这样构建的镜像支持多平台。

三、额外安全建议

不管采用哪种方案, 在配置 MySQL 容器时,都应考虑安全性:

  • 修改默认密码: 不要在生产环境中使用默认的 root 密码。 第一次启动 MySQL 容器后,尽快修改。
  • 限制网络访问: 尽量只允许必要的网络访问你的 MySQL 容器.
  • 数据卷持久化: 务必将 MySQL 数据目录挂载到宿主机上, 以防止容器被删除时数据丢失。
  • 定期备份: 养成定期备份数据库的好习惯!

上面提到的这些解决方案,通常能有效解决在 Apple Silicon M1 Docker 上运行 MySQL 遇到的兼容性问题。具体选择哪种方法, 要根据你的实际情况来定. 找不到合适的官方镜像?试试 platform 参数! 想拥有最大的灵活度?自己构建! 希望兼容多个平台?试试 buildx ! 总有一种办法能搞定它!