从单容器到多服务编排:手把手教你用Docker Compose在Windows上部署Tomcat+MySQL完整开发环境
在当今快速迭代的软件开发领域,容器化技术已成为提升开发效率的关键工具。对于Java开发者而言,如何在本地快速搭建一个稳定、可复用的开发环境,直接影响着日常编码体验和项目推进效率。传统的手动安装配置Tomcat和MySQL不仅耗时费力,而且难以保证环境一致性,这正是Docker Compose技术大显身手的场景。
本文将带你深入一个真实的开发场景:使用Docker Compose在Windows系统上编排Tomcat和MySQL 5.7服务,构建一个即开即用的Java Web开发环境。不同于简单的安装教程,我们将聚焦于生产级细节配置,包括数据持久化、时区同步、字符集优化等实际问题,让你学到的不仅是基础操作,更是可直接应用于实际项目的解决方案。
1. 环境准备与基础配置
1.1 Windows系统适配性检查
在开始之前,确保你的Windows版本满足Docker Desktop的运行要求。专业版、企业版或教育版的Windows 10/11(64位)是最佳选择,版本号需高于1909。可通过以下命令验证:
systeminfo | find "OS 名称"对于家庭版用户,有两种可行方案:
- 升级到专业版(通过合法的许可证密钥)
- 使用Docker Toolbox(旧版兼容方案)
提示:建议使用WSL 2作为后端引擎,能获得更好的性能体验。在PowerShell管理员模式下运行:
wsl --install
1.2 Docker Desktop安装优化
从Docker官网下载稳定的Windows版本安装包,安装过程中有几个关键选项需要注意:
- 启用WSL 2特性:大幅提升I/O性能
- 配置资源分配:建议至少分配4GB内存给Docker
- 镜像加速器:配置国内镜像源加速下载
配置阿里云镜像加速的daemon.json示例:
{ "registry-mirrors": ["https://<你的ID>.mirror.aliyuncs.com"], "features": { "buildkit": true } }安装完成后,验证基础环境:
docker version docker-compose version2. 单容器服务实践
2.1 独立运行Tomcat容器
在进入多服务编排前,我们先理解单个容器的运行原理。以下命令直接运行一个Tomcat容器:
docker run -d \ --name my-tomcat \ -p 8080:8080 \ -v D:/docker/tomcat/webapps:/usr/local/tomcat/webapps \ -e TZ=Asia/Shanghai \ tomcat:9.0关键参数解析:
| 参数 | 说明 | 生产环境建议 |
|---|---|---|
-v | 数据卷挂载 | 使用绝对路径避免权限问题 |
-e TZ | 时区设置 | 统一设置为东八区 |
--name | 容器命名 | 采用项目前缀命名规范 |
2.2 独立运行MySQL容器
MySQL容器需要更多生产级配置,特别是字符集和权限控制:
docker run -d \ --name my-mysql \ -p 3306:3306 \ -v mysql_data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=secure_pwd \ -e MYSQL_DATABASE=app_db \ -e TZ=Asia/Shanghai \ mysql:5.7 \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci注意:root密码不应使用示例中的简单密码,建议通过
--env-file参数从文件读取敏感信息
3. 多服务编排实战
3.1 docker-compose.yml架构设计
创建完整的开发环境编排文件,需考虑以下要素:
- 服务依赖关系:MySQL应先于Tomcat启动
- 网络隔离:创建自定义网络确保服务间安全通信
- 环境变量管理:集中配置敏感信息
- 资源限制:防止单个服务占用过多资源
基础结构示例:
version: '3.8' services: mysql: image: mysql:5.7 container_name: app_mysql # 其他配置将在下文展开 tomcat: image: tomcat:9.0 container_name: app_tomcat depends_on: mysql: condition: service_healthy3.2 MySQL服务深度配置
数据库服务的生产级配置需要特别注意:
mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_DATABASE: app_dev MYSQL_USER: dev_user MYSQL_PASSWORD: dev_password TZ: Asia/Shanghai command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max_connections=200 --innodb_buffer_pool_size=256M volumes: - mysql_data:/var/lib/mysql - ./init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 5s timeout: 3s retries: 5关键优化点:
- 通过
healthcheck确保服务真正可用 - 使用
init.sql初始化数据库结构 - 限制缓冲池大小避免内存溢出
3.3 Tomcat服务优化配置
Java Web容器的配置需要兼顾开发和调试需求:
tomcat: image: tomcat:9.0 environment: CATALINA_OPTS: "-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom" TZ: Asia/Shanghai volumes: - ./webapps:/usr/local/tomcat/webapps - ./logs:/usr/local/tomcat/logs - ./conf/server.xml:/usr/local/tomcat/conf/server.xml ports: - "8080:8080" - "8000:8000" # 调试端口 depends_on: mysql: condition: service_healthy性能调优建议:
- 适当调整JVM内存参数
- 挂载自定义的server.xml优化连接池
- 暴露调试端口便于IDE连接
4. 高级编排技巧
4.1 网络隔离与连接配置
创建自定义网络并配置服务间连接:
networks: app_net: driver: bridge ipam: config: - subnet: 172.20.0.0/24 services: mysql: networks: app_net: aliases: - db tomcat: networks: app_net:在Spring Boot应用中,数据库连接URL应使用服务名:
spring.datasource.url=jdbc:mysql://db:3306/app_dev4.2 数据持久化策略
使用命名卷保证数据安全:
volumes: mysql_data: driver: local driver_opts: type: none o: bind device: D:/docker/mysql_data备份与恢复操作示例:
# 备份 docker run --rm -v mysql_data:/volume -v $PWD:/backup alpine tar cvf /backup/mysql_backup.tar /volume # 恢复 docker run --rm -v mysql_data:/volume -v $PWD:/backup alpine sh -c "rm -rf /volume/* && tar xvf /backup/mysql_backup.tar -C /volume"4.3 开发效率提升技巧
热部署配置:
tomcat: volumes: - ./target/your-app.war:/usr/local/tomcat/webapps/ROOT.war日志实时查看:
docker-compose logs -f tomcat快速重启单个服务:
docker-compose restart tomcat环境变量管理: 创建
.env文件:DB_ROOT_PASSWORD=your_secure_password TZ=Asia/Shanghai在docker-compose.yml中引用:
environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
5. 项目实战演示
5.1 完整docker-compose.yml示例
version: '3.8' services: mysql: image: mysql:5.7 container_name: app_mysql environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_DATABASE: app_dev TZ: Asia/Shanghai command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max_allowed_packet=128M volumes: - mysql_data:/var/lib/mysql - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 5s timeout: 3s retries: 5 networks: - app_net tomcat: image: tomcat:9.0-jdk11 container_name: app_tomcat environment: CATALINA_OPTS: "-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom" TZ: Asia/Shanghai volumes: - ./webapps:/usr/local/tomcat/webapps - ./logs:/usr/local/tomcat/logs ports: - "8080:8080" depends_on: mysql: condition: service_healthy networks: - app_net volumes: mysql_data: networks: app_net: driver: bridge5.2 操作流程与验证
启动整个环境:
docker-compose up -d查看服务状态:
docker-compose ps测试MySQL连接:
docker exec -it app_mysql mysql -u root -p部署War包:
cp target/your-app.war ./webapps/ROOT.war访问应用:
http://localhost:8080
5.3 常见问题排查
端口冲突解决方案:
netstat -ano | findstr :8080 taskkill /PID <PID> /F容器时区同步验证:
docker exec app_tomcat date数据库连接问题诊断:
docker-compose logs mysql