本文目录导读:

在PHP项目的Docker容器化部署中,实现容器间网络互通主要有以下几种方式,按推荐程度排序:
使用Docker Compose(最推荐)
基础配置
# docker-compose.yml
version: '3.8'
services:
php:
image: php:8.2-fpm
build:
context: .
dockerfile: Dockerfile
container_name: php-app
volumes:
- ./app:/var/www/html
networks:
- app-network
depends_on:
- mysql
- redis
nginx:
image: nginx:alpine
container_name: nginx-web
ports:
- "80:80"
- "443:443"
volumes:
- ./app:/var/www/html
- ./nginx/conf.d:/etc/nginx/conf.d
networks:
- app-network
depends_on:
- php
mysql:
image: mysql:8.0
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: appdb
MYSQL_USER: appuser
MYSQL_PASSWORD: apppass
volumes:
- mysql_data:/var/lib/mysql
networks:
- app-network
redis:
image: redis:7-alpine
container_name: redis-cache
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
mysql_data:
PHP代码中连接服务
// 使用服务名称作为主机名
$db = new PDO('mysql:host=mysql;dbname=appdb;charset=utf8', 'appuser', 'apppass');
$redis = new Redis();
$redis->connect('redis', 6379);
自定义网络(手动方式)
创建网络
# 创建自定义网络 docker network create --driver bridge php-network # 查看网络 docker network ls
运行容器并加入网络
# 启动MySQL docker run -d --name mysql-db \ --network php-network \ -e MYSQL_ROOT_PASSWORD=rootpass \ mysql:8.0 # 启动PHP docker run -d --name php-app \ --network php-network \ -v $(pwd)/app:/var/www/html \ php:8.2-fpm # 启动Nginx docker run -d --name nginx-web \ --network php-network \ -p 80:80 \ -v $(pwd)/app:/var/www/html \ nginx:alpine
使用容器名直接访问
启动时要指定网络别名
# 创建网络 docker network create app-net # 运行MySQL docker run -d --name mysql-db \ --network app-net \ --network-alias mysql \ mysql:8.0 # 运行PHP docker run -d --name php-app \ --network app-net \ --network-alias php \ -v $(pwd)/app:/var/www/html \ php:8.2-fpm
共享网络栈(不推荐)
# 创建一个基础容器 docker run -d --name base-container \ -p 80:80 \ nginx:alpine # 其他容器使用这个容器的网络 docker run -d --name php-app \ --network container:base-container \ php:8.2-fpm
环境变量配置示例
docker-compose.yml 中的配置
services:
php:
environment:
- DB_HOST=mysql
- DB_PORT=3306
- DB_DATABASE=appdb
- DB_USERNAME=appuser
- DB_PASSWORD=apppass
- REDIS_HOST=redis
- REDIS_PORT=6379
- CACHE_TYPE=redis
PHP配置文件
// config.php
return [
'db' => [
'host' => getenv('DB_HOST') ?: 'localhost',
'port' => getenv('DB_PORT') ?: '3306',
'database' => getenv('DB_DATABASE') ?: 'appdb',
'username' => getenv('DB_USERNAME') ?: 'root',
'password' => getenv('DB_PASSWORD') ?: '',
],
'redis' => [
'host' => getenv('REDIS_HOST') ?: 'localhost',
'port' => getenv('REDIS_PORT') ?: '6379',
],
];
常见问题排查
DNS解析问题
# 进入PHP容器测试网络 docker exec -it php-app bash # 测试DNS解析 ping mysql nslookup redis # 测试端口连通性 nc -zv mysql 3306 telnet redis 6379
防火墙问题
# 检查iptables规则 docker network inspect app-network # 确保没有防火墙阻止 iptables -L -n
高级配置
外部网络连接
services:
php:
networks:
- app-network
- external-network
networks:
app-network:
driver: bridge
external-network:
external: true
name: existing-network
网络隔离
services:
# 前端可以访问的网络
nginx:
networks:
- frontend
- backend
# 后端可以访问的网络
php:
networks:
- backend
- database
# 数据库只能后端访问
mysql:
networks:
- database
networks:
frontend:
backend:
database:
最佳实践建议
- 始终使用Docker Compose:简化管理,推荐使用
docker-compose.yml配置 - 使用服务名称:不要在代码中硬编码IP地址
- 环境变量配置:通过环境变量配置数据库连接信息
- 网络隔离:根据安全需求划分不同网络
- 健康检查:配置健康检查确保服务可用
- 日志监控:启用容器日志记录
这样配置后,PHP容器就可以通过服务名称(如 mysql、redis)访问其他容器,无需关心具体IP地址的变化。