在 macOS 上用 Docker 为 Java 后端 & 常见开发需求搭建完整服务(详尽教程)

说明:本文假设你在 macOS(Intel 或 Apple Silicon)上使用 Docker Desktop。如果你已经安装 Docker,请从"创建 compose 文件"那一节直接开始。


目录(快速导航)

  1. 安装 Docker Desktop(macOS)
  2. Docker Desktop 基本配置建议(资源、端口、文件共享)
  3. 推荐服务清单(为 Java 后端与通用开发)
  4. 为所有服务准备的 docker-compose.yml(完整示例)
  5. 启动 / 停止 / 管理容器的常用命令
  6. 每个服务的详细说明、配置与注意事项(MySQL / PostgreSQL / Redis / Elasticsearch + Kibana / RabbitMQ / Nginx / Jenkins / Gitea / MinIO / Prometheus + Grafana / Portainer / Node)
  7. Spring Boot(Java 后端)连接示例配置
  8. 数据卷、备份与恢复(MySQL、Postgres、Elasticsearch 等)
  9. 常见问题与排查方法
  10. 安全、性能与生产提醒

1. 安装 Docker Desktop(macOS)------一步步来

  1. 访问 Docker 官网下载适合你 Mac 的 Docker Desktop 安装包(Apple Silicon / Intel)。

    • 在浏览器输入 docker desktop mac 即可找到下载页面(注意选对 CPU 架构)。
  2. 下载完成后,双击 .dmg,把 Docker.app 拖到 Applications 文件夹。

  3. 打开 Applications 中的 Docker.app,第一次启动会要求输入系统密码(以允许安装虚拟化工具)。

  4. 启动后菜单栏会出现小鲸鱼图标,等待 "Docker is running"。

  5. (可选)登录 Docker Hub 账号以便拉取私有镜像或速率更高。

提示:Apple Silicon(M1/M2)与 Intel 镜像的差异:优先使用 :alpine 或多平台镜像(多数官方镜像支持 multi-arch)。如果镜像只支持 amd64,Docker Desktop 会自动使用仿真(QEMU),但会慢一些。


2. Docker Desktop 基本配置(很重要)

打开 Docker Desktop → Preferences(偏好):

  • Resources(资源):给 Docker 分配足够资源(尤其是运行 Elasticsearch、Jenkins、Postgres 时)

    • CPU: 4 cores 或更多(视主机而定)
    • Memory: 8GB 起(如果跑 ES + Kibana 建议 12GB)
    • Swap: 1--2GB
  • File sharing / Volumes :确保你的项目目录(比如 ~/projects~/workspace)已被允许共享给 Docker。

  • Network:默认即可,一般无需修改。


3. 推荐服务清单(针对 Java 后端 + 常见需求)

  • 必备(Java 后端常用):MySQL / PostgreSQL、Redis、Nginx(反向代理)、RabbitMQ、Elasticsearch + Kibana、MinIO(S3 存储模拟)
  • CI / 管理:Jenkins、Gitea(轻量 Git 服务)、Portainer(Docker 管理 UI)
  • 监控 / 日志:Prometheus + Grafana、Loki(可选)
  • 辅助:Node 镜像(前端构建)、MailHog(邮件捕获,开发环境)

4. 一份完整的 docker-compose.yml(示例)

下面是一个功能齐全但尽量通用docker-compose.yml,包含 MySQL、Postgres、Redis、Elasticsearch + Kibana、RabbitMQ、MinIO、Nginx、Jenkins、Gitea、Prometheus、Grafana、Portainer。把它放在一个目录下(例如 ~/docker-dev),文件名 docker-compose.yml

yaml 复制代码
version: '3.8'

services:
  # MySQL
  mysql:
    image: mysql:8.0
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: demo
      MYSQL_USER: demo
      MYSQL_PASSWORD: demopass
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d  # 可放初始化 SQL
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  # PostgreSQL
  postgres:
    image: postgres:15
    container_name: postgres
    environment:
      POSTGRES_USER: demo
      POSTGRES_PASSWORD: demopass
      POSTGRES_DB: demo
    volumes:
      - pg_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  # Redis
  redis:
    image: redis:7-alpine
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

  # Elasticsearch (适合开发,生产请更谨慎)
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.14.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
      - xpack.security.enabled=false
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es_data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    healthcheck:
      test: ["CMD-SHELL", "curl -sS http://localhost:9200/_cluster/health | grep -q '\"status\"'"]
      interval: 20s
      timeout: 10s
      retries: 10

  # Kibana
  kibana:
    image: docker.elastic.co/kibana/kibana:8.14.0
    container_name: kibana
    environment:
      ELASTICSEARCH_HOSTS: 'http://elasticsearch:9200'
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch

  # RabbitMQ
  rabbitmq:
    image: rabbitmq:3.10-management
    container_name: rabbitmq
    ports:
      - "5672:5672"
      - "15672:15672"
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq

  # MinIO (S3 仿真)
  minio:
    image: minio/minio
    container_name: minio
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123
    command: server /data
    ports:
      - "9000:9000"
      - "9001:9001" # 控制台(新版)
    volumes:
      - minio_data:/data

  # Jenkins
  jenkins:
    image: jenkins/jenkins:lts-jdk11
    container_name: jenkins
    user: root
    environment:
      JAVA_OPTS: "-Djenkins.install.runSetupWizard=false"
    volumes:
      - jenkins_home:/var/jenkins_home
    ports:
      - "8080:8080"
      - "50000:50000"

  # Gitea (轻量的 Git 服务)
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
      USER_UID: 1000
      USER_GID: 1000
    volumes:
      - gitea_data:/data
    ports:
      - "3000:3000"
      - "222:22"

  # Nginx (作为静态/反向代理)
  nginx:
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - jenkins

  # Prometheus
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports:
      - "9090:9090"

  # Grafana
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3001:3000"
    volumes:
      - grafana_data:/var/lib/grafana

  # Portainer (Docker 管理 UI)
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    command: -H unix:///var/run/docker.sock
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    ports:
      - "9002:9000"

volumes:
  mysql_data:
  pg_data:
  redis_data:
  es_data:
  rabbitmq_data:
  minio_data:
  jenkins_home:
  gitea_data:
  grafana_data:
  portainer_data:

说明:

  • 把以上 docker-compose.yml 放在 ~/docker-dev(示例路径)。
  • 你可以把敏感密码放在 .env 文件里(更安全),并用 ${VAR} 在 Compose 文件中引用。

5. 启动 / 停止 / 查看日志(常用命令)

docker-compose.yml 所在目录执行:

  • 启动(后台):
bash 复制代码
docker compose up -d
  • 查看容器状态:
bash 复制代码
docker compose ps
  • 查看某个服务日志(实时):
bash 复制代码
docker compose logs -f mysql
# 或者 docker logs -f mysql
  • 停止并移除容器(保留数据卷):
bash 复制代码
docker compose down
  • 停止并移除容器及数据卷(小心!会删除数据):
bash 复制代码
docker compose down -v
  • 进入正在运行的容器(调试):
bash 复制代码
docker exec -it mysql bash
# 如果容器没有 bash,使用 sh

6. 每个服务的详细配置、注意事项与技巧

下面逐个讲解常用服务的要点、如何与 Java/Spring Boot 连接,以及常见坑。


MySQL(开发)

  • 镜像mysql:8.0
  • 端口3306
  • 数据持久化 :使用 Docker 卷(上例 mysql_data
  • 初始化脚本 :把 .sql 放到 ./mysql/init,容器首次启动时会执行(官方 entrypoint 逻辑)。
  • JDBC 示例(Spring Boot application.properties)
properties 复制代码
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=demo
spring.datasource.password=demopass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  • 连接问题 :若从 macOS 本机用 localhost:3306 连接有效(因为 ports: "3306:3306" 做了映射)。如果使用 Docker 网络内其他服务,使用 mysql:3306(服务名)作为主机名。

PostgreSQL

  • 镜像postgres:15
  • 端口5432
  • JDBC 示例
properties 复制代码
spring.datasource.url=jdbc:postgresql://localhost:5432/demo
spring.datasource.username=demo
spring.datasource.password=demopass

Redis

  • 镜像redis:7-alpine
  • 端口6379
  • Spring Boot 配置
properties 复制代码
spring.redis.host=localhost
spring.redis.port=6379

Elasticsearch + Kibana(注意内存与兼容)

  • 镜像docker.elastic.co/elasticsearch/elasticsearch:8.x

  • 要求

    • ES 通常需要较多内存(设置 ES_JAVA_OPTS,例如 -Xms1g -Xmx1g)。
    • 在 Linux 上常需设置 vm.max_map_count=262144。在 macOS 上 Docker Desktop 使用内置 Linux VM,通常不需要用户手动设置;如果遇到错误,重启 Docker Desktop 或查看官方文档。
  • 访问http://localhost:9200(ES)和 http://localhost:5601(Kibana)。

  • Spring Data Elasticsearch :使用 http://localhost:9200 作为主机;对于 Spring Boot 3 / recent ES 客户端,查看对应版本兼容性。


RabbitMQ

  • 镜像rabbitmq:3.10-management
  • 管理界面http://localhost:15672(默认 guest/guest,compose 示例没有修改)
  • Spring Boot 配置
properties 复制代码
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

MinIO(S3 仿真)

  • 镜像minio/minio
  • 访问http://localhost:9000(控制台 9001)
  • SDK:遵从 AWS S3 API(访问 key、secret 保存在环境变量中)
  • 创建 bucket :可以在控制台或 MinIO 客户端 mc 创建。

Jenkins

  • 镜像jenkins/jenkins:lts-jdk11
  • 数据目录 :映射到 jenkins_home
  • 访问http://localhost:8080
  • 第一次启动 :如关闭了 setup wizard,可在镜像里配置 admin 密码。若开启,按提示获取初始管理员密码(在 jenkins_home/secrets/initialAdminPassword)。

Gitea(轻量 Git 服务)

  • 访问http://localhost:3000
  • SSH222 映射到容器的 22(用于 git+ssh)

Nginx

  • 用途:本地反向代理、模拟生产环境部署、托管静态资源
  • 配置 :把 ./nginx/conf.d 映射到 /etc/nginx/conf.d,可以写 site.conf 来反代到你的 Spring Boot(http://backend:8080)或前端静态文件。
  • 示例反向代理
nginx 复制代码
server {
  listen 80;
  server_name localhost;

  location / {
    proxy_pass http://jenkins:8080; # 举例
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

Prometheus + Grafana

  • Prometheus 用于采集指标(抓 /actuator/prometheus),Grafana 用于展示。

  • 在 Spring Boot 项目中:

    • 引入 micrometer-registry-prometheus
    • 启用 management.endpoint.prometheus.enabled=true,暴露端点 /actuator/prometheus
  • Prometheus 配置文件示例(prometheus.yml):

yaml 复制代码
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'spring'
    static_configs:
      - targets: ['host.docker.internal:9000'] # 示例:host.docker.internal 用于宿主机访问

注意:host.docker.internal 在 Docker Desktop (mac) 上可用于容器访问宿主机服务;反过来宿主机访问容器用 localhost:端口映射


Portainer(可视化管理 Docker)

  • 访问:http://localhost:9002
  • 便于查看容器、卷、镜像、日志。

7. Spring Boot(Java 后端)连接示例(完整)

假设 Spring Boot 应用运行在本机(或容器外)并要连接上面服务。

application-dev.properties(示例):

properties 复制代码
# MySQL
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
spring.datasource.username=demo
spring.datasource.password=demopass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# Redis
spring.redis.host=localhost
spring.redis.port=6379

# RabbitMQ
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

# Elasticsearch (示例)
spring.elasticsearch.uris=http://localhost:9200

# Actuator Prometheus
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true

如果你的 Spring Boot 也放进 Docker(和上面的服务放在同一 docker-compose),localhost 应改为服务名(例如 mysql:3306);示例:

yaml 复制代码
# docker-compose 中 app 服务示例
app:
  image: your-springboot-image:latest
  environment:
    - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/demo?useSSL=false&serverTimezone=UTC
  depends_on:
    - mysql
    - redis

8. 数据卷、备份与恢复(关键)

MySQL 备份(导出 SQL)

bash 复制代码
docker exec -it mysql sh -c 'exec mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" demo' > demo.sql

恢复

bash 复制代码
cat demo.sql | docker exec -i mysql sh -c 'mysql -u root -p"$MYSQL_ROOT_PASSWORD" demo'

PostgreSQL 备份

bash 复制代码
docker exec -t postgres pg_dumpall -c -U demo > dump.sql

Elasticsearch 快照(production 推荐)

  • 在生产环境使用 snapshot to repository(例如文件系统或 S3)。开发环境若只是数据可重建,也可直接删除卷重建索引。

卷查看与清理

  • 列出卷:
bash 复制代码
docker volume ls
  • 删除未使用卷(谨慎):
bash 复制代码
docker volume prune

9. 常见问题与排查

  1. 容器启动失败 / CrashLoop

    • 看日志:docker compose logs -f 服务名
    • 常见原因:端口冲突、环境变量缺失、数据目录权限
  2. Elasticsearch 报 max_map_count 错误

    • 在 Linux 上执行 sudo sysctl -w vm.max_map_count=262144
    • 在 macOS Docker Desktop 下通常不需要;若出现,重启 Docker Desktop 并查看日志或官方文档。
  3. 连接失败(从宿主机到容器)

    • 确认 ports 已映射(3306:3306)。
    • 使用 docker compose ps 检查端口映射。
    • 宿主机用于连接容器应使用 localhost:端口
  4. 数据丢失

    • 启动时如果没有使用 volumes 而用 bind mount,注意宿主机目录权限与 SELinux(Linux)问题。
    • 生产环境务必使用 Volume + 备份策略。
  5. 镜像拉取失败 / 速率限

    • 登录 Docker Hub 或使用公司私有镜像仓库。

10. 安全、性能与生产提醒(重点)

  • 不要 在生产环境把敏感密码直接写在 docker-compose.yml 中,使用环境变量管理或 secrets(Docker Swarm / Kubernetes secrets)。
  • 生产部署建议使用 Kubernetes(K8s)或托管服务而不是 Docker Compose。
  • 数据库与 ES 的内存配置要按实际机器尺寸调整(ES_JAVA_OPTS、Postgres 的 shared_buffers 等)。
  • 对外暴露管理端口(如 Jenkins、Gitea、Kibana)时,记得加认证与防火墙规则。
  • 镜像版本请固定(不要使用 latest 在生产),确保可复现部署。

11. 额外小技巧(提高效率)

  • .env 文件管理密码:

    复制代码
    MYSQL_ROOT_PASSWORD=rootpassword
    MYSQL_USER=demo
    MYSQL_PASSWORD=demopass

    并在 compose 用 ${MYSQL_PASSWORD} 引用。

  • 使用 docker-compose.override.yml 来覆盖开发/测试环境配置。

  • docker-compose up --build 来强制 rebuild 本地镜像。

  • 使用 host.docker.internal(mac)让容器访问宿主机服务(例如本机运行的 IDE 服务)。


12. 一个快速可运行的入门流程(从零到有)

  1. 安装 Docker Desktop(见第1节)

  2. ~/docker-dev 创建 docker-compose.yml(使用上面的示例或精简版本)

  3. 进入目录,启动:

    bash 复制代码
    cd ~/docker-dev
    docker compose up -d
  4. 看各服务状态:docker compose ps

  5. 打开浏览器访问:

    • MySQL: 用数据库客户端(DataGrip / DBeaver)连接 localhost:3306
    • Jenkins: http://localhost:8080
    • Gitea: http://localhost:3000
    • Kibana: http://localhost:5601
    • Elasticsearch: http://localhost:9200
    • MinIO: http://localhost:9000
    • Grafana: http://localhost:3001
    • Portainer: http://localhost:9002
  6. 在 Spring Boot 中配置 application.properties 指向 localhost:3306 等。


13. 常见场景示例(快速片段)

  • 把 Spring Boot 也放进 Compose(和 DB 同网段)
yaml 复制代码
app:
  build: ./app
  image: my-spring-app
  depends_on:
    - mysql
    - redis
  environment:
    SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/demo
    SPRING_DATASOURCE_USERNAME: demo
    SPRING_DATASOURCE_PASSWORD: demopass
  ports:
    - "8081:8080"
  • 通过 IntelliJ 远程调试容器内的 Java 应用 :启动 JVM 时加入 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 并在 compose 映射 5005 端口。

相关推荐
后端小张19 分钟前
【JAVA 进阶】SpringAI人工智能框架深度解析:从理论到实战的企业级AI应用开发指南
java·开发语言·人工智能
麦烤楽鸡翅27 分钟前
小红书推荐系统(牛客)
java·python·算法·秋招·春招·牛客·面试算法题
春生野草27 分钟前
(二)Docker实战--Docker镜像部署与启动
学习·docker·容器
C++业余爱好者41 分钟前
.NET线程池ThreadPool.QueueUserWorkItem
java·数据库·.net
.豆鲨包44 分钟前
【Android】Android内存缓存LruCache与DiskLruCache的使用及实现原理
android·java·缓存
superlls44 分钟前
(Java基础)集合框架继承体系
java·开发语言
宋哈哈1 小时前
页面水印sdk源码
java·前端·javascript
你不是我我1 小时前
【Java 开发日记】我们来说一下 Mybatis 的缓存机制
java·spring·mybatis
咪咪渝粮1 小时前
112.路径总和
java·数据结构·算法
WKP94181 小时前
原型设计模式
java·设计模式