在docker compose中,php连接mysql的服务名应直接填写`docker-compose.yml`文件里定义的mysql服务名称。例如,若mysql服务的配置键名为`mysql`,则php应用的环境变量`database_host`或代码中的连接地址必须写为`mysql`,这样docker内部dns才能正确解析并建立连接。

如何配置环境变量以指定服务名
直接在PHP容器的环境变量中设置数据库主机地址为对应的服务名即可。假设你的`docker-compose.yml`文件中定义了名为`db`的MySQL服务,那么在PHP容器的配置中,将`DB_HOST`设置为`db`。Docker Compose会自动为每个服务创建一个内部网络,并通过服务名提供DNS解析,确保容器间可以通过该名称互相访问。

version: '3.8'
services:
app:
image: php:8.0-apache
environment:
- DB_HOST=db
- DB_NAME=myapp
- DB_USER=root
- DB_PASSWORD=secret
depends_on:
- db
db:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=myapp
上述配置中,`app`服务通过`depends_on`依赖`db`服务,且环境变量`DB_HOST`明确指向`db`。当PHP代码尝试连接数据库时,使用`$_ENV['DB_HOST']`获取的值即为`db`,Docker DNS会将其解析为`db`容器的内部IP地址。
服务名解析与网络隔离的影响
服务名的解析依赖于Docker Compose创建的内部网络。默认情况下,所有在同一`docker-compose.yml`中定义的服务都在同一个默认网络上,因此它们可以通过服务名互相发现。如果手动创建了网络,必须确保PHP和MySQL服务都连接到同一个网络,否则服务名将无法解析。
Docker Hub (hub.docker.com)。此技能适用于所有 Docker Hub 操作,包括读取、创建、更新和删除数据。只要任务涉及 Docker Hub,就使用此技能。

# docker-compose.yml snippet
networks:
default:
driver: bridge
services:
app:
networks:
- default
db:
networks:
- default
在上述示例中,显式地将`app`和`db`服务连接到`default`网络。虽然这是默认行为,但显式声明有助于避免在网络配置复杂时的混淆。如果两个服务不在同一网络,即使服务名相同,也无法通过DNS解析到达对方,导致连接失败。
基于depends_on条件的连接时序问题
当使用`depends_on`时,Docker Compose会确保`db`服务先启动,但这并不意味着MySQL已经准备好接受连接。`depends_on`只等待服务进程启动,而不等待数据库初始化完成。如果PHP应用在MySQL完全就绪前尝试连接,可能会遇到连接拒绝错误。为解决此问题,可以在PHP应用中实现重试机制,或使用`wait-for-it`等工具等待数据库就绪。
#!/bin/bash # wait-for-it.sh host="$1"; shift; delay=0; interval=1; until nc -z "$host" 3306; do delay=$((delay + interval)); echo "Waiting for $host:3306 ($delay seconds)"; sleep $interval; done echo "$host:3306 is available after $delay seconds";
在PHP容器中执行上述脚本,等待MySQL端口开放后再启动应用。这确保了在连接尝试时,MySQL服务已完全初始化并可接受连接。这种方法比单纯依赖`depends_on`更可靠,特别是在处理需要较长时间初始化的数据库服务时。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










