Skip to content

macOS 开发环境配置指南

本文档记录了在 macOS 上搭建开发环境的完整流程,适用于后端/前端开发者。

Homebrew

macOS 上最流行的包管理器,几乎所有开发工具都可以通过它安装。

官网brew.sh

bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

国内加速

如果下载速度较慢,可以使用清华镜像源:

bash
export HOMEBREW_INSTALL_FROM_API=1
export HOMEBREW_API_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api"
export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles"
export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"
export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git"

版本控制

Git

bash
brew install git

基础配置

bash
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
git config --global init.defaultBranch main

SSH 密钥配置

bash
ssh-keygen -t ed25519 -C "your.email@example.com"

注:ed25519 是目前更安全且性能更好的算法。如果你的系统不支持,使用 RSA 方案。

生成过程中的提示:

  • Enter file in which to save the key: 直接按 回车,使用默认路径(通常是 ~/.ssh/id_ed25519)。
  • Enter passphrase: 设置密钥锁。如果不想每次提交代码都输密码,直接按 回车(留空)。
  • Enter same passphrase again: 再次按 回车

密钥生成后,你会得到两个文件:

  • id_ed25519私钥):保存在本地,绝对不能泄露
  • id_ed25519.pub公钥):这是你需要复制并填到 GitHub/GitLab 上的内容。

最后,将公钥添加到 Git 平台,以 GitHub 为例:

  1. 登录 GitHub,点击右上角头像 -> Settings
  2. 在左侧菜单找到 SSH and GPG keys
  3. 点击 New SSH key
  4. Title 随便起个名字(如 "My Laptop"),在 Key 中粘贴刚才复制的内容。
  5. 点击 Add SSH key 完成。

容器化

OrbStack

macOS 上最快的 Docker Desktop 替代品,资源占用低、启动速度快。

bash
brew install --cask orbstack

对比 Docker Desktop

  • 启动速度:秒级 vs 分钟级
  • 内存占用:更低
  • 原生支持 Linux 虚拟机

Java 开发环境

JDK 版本管理 - SDKMAN

推荐使用 SDKMAN 管理多个 JDK 版本。

bash
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

常用命令

bash
# 查看可用版本
sdk list java

# 安装指定版本
sdk install java 21-zulu
sdk install java 17-zulu
sdk install java 8.0.422-zulu

# 切换版本
sdk use java 21-zulu

# 设置默认版本
sdk default java 21-zulu

Maven

bash
brew install maven

配置阿里云镜像(编辑 ~/.m2/settings.xml):

xml
<mirrors>
  <mirror>
    <id>aliyunmaven</id>
    <mirrorOf>*</mirrorOf>
    <name>阿里云公共仓库</name>
    <url>https://maven.aliyun.com/repository/public</url>
  </mirror>
</mirrors>

MySQL

方式一:Homebrew 安装

bash
brew install mysql

如果你需要安装特定版本(例如 8.0),可以使用 brew install mysql@8.0

安装完成后,你可以选择如何运行 MySQL:

  • 后台服务(随系统启动) 这是最常用的方式,MySQL 会在后台持续运行。

    bash
    brew services start mysql
  • 手动在前台启动

MySQL 安装后默认是没有 root 密码的。为了安全,必须运行以下安全安装脚本来设置密码并移除不安全设置:

bash
mysql_secure_installation

在脚本运行过程中,你会遇到以下提示:

  1. VALIDATE PASSWORD COMPONENT? (是否启用密码强度校验):根据个人习惯选 yn。本地的一般选n就可以。
  2. New password: 输入你想要设置的 root 密码。
  3. Remove anonymous users? (移除匿名用户):选 y
  4. Disallow root login remotely? (禁止 root 远程登录):选 y表示仅限本机连接。
  5. Remove test database? (移除测试数据库):选 y
  6. Reload privilege tables now? (立即刷新权限):选 y

配置完成后,尝试登录 MySQL:

bash
mysql -u root -p
操作命令/路径
停止 MySQLbrew services stop mysql
查看状态brew services list
配置文件 (Apple Silicon)/opt/homebrew/etc/my.cnf
配置文件 (Intel)/usr/local/etc/my.cnf
数据目录/opt/homebrew/var/mysql/

方式二:docker安装

假设docker数据统一在/data/docker下管理

bash
cd /data/docker
rm -rf ./mysql/*
mkdir -p "$PWD/mysql/"{logdir,datadir,confdir}
docker run -p 3306:3306 --restart=always --name mysql \
-v "$PWD/mysql/logdir":/var/log/mysql  \
-v "$PWD/mysql/datadir":/var/lib/mysql  \
-v "$PWD/mysql/confdir":/etc/mysql/conf.d  \
-e MYSQL_ROOT_PASSWORD=mysql \
-e TZ=Asia/Shanghai \
-d mysql:latest

Redis

方式一:Homebrew 安装

安装Redis

bash
brew install redis

启动、停止、重启的命令

bash
brew services start redis
brew services stop redis
brew services restart redis

如果你只是临时用一下,或者想直接在终端看到运行日志,可以使用这种方式。按下 Ctrl + C 即可停止。

bash
redis-server /opt/homebrew/etc/redis.conf

注意: 如果你是 Intel 芯片的 Mac,配置文件路径通常是 /usr/local/etc/redis.conf。如需修改密码,找到 # requirepass foobared 这一行,去掉行首的 #,将 foobared 修改为你想要的密码,例如:requirepass YourRedisPassword

方式二:Docker 安装

准备了一个简单的脚本,挂载的目录是/data/docker,设置了密码为redis,可修改。需要:

  • 保存脚本为 setup_redis.sh
  • 添加执行权限:chmod +x setup_redis.sh
  • 运行脚本:./setup_redis.sh
bash
#!/bin/bash

# 1. 切换到/data/docker目录
cd /data/docker

# 2. 创建redis目录并进入
mkdir -p redis
cd redis

# 3. 创建redis配置文件
cat > redis.conf << EOF
bind 0.0.0.0
port 6379
protected-mode no
requirepass redis
appendonly yes
EOF

# 4. 运行redis容器
docker run -d \
  --name redis \
  -p 6379:6379 \
  -v $(pwd)/redis.conf:/usr/local/etc/redis/redis.conf \
  redis:7.2.0 \
  redis-server /usr/local/etc/redis/redis.conf

# 检查容器是否启动成功
if [ $? -eq 0 ]; then
  echo "Redis容器启动成功!"
  echo "容器信息:"
  docker ps | grep redis
else
  echo "Redis容器启动失败,请检查错误信息"
fi

xxl-job

需提前有MySQL环境,并且执行好sql,官方提供了sql:https://github.com/xuxueli/xxl-job/blob/master/doc/db/tables_xxl_job.sql 。需要先在MySQL数据库执行好sql,然后使用docker创建xxl-job,其中需要配置好你的MySQL连接地址,比如选择宿主机的3306就可以写成jdbc:mysql://host.docker.internal:3306

bash
docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://host.docker.internal:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai \
    --spring.datasource.username=root \
    --spring.datasource.password=mysql" \
    -p 8080:8080 \
    --name xxl-job-admin \
    -d xuxueli/xxl-job-admin:3.3.2

启动后进入 http://localhost:8080/xxl-job-admin/ ,默认的用户名和密码是 admin / 123456。一个 Spring Boot 配置示例:

yml
xxl:
  job:
    admin:
      addresses: http://127.0.0.1:8080/xxl-job-admin
    executor:
      appname: onecoupon-merchant-admin
      port: 9999
      logpath: ./logs/xxl-job/jobhandler
      logretentiondays: 30
    accessToken: default_token

nacos

bash
docker run \
-d -p 8848:8848 \
-p 9848:9848 \
--name nacos \
-e MODE=standalone \
-e TIME_ZONE='Asia/Shanghai' \
nacos/nacos-server:v2.4.3

kafka

进入网站 kafka。以kafka4.1.0为例。

pZDctTP.png

下载后解压:

KRaft 模式(Kafka Raft Metadata mode) 启动一个单节点(standalone)Kafka 服务器。

注:KRaft 是 Kafka 从 2.8 版本开始引入、并在 3.x+ 版本中逐步取代 ZooKeeper 的新元数据管理机制。

  • 生成一个唯一的 Kafka 集群 ID,并将其赋值给环境变量 KAFKA_CLUSTER_IDbin/kafka-storage.sh random-uuid 是 Kafka 提供的一个工具,用于生成符合 Kafka 要求的随机 UUID(通用唯一标识符)。

  • 对 Kafka 的本地存储目录进行格式化,为启动做准备。

    • -t $KAFKA_CLUSTER_ID:指定上一步生成的集群 ID。

    • -c config/server.properties:指定 Kafka 服务器的配置文件路径。

    • --standalone:表示这是单节点模式(即该节点同时承担 controller 和 broker 角色),适用于开发或测试环境。

      此命令只需在首次启动清理数据后重新初始化时运行一次。它会在 server.properties 中配置的 log.dirs(或默认路径)下创建必要的元数据结构。

  • 使用指定的配置文件启动 Kafka 服务器。

bash
KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c config/server.properties --standalone
bin/kafka-server-start.sh config/server.properties

RocketMQ

创建docker-compose.yml文件如下

yaml
version: '3'
services:
  rmqnamesrv:
    image: apache/rocketmq:5.2.0
    container_name: rmqnamesrv
    ports:
      - "9876:9876"
    command: ["sh", "mqnamesrv"]
    healthcheck:
      test: ["CMD-SHELL", "cat < /dev/null > /dev/tcp/127.0.0.1/9876"]
      interval: 5s
      timeout: 3s
      retries: 5

  rmqbroker:
    image: apache/rocketmq:5.2.0
    container_name: rmqbroker
    ports:
      - "10911:10911"
      - "10909:10909"
      - "8081:8081"
    volumes:
      - ./broker.conf:/home/rocketmq/rocketmq-5.2.0/conf/broker.conf
    command: ["sh", "mqbroker", "-c", "/home/rocketmq/rocketmq-5.2.0/conf/broker.conf"]
    depends_on:
      - rmqnamesrv
    healthcheck:
      test: ["CMD-SHELL", "cat < /dev/null > /dev/tcp/127.0.0.1/10911"]
      interval: 5s
      timeout: 3s
      retries: 5

  rmqdashboard:
    image: apacherocketmq/rocketmq-dashboard:latest
    container_name: rmqdashboard
    ports:
      - "8180:8082"
    environment:
      - JAVA_OPTS=-Drocketmq.namesrv.addr=rmqnamesrv:9876
    depends_on:
      rmqbroker:
        condition: service_healthy
    restart: on-failure

其中指定的配置文件的内容是:

conf
# broker.conf
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH

# 使用宿主机局域网 IP,让 Java 应用和 Dashboard 都能连接
brokerIP1 = 192.168.0.100

# 指向 NameServer 地址
namesrvAddr = rmqnamesrv:9876

# 开启自动创建 Topic
autoCreateTopicEnable = true

在 RocketMQ 的配置中,brokerIP1 的作用至关重要:它决定了 Broker 向 NameServer 注册的通讯地址。当 Producer、Consumer 或 Dashboard 访问 NameServer 时,获取到的正是这个地址。

  1. 对于宿主机开发: Java 程序通过 9876 端口与 NameServer 通信后,会拿到 192.168.0.100。由于该域名在宿主机上能解析,程序可以顺利通过映射端口连接到容器内的 Broker。
  2. 对于容器化组件(如 Dashboard): 如果将 brokerIP1 设为 127.0.0.1,Dashboard(运行在独立容器中)从 NameServer 获取地址后,会尝试连接其自身容器内部的 10911 端口,从而导致连接失败。

因此,将 brokerIP1 设置为 192.168.0.100,如果你在服务器上安装,可以使用公网的IP地址。

关于启动顺序与健康检查:docker-compose.yml 中,我们引入了 healthcheck(健康检查)机制。这是为了确保 Dashboard 在 Broker 真正就绪后才启动。若不进行控制,三个容器同时启动时,Dashboard 常因 Broker 尚未完成初始化而连接失败,导致必须手动重启 Dashboard。

关于检查命令的选择: 方案中没有使用常见的 nc (netcat) 命令,是因为 RocketMQ 5.x 官方镜像为了追求极致精简,内部并未预装 nc。如果强行使用 nc -z,Docker 会因为在容器内找不到该命令而判定健康检查永久失败。由于 Dashboard 配置了必须等待 Broker “健康”才启动,这会导致 Dashboard 始终卡在 Waiting 状态。

关于平台兼容性警告: 在 Apple Silicon (M1/M2/M3) 等 ARM 架构机器上启动时,可能会提示平台不匹配(linux/amd64 不匹配 linux/arm64)。这是因为官方镜像目前主要支持 AMD64 架构。虽然这会通过二进制翻译运行,导致性能上有轻微损耗,但在开发调试阶段完全不影响功能使用。

有人问,为什么不把brokerIP1设置为host.docker.internal呢?这似乎可以同时兼容Java客户端和DashBoard

当你设置 brokerIP1 = host.docker.internal 时:

  1. Broker 向 NameServer 注册地址为 host.docker.internal:10911

  2. NameServer 返回这个地址给客户端

  3. 客户端解析 host.docker.internal 得到 198.18.1.213

  4. 客户端尝试连接 198.18.1.213:10911

关键问题:198.18.1.213 是 OrbStack 的虚拟网络 IP,它和端口映射走的是不同的网络栈:

  • 端口映射 0.0.0.0:10911 -> 容器:10911 主要服务于 127.0.0.1 和物理网卡 IP
  • 198.18.1.213 是 OrbStack 的"宿主机虚拟表示",但它可能没有正确映射到端口转发规则

日志很清楚地告诉我们:

send request to <host.docker.internal/198.18.1.213:10911> failed

Send [2] times, still failed, cost [13139]ms

即使超时时间足够长(13秒),请求还是直接失败(不是超时)。这说明 OrbStack 的 198.18.1.213 虚拟 IP 在处理 RocketMQ 的 Netty 通信时有根本性问题,不仅仅是慢的问题。

简单说:OrbStack 的 host.docker.internal 端口转发实现有问题。

理论上 Docker Desktop 的 host.docker.internal 应该可以正常工作。但是我没有试过。

总之,在 OrbStack 环境下,host.docker.internal 无法用于 RocketMQ 通信。

RabbitMQ

bash
docker run -d \
  --hostname my-rabbit \
  --name rabbitmq \
  -p 5672:5672 \
  -p 15672:15672 \
  -e RABBITMQ_DEFAULT_USER=admin \
  -e RABBITMQ_DEFAULT_PASS=admin123 \
  rabbitmq:3-management

3-management 标签表示包含 Web 管理插件(默认端口 15672),适合开发和调试。

Web 管理界面:浏览器访问http://localhost:15672,使用上面设置的用户名/密码(如 admin / admin123)登录。若希望重启容器后保留队列和消息,可挂载数据卷:

bash
docker run -d \
  --hostname my-rabbit \
  --name rabbitmq \
  -p 5672:5672 \
  -p 15672:15672 \
  -e RABBITMQ_DEFAULT_USER=admin \
  -e RABBITMQ_DEFAULT_PASS=admin123 \
  -v rabbitmq_data:/var/lib/rabbitmq \
  rabbitmq:3-management

这里使用了命名卷 rabbitmq_data,Docker 会自动创建并管理。

Node.js 开发环境

fnm (Fast Node Manager)

比 nvm 更快的 Node.js 版本管理器。

bash
brew install fnm

~/.zshrc 中添加:

bash
eval "$(fnm env --use-on-cd)"

常用命令

bash
# 安装 Node.js
fnm install 20
fnm install --lts

# 切换版本
fnm use 20
fnm default 20

# 列出本地已安装的版本
fnm list

# 列出远程所有可安装的版本(包括 nightly、rc 等)
fnm list-remote

# 只列出 LTS 版本
fnm list-remote --lts

# 列出当前正在使用的版本(带 * 标记)
fnm list --using

pnpm

高效的包管理器,比 npm/yarn 更快、更节省磁盘空间。

bash
brew install pnpm

IDE & 编辑器

IntelliJ IDEA

Java/Kotlin 开发首选。

下载地址:IntelliJ IDEA下载

目前IntelliJ IDEA可以直接使用无需激活,如需激活,可以参考JetBrains 离线懒人工具 2.0 更新咯,内含激活工具箱,下载地址为蓝奏云

根据操作系统选择对应的下载。如果是macos系统,安装软件时可能出现“该文件已损坏”的提示,只需要在终端输入命令

sh
sudo xattr -rd com.apple.quarantine /Applications/xxxx.app

Visual Studio Code

轻量级编辑器,前端开发神器。

bash
brew install --cask visual-studio-code

基于vscode二次开发的AI编辑器

数据库客户端

DataGrip

JetBrains 出品的数据库 IDE,支持多种数据库。下载地址:DataGrip

TablePlus

轻量级数据库客户端,界面简洁。

bash
brew install --cask tableplus

Tiny RDM

一个更现代化的Redis桌面管理客户端。下载地址:Tiny RDM

API 调试

Postman

bash
brew install --cask postman

apifox

API 设计、开发、测试一体化协作平台。Apifox = Postman + Swagger + Mock + JMeter。下载地址:apifox

效率工具

Raycast

替代 Spotlight 的效率启动器,支持丰富的扩展。

bash
brew install --cask raycast

Rectangle

窗口管理工具,快捷键分屏。

bash
brew install --cask rectangle

Snipaste

截图贴图工具。

bash
brew install --cask snipaste

实用系统配置

显示隐藏文件

bash
defaults write com.apple.finder AppleShowAllFiles -bool true
killall Finder

加快按键重复速度

bash
defaults write -g KeyRepeat -int 1
defaults write -g InitialKeyRepeat -int 10

禁用 .DS_Store 文件生成(网络驱动器)

bash
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true