如何让同一Nginx Docker容器下的两个站点互相通信?
本地通过Docker搭建了包含Nginx Web服务器、PHP 8.2-FPM、PHP 7.4-FPM的环境,针对依赖不同PHP版本的应用,已在Nginx中创建对应.conf配置文件,通过fastcgi_pass指定了匹配的PHP-FPM版本。当前client.localhost(前端应用)和api.localhost(API应用)均可被外部正常访问,但从client.localhost内部调用api.localhost时,出现错误:cURL error 7: Failed to connect to api.localhost port 80 after 0 ms: Couldn't connect to server,两者无法互通。
附当前Nginx配置示例(仅server_name、root、PHP版本有差异):
server { listen 80; listen [::]:80; server_name api.localhost; root /var/www/html/api/public; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri /index.php =404; fastcgi_pass php82:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_read_timeout 600; include fastcgi_params; } location ~ /\.ht { deny all; } error_log /var/log/nginx/api_error.log debug; access_log /var/log/nginx/api_access.log; }
当前docker-compose.yml配置:
version: "3.8" services: nginx: build: context: nginx ports: - "80:80" volumes: - ./nginx/conf:/etc/nginx/conf.d - /var/www/html:/var/www/html - ./logs:/var/log/nginx php82: build: context: php args: PHP_VERSION: 8.2 volumes: - /var/www/html:/var/www/html extra_hosts: - "host.docker.internal:host-gateway" environment: XDEBUG_CONFIG: client_host=host.docker.internal DEBUG: 1 php74: build: context: php args: PHP_VERSION: 7.4 volumes: - /var/www/html:/var/www/html extra_hosts: - "host.docker.internal:host-gateway" environment: XDEBUG_CONFIG: client_host=host.docker.internal DEBUG: 1
问题核心是运行client应用的PHP-FPM容器无法解析api.localhost并指向Nginx服务,可通过以下配置修改解决:
为PHP容器添加hosts映射:在
docker-compose.yml的php82、php74服务中,新增extra_hosts规则,将api.localhost和client.localhost指向Nginx容器的服务名(Docker Compose默认会为同一网络的服务创建DNS解析,服务名可直接作为内部域名使用):extra_hosts: - "host.docker.internal:host-gateway" - "api.localhost:nginx" - "client.localhost:nginx"这样PHP容器内访问
api.localhost时,会直接转发到Nginx容器的80端口。确认网络一致性:Docker Compose默认会为所有服务创建共享网络,当前nginx、php82、php74已在同一网络中,无需额外配置;若手动指定过网络,需确保三者归属同一网络。
可选:直接使用Nginx服务名调用:若不想配置hosts,可在client代码中直接用
nginx作为域名调用API(如http://nginx/api/xxx),此方式需确保Nginx的server配置能正确匹配请求,缺点是需要调整代码中的API地址。
version: "3.8" services: nginx: build: context: nginx ports: - "80:80" volumes: - ./nginx/conf:/etc/nginx/conf.d - /var/www/html:/var/www/html - ./logs:/var/log/nginx php82: build: context: php args: PHP_VERSION: 8.2 volumes: - /var/www/html:/var/www/html extra_hosts: - "host.docker.internal:host-gateway" - "api.localhost:nginx" - "client.localhost:nginx" environment: XDEBUG_CONFIG: client_host=host.docker.internal DEBUG: 1 php74: build: context: php args: PHP_VERSION: 7.4 volumes: - /var/www/html:/var/www/html extra_hosts: - "host.docker.internal:host-gateway" - "api.localhost:nginx" - "client.localhost:nginx" environment: XDEBUG_CONFIG: client_host=host.docker.internal DEBUG: 1
内容的提问来源于stack exchange,提问作者Gustavo Araújo

