CI/CD ·

Mac 上如何运行 Docker?M 系列芯片安装 Docker Desktop、部署 MySQL、Redis 和 Web 项目实战

Mac 上如何运行 Docker?M 系列芯片安装 Docker Desktop、部署 MySQL、Redis 和 Web 项目实战

这篇实操指南面向首次在 Apple Silicon Mac 上配置容器开发环境的开发者。我们按安装、架构验证、Compose 编排、连接测试与故障排查展开,并提供可运行的示例项目和部署检查清单。

Docker 官方安装文档列明 Docker Desktop 的最低内存要求为 4 GB。(Docker Desktop for Mac 安装与系统要求) Mac 上如何运行 Docker?在 M 系列芯片 Mac 上安装适配 Apple Silicon 的 Docker Desktop,确认容器镜像架构兼容,再用 Docker Compose 编排 MySQL、Redis 和 Web 项目。

适合:使用 M 系列芯片 Mac 搭建本地开发环境。按下面步骤可验证 Docker 是否可用、数据库和缓存是否能连接,以及 Web 项目是否能访问。 不适合:把本地示例直接当生产部署,或需要长期对外提供服务的团队;示例凭据、网络暴露和运维策略都需要另行设计。

适合首次配置 Docker 的 Apple Silicon Mac 开发者,也适合需要同时运行 MySQL、Redis 和 Web 项目的后端或全栈开发者。 如果团队正在评估远程 Mac 能否承接容器开发与构建任务,文末会说明适用边界。

Mac 上如何运行 Docker:安装前要确认什么?

Docker Desktop 并不是把 Linux 容器直接运行在 macOS 内核上。它会在 Mac 上运行轻量 Linux 虚拟机,再由虚拟机中的 Docker Engine 启动 Linux 容器;Docker 官方文档介绍了这层虚拟机与网络机制。(Docker Desktop 网络机制)

M 系列芯片采用 Apple Silicon 架构。创建 Linux 虚拟机或选择容器镜像时,架构必须对应;Apple 的虚拟化文档说明了在 Apple Silicon 上运行 Linux 虚拟机的要求。(Apple 虚拟化框架:在虚拟机中运行 Linux) Docker 拉取多架构镜像时,通常会按运行环境选择匹配的变体。(Docker 多平台镜像文档)

安装前先核对这几项:

  • macOS 是否属于 Docker Desktop 当前支持范围。支持范围可能随系统发布变化,安装时应查看 Docker 官方安装文档。
  • 可用内存是否满足最低要求,并留出空间给 macOS、编辑器和容器。官方列出的 Docker Desktop 最低内存要求是 4 GB,这不是多服务项目的资源建议值。
  • 数据库、缓存和应用镜像是否包含 arm64 变体。MySQL 官方镜像列出 arm64v8 支持,Redis 官方镜像也列出 arm64v8;自建或第三方镜像仍要单独检查。(MySQL 官方镜像说明、Redis 官方镜像说明)
  • 团队是否需要统一镜像版本、凭据管理和数据备份。Compose 能帮助复现服务定义,但不会自动完成这些治理工作。

安装完成后,我们要验证的不是“应用图标能打开”,而是 Docker 客户端和服务端均可用、MySQL 与 Redis 能响应、Web 项目能从 Mac 访问,并且重建容器后持久化数据仍在。

第一步:在 M 系列芯片 Mac 安装 Docker Desktop

从 Docker 官方安装页选择 Mac with Apple chip 对应的安装包。打开下载的磁盘映像,将 Docker 应用拖入“应用程序”文件夹,再从“应用程序”启动。首次启动时按提示确认服务条款和必要的系统权限;安装方式与系统要求以 Docker 官方安装文档为准。

安装程序或权限选项可能随版本变化,因此不要照搬旧截图里的固定按钮位置。遇到授权提示时,核对其来源和用途;不要为了让命令“先跑起来”而把 Docker 套接字或凭据开放给不可信程序。

Docker Desktop 状态显示运行后,打开终端检查客户端和服务端:

bash
docker version
docker compose version
docker info

docker version 应同时列出 Client 和 Server 信息。若只有客户端信息或提示无法连接引擎,先确认 Docker Desktop 已完全启动,再检查当前 Docker context:

bash
docker context ls
docker context show

不要一开始就手动改 DOCKER_HOST。优先核对 Docker Desktop 是否已启动、当前 context 是否正确,以及安装权限和套接字设置。

第二步:如何确认镜像架构与容器运行正常?

先用轻量的官方测试镜像验证容器能启动并退出:

bash
docker run --rm hello-world

看到欢迎信息后,检查本机 Docker 服务端架构:

bash
docker info --format '{{.OSType}}/{{.Architecture}}'

然后查看目标镜像可用的平台变体。以 MySQL 为例:

bash
docker buildx imagetools inspect mysql:8.4

输出中查找 linux/arm64。镜像已拉取后,也可以检查本地镜像元数据:

bash
docker image inspect mysql:8.4 \
  --format '{{.Os}}/{{.Architecture}}'

多架构镜像包含指向不同平台镜像的清单;Docker 文档说明,拉取时会据运行环境选择相应变体。若启动时出现架构不兼容警告,先核实镜像清单和镜像维护者的支持范围,不要习惯性加 --platform linux/amd64。强制运行不同架构可能触发模拟执行,不代表镜像本身适合该平台。

接下来用 Compose 创建一个可测试的最小 Web 应用。项目目录结构如下:

text
mac-docker-demo/
├── compose.yaml
├── .env
├── Dockerfile
├── requirements.txt
└── app.py

Dockerfile 和依赖文件:

dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
text
Flask
mysql-connector-python
redis

app.py 会执行一次 MySQL 查询,并递增 Redis 计数器:

python
import os

import mysql.connector
import redis
from flask import Flask

app = Flask(__name__)

@app.get("/")
def index():
    db = mysql.connector.connect(
        host=os.getenv("MYSQL_HOST", "db"),
        user=os.getenv("MYSQL_USER", "devuser"),
        password=os.environ["MYSQL_PASSWORD"],
        database=os.getenv("MYSQL_DATABASE", "demo"),
    )
    cursor = db.cursor()
    cursor.execute("SELECT 1")
    result = cursor.fetchone()[0]
    cursor.close()
    db.close()

    cache = redis.Redis(
        host=os.getenv("REDIS_HOST", "redis"),
        port=int(os.getenv("REDIS_PORT", "6379")),
        decode_responses=True,
    )
    count = cache.incr("page_visits")
    return f"MySQL={result}; Redis visits={count}\n"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

这里的 db 和 redis 是 Compose 服务名,不是 Mac 的 localhost。同一 Compose 网络中的服务可通过服务名互相访问;端口发布则负责让 Mac 主机访问容器。(Docker Compose 服务配置与网络)

第三步:用 Docker Compose 启动 MySQL、Redis 和 Web 项目

在项目目录中创建 .env。以下值仅用于本地演示,不能用于生产;实际项目应使用自己的秘密管理方式,并避免将含真实密码的文件提交到代码仓库。

dotenv
MYSQL_DATABASE=demo
MYSQL_USER=devuser
MYSQL_PASSWORD=local-only-change-me
MYSQL_ROOT_PASSWORD=local-root-only-change-me

创建 compose.yaml:

yaml
services:
  db:
    image: mysql:8.4
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE:?请设置 MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER:?请设置 MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:?请设置 MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?请设置 MYSQL_ROOT_PASSWORD}
    ports:
      - "127.0.0.1:3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "mysqladmin ping -h 127.0.0.1 -uroot -p\"$${MYSQL_ROOT_PASSWORD}\" --silent"
        ]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 20s

  redis:
    image: redis:7.4-alpine
    command: ["redis-server", "--appendonly", "yes"]
    ports:
      - "127.0.0.1:6380:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 10

  web:
    build: .
    environment:
      MYSQL_HOST: db
      MYSQL_DATABASE: ${MYSQL_DATABASE:?请设置 MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER:?请设置 MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:?请设置 MYSQL_PASSWORD}
      REDIS_HOST: redis
      REDIS_PORT: "6379"
    ports:
      - "127.0.0.1:8000:5000"
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy

volumes:
  mysql_data:
  redis_data:

这个配置使用官方 MySQL 镜像和 Redis 镜像。团队若需要更强的可复现性,应固定经过审核的镜像摘要。MySQL 初始化变量只在数据目录尚未初始化时生效;改了 .env 却发现旧密码仍有效,先检查已有数据卷,而不是反复修改环境变量。

Compose 中的 depends_on 配合健康检查,能让 Web 服务等待数据库与缓存达到健康状态;单纯声明启动顺序并不等于服务已经可连接。命名数据卷把 MySQL 数据目录和 Redis 数据文件保存在容器生命周期之外。(Docker Compose 启动顺序与健康检查)

在启动前校验配置,再构建并启动服务:

bash
docker compose config -q
docker compose up -d --build
docker compose ps

如果 config -q 报环境变量缺失,先核对 .env 的文件位置和变量名。启动后,docker compose ps 中的服务状态和健康状态比“命令已经返回”更能说明依赖是否就绪。

第四步:从 Mac 验证网页、MySQL、Redis 与数据卷

浏览器访问 http://localhost:8000,或在终端请求:

bash
curl http://localhost:8000

页面返回 MySQL 查询结果与 Redis 访问计数,表示 Web 容器分别完成了数据库查询和缓存写入。连续请求时,Redis 计数应递增。

从容器内直接检查数据库和缓存:

bash
docker compose exec db \
  mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"

如果当前终端没有加载 .env,也可以进入 MySQL 容器交互式输入用户名和密码;不要把真实密码写进公开脚本。

bash
docker compose exec redis redis-cli SET demo_key "saved"
docker compose exec redis redis-cli GET demo_key

检查日志和端口映射:

bash
docker compose logs --tail=100 db redis web
docker compose port web 5000

Mac 上的浏览器和数据库客户端通过已发布端口访问服务;同一 Compose 网络内的 Web 容器则使用 db:3306、redis:6379 这样的服务地址。把容器内连接地址写成 localhost,通常会让应用连接自己,而不是数据库。发布端口时绑定 127.0.0.1,可将本地开发服务限制在回环接口。

验证数据卷时,先写入 Redis 键或创建测试数据库记录,然后执行:

bash
docker compose down
docker compose up -d
docker compose exec redis redis-cli GET demo_key

命名卷仍存在时,重建服务容器后数据应可读取。执行 docker compose down -v 会删除 Compose 管理的命名卷;MySQL 和 Redis 数据也会随之清除。MySQL 官方文档说明,删除容器时是否删除关联数据卷取决于是否显式删除卷。(MySQL Docker 入门文档)

常见故障按证据定位,不先猜原因

容器启动时报架构不匹配:查看 docker buildx imagetools inspect 镜像名:标签 的平台清单,再看容器日志。确认官方镜像是否包含 linux/arm64;只有确有兼容性需要时,才考虑模拟运行,并记录其构建与运行影响。

端口绑定失败:如果日志出现端口已占用,检查本机是否已有服务监听相同端口;也可调整 Compose 左侧的主机端口,再用 docker compose port 服务名 容器端口 核对映射。不要把 Web、数据库或缓存端口无差别地暴露到局域网。

MySQL 反复重启或凭据不生效:先看 docker compose logs db 和 docker compose ps。确认环境变量没有拼错,并检查数据卷是否已有初始化数据;数据目录非空时,MySQL 不会重新执行初始化。

Web 报数据库连接错误:检查应用使用的是 Compose 服务名 db,而不是 localhost;再确认数据库健康状态和 Web 日志。若数据库服务刚启动,核对健康检查是否通过,而不是只看容器是否处于运行状态。

重建后数据消失:检查服务是否挂载了命名卷,以及是否误用了 down -v。容器可替换,数据卷需要单独管理;重要数据还需要独立备份,不能把本地持久化等同于备份方案。

部署完成前,用对比表和清单做最后核对

下面的评分是我们按本地开发便利性、环境可复现性和持续运行条件给出的定性判断,不代表性能实测。

方案评分更适合的情况主要代价
M 系列芯片 Mac + Docker Desktop高日常编码、本地调试、快速验证多服务连接Docker Linux 虚拟机与容器会占用本机资源;关机或休眠时服务不可用
远程 Mac + Docker Desktop条件适合需要远程访问、团队共享开发环境或持续执行构建任务需核对远程接入方式、实例规格、费用与数据管理;网络故障会影响操作
单独使用云数据库或缓存条件适合只想连接已有远端依赖,不要求本地复现全部服务开发环境依赖网络与远端权限,数据隔离和清理要另行处理
项目示例值验证方式
Web 主机访问地址127.0.0.1:8000浏览器打开本地页面,或用 curl 请求
MySQL 主机映射127.0.0.1:3307本机数据库客户端连接,或在容器内运行 MySQL 客户端
Redis 主机映射127.0.0.1:6380redis-cli SET 后再 GET
容器间数据库地址db:3306查看应用配置与 Web 容器日志
容器间缓存地址redis:6379查看应用配置并验证页面计数变化
现象首要证据优先处理
镜像无法启动镜像平台清单、容器日志核实 arm64 支持,再决定是否需要模拟
主机无法访问服务docker compose port 输出、端口占用情况调整主机端口,检查是否绑定回环地址
Web 连不上 MySQL数据库健康状态、应用连接主机名使用 Compose 服务名,确认环境变量
重建后数据不见卷列表、Compose 卷映射、是否用了 down -v保留命名卷,并为重要数据另做备份
  • [ ] Docker Desktop 已启动,docker version 能显示客户端与服务端信息。
  • [ ] 目标镜像的平台清单包含适用的 arm64 变体,或团队已明确接受模拟运行的取舍。
  • [ ] docker compose config -q 通过,示例凭据没有被当作生产密码。
  • [ ] Web 页面可访问,MySQL 查询和 Redis 读写均有实际返回。
  • [ ] 已确认主机端口只按开发需求开放,服务间连接使用 Compose 服务名。
  • [ ] 已验证命名卷的保留行为,并明确 docker compose down -v 会删除持久化数据。

如果本地 Mac 的休眠、网络可达性或资源占用让开发环境难以持续运行,远程 Mac 可以作为另一种工作方式;它同样需要核对实际实例规格、交付方式、访问权限和费用,不应仅凭“能远程连接”就假定适合容器构建。ZekVPS 的远程 Mac 使用帮助说明了连接与实例信息的核对入口;需要判断当前提供的远程 Mac 是否匹配 Docker 开发流程,可先查看关于 ZekVPS 的服务说明,再通过联系页面确认具体条件。

把容器构建与测试任务交给远程 Mac

ZekVPS 提供 Apple M4 裸金属 Mac mini,完整 macOS 环境支持容器开发与远程构建。

整机独享算力与管理员权限,适合运行持续集成、部署测试环境或并行处理多个项目。

若你正准备把 MCP 或 Agent 从 Demo 推到日常运转,先固定一台可快照的云 Mac 节点往往比换第五个框架更有效。 查看 ZekVPS 云端 Mac mini 套餐 — 把实验环境和生产桌面拆开,部署会踏实很多。

限时优惠