在 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 端口。

相关推荐
顾漂亮3 小时前
JVM底层攻坚
java·jvm·spring
编程岁月3 小时前
java面试-0215-HashMap有序吗?Comparable和Comparator区别?集合如何排序?
java·数据结构·面试
木井巳3 小时前
[Java数据结构与算法]详解排序算法
java·数据结构·算法·排序算法
没有bug.的程序员5 小时前
分布式架构未来趋势:从云原生到智能边缘的演进之路
java·分布式·微服务·云原生·架构·分布式系统
AI云原生5 小时前
云原生系列Bug修复:Docker镜像无法启动的终极解决方案与排查思路
运维·服务器·python·docker·云原生·容器·bug
毕业设计制作和分享7 小时前
springboot150基于springboot的贸易行业crm系统
java·vue.js·spring boot·后端·毕业设计·mybatis
tryCbest11 小时前
CentOS部署Docker容器
linux·docker·centos
菠萝炒饭pineapple-boss11 小时前
单机让多docker拥有多ip出口
docker
小梁努力敲代码12 小时前
java数据结构--List的介绍
java·开发语言·数据结构