Docker Compose无法创建服务容器:数据库地址解析失败求助
我在部署开源项目GPS Tracker时使用了以下docker-compose.yml文件:
services: gpstracker-mysql: image: mysql:8.0 container_name: gpstracker-mysql restart: unless-stopped volumes: - ./../storage/docker/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_USER=gpstracker - MYSQL_PASSWORD=gpstracker - MYSQL_DATABASE=gpstracker command: - --character-set-server=utf8 - --collation-server=utf8_unicode_ci networks: - gpstracker-network healthcheck: test: mysqladmin ping -h localhost --password=root interval: 15s retries: 15 gpstracker-redis: image: redis:7.0 container_name: gpstracker-redis restart: unless-stopped networks: - gpstracker-network healthcheck: test: redis-cli ping interval: 5s retries: 15 gpstracker-app: image: gpstracker-app:latest container_name: gpstracker-app restart: unless-stopped depends_on: gpstracker-mysql: condition: service_healthy gpstracker-redis: condition: service_healthy build: context: .. dockerfile: ./docker/Dockerfile ports: - "8080:80" - "8091:8091" expose: - "8080" - "8091" networks: - gpstracker-network tty: true networks: gpstracker-network: name: gpstracker-network driver: bridge
执行了以下构建命令:
sudo docker compose -f docker/docker-compose.yml pull sudo docker compose -f docker/docker-compose.yml up --force-recreate --build -d
出现报错:
PDO::__construct(): php_network_getaddresses: getaddrinfo for gpstracker-mysql failed: Name or service not known
执行docker ps -a发现没有容器被创建:
sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
但相关镜像和网络已存在:
sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE mysql 8.0 c5f0c876cdb1 13 days ago 567MB redis 7.0 f86d36f62d00 5 weeks ago 109MB
sudo docker network ls NETWORK ID NAME DRIVER SCOPE b9c1cd6e9b9c bridge bridge local e1d6002a7558 gpstracker-network bridge local 6eb0cc92d744 host host local eb6f8188ad5f none null local
更新:构建过程显示在执行./composer install --no-dev --optimize-autoloader --classmap-authoritative步骤时出错。
更新2:分步构建服务时,gpstracker-mysql和gpstracker-redis容器可正常创建,但gpstracker-app构建仍报相同错误。
请问我的docker-compose.yml配置存在什么问题?
问题出在构建app镜像的时候,没法访问Docker Compose里的mysql服务,具体原因和解决办法如下:
为啥会报错?
你的gpstracker-app在构建阶段跑了composer install,而这个过程里项目可能要连数据库(比如跑迁移脚本、读取数据库配置生成依赖)。但Docker Compose的构建环节默认不会把构建环境加入到你定义的gpstracker-network里,所以构建时解析不了gpstracker-mysql这个服务名,就报了DNS找不到的错。
你加的depends_on健康检查只管容器启动顺序,不管构建阶段的网络访问。怎么改docker-compose.yml?
办法一:让构建阶段加入服务网络
在gpstracker-app的build配置里加一行network,指定用gpstracker-network,这样构建时就能访问已经启动的mysql和redis了:gpstracker-app: # ... 其他原有配置 build: context: .. dockerfile: ./docker/Dockerfile network: gpstracker-network # 新增这行 # ... 其他原有配置注意用这个办法前,得先把mysql和redis启动起来,比如先跑
docker compose up -d gpstracker-mysql gpstracker-redis,等它们健康检查通过了再构建app。办法二:把构建和运行的依赖分开
修改项目的Dockerfile,别让构建阶段做需要连数据库的事:- 跑
composer install的时候加--no-scripts参数,跳过那些需要数据库的脚本 - 把数据库迁移、配置初始化这些操作放到容器启动的时候做(比如写个entrypoint脚本,容器启动时再执行)
这样构建阶段不用碰数据库,自然就不会有DNS问题。
- 跑
额外要检查的地方
- 确认项目配置文件里,数据库主机写的是
gpstracker-mysql(和docker-compose里的服务名一致),别写成localhost或者别的地址 - 检查mysql的挂载路径
./../storage/docker/db是不是对的,避免mysql启动失败(不过你分步启动mysql正常,这个大概率没问题)
- 确认项目配置文件里,数据库主机写的是
内容的提问来源于stack exchange,提问作者Lito

