说明:本文假设你在 macOS(Intel 或 Apple Silicon)上使用 Docker Desktop。如果你已经安装 Docker,请从"创建 compose 文件"那一节直接开始。
目录(快速导航)
- 安装 Docker Desktop(macOS)
- Docker Desktop 基本配置建议(资源、端口、文件共享)
- 推荐服务清单(为 Java 后端与通用开发)
- 为所有服务准备的
docker-compose.yml
(完整示例) - 启动 / 停止 / 管理容器的常用命令
- 每个服务的详细说明、配置与注意事项(MySQL / PostgreSQL / Redis / Elasticsearch + Kibana / RabbitMQ / Nginx / Jenkins / Gitea / MinIO / Prometheus + Grafana / Portainer / Node)
- Spring Boot(Java 后端)连接示例配置
- 数据卷、备份与恢复(MySQL、Postgres、Elasticsearch 等)
- 常见问题与排查方法
- 安全、性能与生产提醒
1. 安装 Docker Desktop(macOS)------一步步来
-
访问 Docker 官网下载适合你 Mac 的 Docker Desktop 安装包(Apple Silicon / Intel)。
- 在浏览器输入
docker desktop mac
即可找到下载页面(注意选对 CPU 架构)。
- 在浏览器输入
-
下载完成后,双击
.dmg
,把 Docker.app 拖到Applications
文件夹。 -
打开
Applications
中的 Docker.app,第一次启动会要求输入系统密码(以允许安装虚拟化工具)。 -
启动后菜单栏会出现小鲸鱼图标,等待 "Docker is running"。
-
(可选)登录 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 或查看官方文档。
- ES 通常需要较多内存(设置
-
访问 :
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
- SSH :
222
映射到容器的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. 常见问题与排查
-
容器启动失败 / CrashLoop
- 看日志:
docker compose logs -f 服务名
- 常见原因:端口冲突、环境变量缺失、数据目录权限
- 看日志:
-
Elasticsearch 报
max_map_count
错误- 在 Linux 上执行
sudo sysctl -w vm.max_map_count=262144
。 - 在 macOS Docker Desktop 下通常不需要;若出现,重启 Docker Desktop 并查看日志或官方文档。
- 在 Linux 上执行
-
连接失败(从宿主机到容器)
- 确认
ports
已映射(3306:3306
)。 - 使用
docker compose ps
检查端口映射。 - 宿主机用于连接容器应使用
localhost:端口
。
- 确认
-
数据丢失
- 启动时如果没有使用
volumes
而用bind mount
,注意宿主机目录权限与 SELinux(Linux)问题。 - 生产环境务必使用 Volume + 备份策略。
- 启动时如果没有使用
-
镜像拉取失败 / 速率限
- 登录 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. 一个快速可运行的入门流程(从零到有)
-
安装 Docker Desktop(见第1节)
-
在
~/docker-dev
创建docker-compose.yml
(使用上面的示例或精简版本) -
进入目录,启动:
bashcd ~/docker-dev docker compose up -d
-
看各服务状态:
docker compose ps
-
打开浏览器访问:
- 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
- MySQL: 用数据库客户端(DataGrip / DBeaver)连接
-
在 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
端口。